我已经提出了另一个答案,尽管已经指出了很大的区别(优先/约束力),但是这可能会导致很难发现问题(锡曼等人指出了这一点)。我认为我的示例显示了一个不那么常见的代码片段的问题,即使是经验丰富的程序员也不像星期天那样阅读:
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
(extend的结果与该块有什么关系……)
因此,如果要使用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