I’m seeing two odd behaviours with using lambdas:
- It seems as though having a lambda as a function argument with a
block causes a syntax error. It can be mitigated by adding a semicolon
or by using parentheses
def foo(rest)
puts rest.inspect
yield
end
fails syntax error
foo :parm1=>1, :parm2=>lambda { puts “lambda” } do
puts “In bar block”
end
fails syntax error
foo :parm1=>lambda { puts “lambda” }, :parm2=>1 do
puts “In bar block”
end
fails syntax error
foo {:parm1=>1, :parm2=>lambda { puts “lambda” }} do
puts “In bar block”
end
succeeds???
foo :parm1=>1, :parm2=>lambda { puts “lambda”; } do
puts “In bar block”
end
succeeds???
foo (:parm1=>1, :parm2=>lambda { puts “lambda” }) do
puts “In bar block”
end
- I’m not understanding the scoping rules for lambda with
instance_evals inside a class:
If these statements are added at the beginning the
the lambda will evaluate them first
a = 4 # stmt 1
b = 5 # stmt 2
class Bar
attr_accessor :a, :b
def initialize
@a = 1
@b = 2
end
def foo(&block)
instance_eval(&block)
end
end
m = lambda{puts a + b}
Bar.new.foo(&m)
Without stmt1 and stmt2 above, the code correctly outputs 3. But if
stmt1 and stmt2 are incommented, the output is 9 which seems to be the
global scope rather than the scope of the instance of Bar expected
with instance_eval.
Am I missing something?
Thanks,
Charlton
Charlton Wang wrote:
fails syntax error
foo :parm1=>1, :parm2=>lambda { puts “lambda” } do
puts “In bar block”
end
The syntax is wrong whether or not you are passing
a Proc object as an argument.
def foo(rest)
puts rest.inspect
yield
end
==>nil
foo ‘hello’ { puts ‘in block’ }
SyntaxError: compile error
(irb):5: syntax error
foo ‘hello’ { puts ‘in block’ }
^
(irb):5: syntax error
from (irb):5
from :0
foo( ‘hello’ ){ puts ‘in block’ }
“hello”
in block
==>nil
foo( proc{p “I’m neither sheep nor lambda.”} ){ puts ‘in block’ }
#Proc:[email protected]:6(irb)
in block
==>nil
Hi –
On Sat, 6 Dec 2008, Charlton Wang wrote:
I’m seeing two odd behaviours with using lambdas:
I’m skipping to #2 if that’s OK.
@a = 1
Without stmt1 and stmt2 above, the code correctly outputs 3. But if
stmt1 and stmt2 are incommented, the output is 9 which seems to be the
global scope rather than the scope of the instance of Bar expected
with instance_eval.
Am I missing something?
When Ruby sees a and b, it favors the interpretation that they are
local variables. If you want to ensure that they’re interpreted as
method calls, you can do:
puts a() + b()
David
Sorry, you lost me with your example.
My block is being bound with do/end rather than {}. In your examples,
you’re using {} which has tighter binding and the syntax error is
expected.
foo ‘hello’ do puts ‘in block’; end
works just find but this isn’t the same as what I’m asking. I’m binding
the lambda function as a hash value.
Or…maybe I’m missing something obvious.
Charlton
William J. wrote:
Charlton Wang wrote:
fails syntax error
foo :parm1=>1, :parm2=>lambda { puts “lambda” } do
puts “In bar block”
end
The syntax is wrong whether or not you are passing
a Proc object as an argument.
def foo(rest)
puts rest.inspect
yield
end
==>nil
foo ‘hello’ { puts ‘in block’ }
SyntaxError: compile error
(irb):5: syntax error
foo ‘hello’ { puts ‘in block’ }
^
(irb):5: syntax error
from (irb):5
from :0
foo( ‘hello’ ){ puts ‘in block’ }
“hello”
in block
==>nil
foo( proc{p “I’m neither sheep nor lambda.”} ){ puts ‘in block’ }
#Proc:[email protected]:6(irb)
in block
==>nil
The Higgs bozo wrote:
Charlton Wang wrote:
fails syntax error
foo :parm1=>1, :parm2=>lambda { puts “lambda” } do
puts “In bar block”
end
Curiously, that works in 1.9.
I also noticed this succeeds in 1.8 (and 1.9):
foo :parm1=>1, :parm2=>lambda { puts(“lambda”) } do
puts “In bar block”
end
That’s really interesting. So the parentheses as arguments to the puts
make it work. How odd!
Charlton Wang wrote:
fails syntax error
foo :parm1=>1, :parm2=>lambda { puts “lambda” } do
puts “In bar block”
end
Curiously, that works in 1.9.
I also noticed this succeeds in 1.8 (and 1.9):
foo :parm1=>1, :parm2=>lambda { puts(“lambda”) } do
puts “In bar block”
end