Tarek said:
Q2) This is ultimately what I want to do (psuedo code below):
def my_function(&block)
x = 5
s = 15
block.call
end
my_block = lamda{ puts "#{s+x}" }
my_function(&my_block)
But it complains about not knowing what s and x are, ie out of scope.
Why and how can this be resolved?
Turn it around:
def my_function(&block)
x = 5
s = 15
block.call(x,s)
end
my_block = lambda { |x,s| puts "#{s+x}" }
my_function(&my_block)
This is a clean solution. my_block is a genuine function - it accepts
arguments, and returns a result.
It is possible for my_block to have access to local variables defined
within its own scope. But it's hard for it to have access to local
variables which didn't exist at the time it was created. 'def' and
'class' start their own clean scopes.
An alternative approach is using instance variables and objects, but you
may need to use instance_eval to set the context within which the
instance variables are looked up.
class MyClass
def initialize(x=5, s=15)
@x = x
@s = s
end
def my_function(&blk)
instance_eval(&blk)
end
end
obj = MyClass.new
my_block = lambda { puts "#{@s+@x}" }
obj.my_function(&my_block)
But that any method calls in the lambda will also be calls to MyClass
methods, not to methods defined on the 'main' object.