C
Charlton Wang
I'm seeing two odd behaviours with using lambdas:
1. 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 arm1=>1, arm2=>lambda { puts "lambda" } do
puts "In bar block"
end
# fails syntax error
foo arm1=>lambda { puts "lambda" }, arm2=>1 do
puts "In bar block"
end
# fails syntax error
foo {arm1=>1, arm2=>lambda { puts "lambda" }} do
puts "In bar block"
end
# succeeds???
foo arm1=>1, arm2=>lambda { puts "lambda"; } do
puts "In bar block"
end
# succeeds???
foo parm1=>1, arm2=>lambda { puts "lambda" }) do
puts "In bar block"
end
2. 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
1. 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 arm1=>1, arm2=>lambda { puts "lambda" } do
puts "In bar block"
end
# fails syntax error
foo arm1=>lambda { puts "lambda" }, arm2=>1 do
puts "In bar block"
end
# fails syntax error
foo {arm1=>1, arm2=>lambda { puts "lambda" }} do
puts "In bar block"
end
# succeeds???
foo arm1=>1, arm2=>lambda { puts "lambda"; } do
puts "In bar block"
end
# succeeds???
foo parm1=>1, arm2=>lambda { puts "lambda" }) do
puts "In bar block"
end
2. 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