Можно ли сделать ключевое слово 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!"
}