【发布时间】:2011-11-12 08:16:29
【问题描述】:
如何将实例变量作为参数传递给块?
这在 Ruby 1.9 中不起作用(形式参数不能是实例变量)。
awesome do |foo, @bar|
puts 'yay'
end
【问题讨论】:
标签: ruby
如何将实例变量作为参数传递给块?
这在 Ruby 1.9 中不起作用(形式参数不能是实例变量)。
awesome do |foo, @bar|
puts 'yay'
end
【问题讨论】:
标签: ruby
Ruby 1.9 将块参数设置为块的本地参数。这也意味着块参数不能再是全局变量或实例变量。您可以将闭包用于您的目的:
@foo = 10
1.times do |i|
puts @foo
end
# => "10"
更新 局部变量可以帮助您,而不是使用实例变量:
foo = 10
1.times do |i|
puts foo
end
# => "10"
在这种情况下,您不会遇到与在不同上下文中执行代码相关的问题。
【讨论】:
这里有 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"