How to pass an instance variable as an argument to a block?
This doesn't work in Ruby 1.9 (formal argument cannot be an instance variable).
awesome do |foo, @bar|
puts 'yay'
end
Ruby 1.9 makes block parameters local to the block. This also means that block parameters can no longer be global or instance variables. You can use closures for your purposes:
@foo = 10
1.times do |i|
puts @foo
end
# => "10"
UPDATE Instead of using instance variables, local variable can help you:
foo = 10
1.times do |i|
puts foo
end
# => "10"
In such cases, you won't get problems related to code execution inside different context.
There are 3 cases here which could be relevant:
awesome2.awesome.awesome3.So lets try to implement both examples to see them. The example is lengthy, the relevant lines are:
awesome gets the instance variable as argument, which is then used by the receiver in the call of the blockawesome2 gets no instance variable, it is bound by Sender#use_in_block. No chance for the receiver to change that binding.awesome3 gets the instance variable of the sender, but uses its own instance variable for calling the blockSo depending on what you want to reach, one of the three is the better solution.
class Sender
attr_accessor :send_var
def call_a_block(var)
rec = Receiver.new(5)
@my_var = var
res = rec.awesome(@my_var) do |arg1|
arg1 + 3
end
res2 = rec.awesome3(@my_var) do |arg1|
arg1 + 3
end
p "Result of calling awesome with: 3 and #{@my_var} is #{res}"
p "Result of calling awesome3 with: 3 and #{@my_var} is #{res2}"
end
def use_in_block(var)
rec = Receiver.new(6)
@my_var = var
res = rec.awesome2 do
4 + @my_var
end
p "Result of calling awesome2 with: 4 and #{@my_var} is #{res}"
end
end
class Receiver
attr_accessor :rec_var
def initialize(var)
@rec_var = var
end
def awesome(arg1)
res = yield(arg1)
res * 2
end
def awesome3(arg1)
res = yield(@rec_var)
res * 2
end
def awesome2
res = yield
res * 2
end
end
s = Sender.new
s.call_a_block(7)
s.call_a_block(20)
s.use_in_block(7)
s.use_in_block(20)
Results are:
c:\Temp>ruby call.rb
"Result of calling awesome with: 3 and 7 is 20"
"Result of calling awesome3 with: 3 and 7 is 16"
"Result of calling awesome with: 3 and 20 is 46"
"Result of calling awesome3 with: 3 and 20 is 16"
"Result of calling awesome2 with: 4 and 7 is 22"
"Result of calling awesome2 with: 4 and 20 is 48"