如何将实例变量作为参数传递给块?
这在Ruby 1.9中不起作用(形式参数不能是实例变量)。
awesome do |foo, @bar|
puts 'yay'
end
答案 0 :(得分:4)
Ruby 1.9使块参数成为块本地。这也意味着块参数不再是全局变量或实例变量。您可以将闭包用于您的目的:
@foo = 10
1.times do |i|
puts @foo
end
# => "10"
<强>更新强> 本地变量可以帮助您:
,而不是使用实例变量foo = 10
1.times do |i|
puts foo
end
# => "10"
在这种情况下,您不会遇到与不同上下文中的代码执行相关的问题。
答案 1 :(得分:2)
这里有3个案例可能是相关的:
awesome2
的用法。awesome
。awesome3
。因此,让我们尝试实现这两个示例来查看它们。这个例子很冗长,相关的行是:
awesome
获取实例变量作为参数,然后接收器在块的调用中使用awesome2
没有实例变量,它由Sender#use_in_block
绑定。接收者没有机会改变这种约束力。awesome3
获取发件人的实例变量,但使用自己的实例变量来调用块因此,根据您想要达到的目标,三者中的一个是更好的解决方案。
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)
结果是:
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"