Пожалуйста, обратите внимание на следующие различные способы для определения метода m
:неявный блок прохождения и динамически определенные методы
Метод 1:
class C def m; yield; end end
Метод 2:
class C def initialize (class << self; self; end).class_eval do define_method(:m){|&b| b.call } end end end
Способ 3:
class C def initialize (class << self; self; end).class_eval do define_method(:m){puts block_given?; yield} end end end
Тогда я могу вызвать m
с помощью Object#send
.
o = C.new
o.send(:m) {puts 'test'}
Призывая m
, используя метод 1 или метод 2 работает отлично, Метод 3 дает эту ошибку:
no block given (yield) (LocalJumpError)
Я понимаю, что блок не является объектом, но вместо того, чтобы просто часть метода вызова синтаксис и вы не можете передать неявный блок от одной функции к другой, не писать что-то неясное, как это:
def printer
yield
end
def proxy
printer &Proc.new
end
proxy { puts "&Proc.new probably creates Proc object from block"}
Но в таком случае, почему метод 1 работает? Было бы здорово получить ответ, который объяснил бы, что происходит под капотом.
Непонятно, что вы подразумеваете под «define ... static», «с явным блоком» или «первым случаем». Я могу догадаться, что вы, вероятно, упоминали либо ваш метод 1, метод 2, либо метод 3, но неясно, какой из них. – sawa
@sawa Я думал, что это будет ясно с фрагментом кода. Вы цитировали метод 1, метод 2 и метод 1 соответственно :) – yuyoyuppe
Почему вы использовали 'send' для вызова' m'? Не похоже, что это имеет какое-то значение. – sawa