Я поставив ще один відповідь, хоча велика різниця вже була вказана (prcedence / прив'язка), і це може спричинити важкі проблеми (Чоловік з жерсті та інші вказали на це). Я думаю, що мій приклад показує проблему з не таким звичним фрагментом коду, навіть досвідчені програми не читають, як у неділю:
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
не існує ...
Чому це трапляється, тут вказується більше, ніж один. Але куди тут поставити брекети? (@ The Tin Man: Я завжди використовую брекети, як ти, але тут ... під наглядом)
тому кожна відповідь, як
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