Я поставил другой ответ, хотя большая разница уже была указана (prcedence / binding), и это может привести к трудностям при поиске проблем (Жестянщик и другие указали на это). Я думаю, что мой пример показывает проблему с не очень обычным фрагментом кода, даже опытные программисты не читают как воскресные времена:
module I18n
extend Module.new {
old_translate=I18n.method(:translate)
define_method(:translate) do |*args|
InplaceTrans.translate(old_translate, *args)
end
alias :t :translate
}
end
module InplaceTrans
extend Module.new {
def translate(old_translate, *args)
Translator.new.translate(old_translate, *args)
end
}
end
Затем я сделал некоторый код, украшающий ...
#this code is wrong!
#just made it 'better looking'
module I18n
extend Module.new do
old_translate=I18n.method(:translate)
define_method(:translate) do |*args|
InplaceTrans.translate(old_translate, *args)
end
alias :t :translate
end
end
если вы измените {}
здесь, do/end
вы получите ошибку, этот метод translate
не существует ...
Почему это происходит, указывается здесь более чем один - приоритет. Но где поставить скобки здесь? (@ Оловянный человечек: я всегда использую брекеты, как и вы, но здесь ... под присмотром)
так что каждый ответ нравится
If it's a multi-line block, use do/end
If it's a single line block, use {}
просто неправильно, если используется без «НО Следите за фигурными скобками / приоритетом!»
очередной раз:
extend Module.new {} evolves to extend(Module.new {})
и
extend Module.new do/end evolves to extend(Module.new) do/end
(что когда-либо делает результат с блоком ...)
Так что если вы хотите использовать do / end, используйте это:
#this code is ok!
#just made it 'better looking'?
module I18n
extend(Module.new do
old_translate=I18n.method(:translate)
define_method(:translate) do |*args|
InplaceTrans.translate(old_translate, *args)
end
alias :t :translate
end)
end