Можно ли сделать так, чтобы ключевое слово yield работало внутри блока, указанного для define_method? Простой пример:
class Test
define_method :test do |&b|
puts b # => #<Proc:...>
yield
end
end
Test.new.test {
puts "Hi!"
}
Этот код выдает следующую ошибку в Ruby 1.8.7 и 1.9.0:
test.rb: 4: в `test ': блок не указан (LocalJumpError)
из test.rb: 8
Странно то, что блочная переменная b != nil
, но block_given?
возвращает false. Является ли намеренное поведение Ruby не распознавать блоки по Proc объектам?
Редактировать: С уважением к Beerlington ответ: b.call()
это не то, что я ищу. Переменная блока использовалась только для указания того, что блок фактически задан и не обнаружен внутри define_method.
Причина, по которой мне нужно использовать yield
вместо block.call
Я готов написать какое-то расширение для способа определения новых классов в Ruby, поэтому любой код, который вы можете написать на чистом Ruby, должен приниматься при использовании моего расширения.
Таким образом, подобная семантика не может быть принята во внимание, потому что это заставляет пользователей моей библиотеки использовать только один правильный способ передать блок. Это нарушает правило TIMTOWTDI и не делает мою библиотеку прозрачной.
Пример из реальной жизни
Код ниже можно упростить до кода выше, так как my_def
использует define_method
:
require 'my_library'
class Test
# client can write 'my_def' instead of 'def' since
# my_library extends Class class
my_def :test, "some parameter" do
yield # oh no, error :(
end
end
Test.new.test {
puts "Hi!"
}