Действительно ли возможно заставить ключевое слово урожая работать в блоке, данном 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:
тест rb:4:in 'тест': никакой блок не дан (LocalJumpError) от теста 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!"
}
Думаю, это то, что вы ищете:
class Test
define_method :test do |&b|
b.call
end
end
Test.new.test {
puts "Hi!"
}
Подробнее на http://coderrr.wordpress.com/2008/10/29/using-define_method-with-blocks-in-ruby- 18 /