Umieściłem kolejną odpowiedź, chociaż wskazano już dużą różnicę (pierwszeństwo / wiązanie), a to może powodować trudne do znalezienia problemy (zwrócił na to uwagę Blaszany Człowiek i inni). Myślę, że mój przykład pokazuje problem z niezbyt zwykłym fragmentem kodu, nawet doświadczeni programiści nie czytają jak w niedzielę:
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
Potem zrobiłem kod upiększający ...
#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
jeśli zmienisz {}
tutaj na do/end
to otrzymasz błąd, ta metoda translate
nie istnieje ...
Dlaczego tak się dzieje, wskazuje się tutaj więcej niż jeden - pierwszeństwo. Ale gdzie tu założyć aparat? (@ The Tin Man: zawsze używam szelek, tak jak ty, ale tutaj ... przeoczony)
więc każda odpowiedź jak
If it's a multi-line block, use do/end
If it's a single line block, use {}
jest po prostu błędne, jeśli jest używane bez „ALE Miej oko na nawiasy klamrowe / pierwszeństwo!”
jeszcze raz:
extend Module.new {} evolves to extend(Module.new {})
i
extend Module.new do/end evolves to extend(Module.new) do/end
(co kiedykolwiek wynik rozszerzenia robi z blokiem ...)
Więc jeśli chcesz użyć do / end, użyj tego:
#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