Как передать переменную экземпляра в качестве аргумента в блок?переменная экземпляра в блоках
Это не работает в Ruby 1.9 (формальный аргумент не может быть переменной экземпляра).
awesome do |foo, @bar|
puts 'yay'
end
Как передать переменную экземпляра в качестве аргумента в блок?переменная экземпляра в блоках
Это не работает в Ruby 1.9 (формальный аргумент не может быть переменной экземпляра).
awesome do |foo, @bar|
puts 'yay'
end
Есть 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"
Ruby 1.9 делает параметры блока локальными для блока. Это также означает, что параметры блока больше не могут быть глобальными или переменными экземпляра. Вы можете использовать затворы для ваших целей:
@foo = 10
1.times do |i|
puts @foo
end
# => "10"
UPDATE Вместо того чтобы использовать переменные экземпляра, локальная переменная может помочь вам:
foo = 10
1.times do |i|
puts foo
end
# => "10"
В таких случаях, вы не получите проблемы, связанные с выполнение кода в другом контексте.
Спасибо за объяснение. Другие могут захотеть прочитать это [intro] (http://rubylearning.com/satishtalim/ruby_blocks.html). Моя проблема была не в этом, поэтому я задал новый вопрос. – m33lky
Кроме того, это решение: '[1,2,3] .each {| bar | @ bar = bar} 'взято из [здесь] (http://boga.wordpress.com/2008/04/15/ruby-19-porting-notes/). – m33lky