J'ai mis une autre réponse, bien que la grande différence ait déjà été signalée (précedence / binding), et que cela peut poser des problèmes difficiles à trouver (le Tin Man, et d'autres l'ont souligné). Je pense que mon exemple montre le problème avec un extrait de code pas si habituel, même les programmeurs expérimentés ne lisent pas comme les dimanches:
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
Ensuite, j'ai fait du code embellissant ...
#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
si vous changez {}
ici, do/end
vous obtiendrez l'erreur, cette méthodetranslate
n'existe pas ...
Pourquoi cela se produit est souligné ici plus d'un - la préséance. Mais où mettre des accolades ici? (@the Tin Man: j'utilise toujours des accolades, comme vous, mais ici ... supervisé)
donc chaque réponse comme
If it's a multi-line block, use do/end
If it's a single line block, use {}
est tout simplement faux s'il est utilisé sans le "MAIS Gardez un œil sur les accolades / priorité!"
encore:
extend Module.new {} evolves to extend(Module.new {})
et
extend Module.new do/end evolves to extend(Module.new) do/end
(ce que fait le résultat de extend avec le bloc ...)
Donc, si vous voulez utiliser do / end, utilisez ceci:
#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