Ruby 拦截I18n转换/扩展Module.new{..}做什么?
我有一个很小的逻辑,就是直接在页面上使用AJAX进行I18n“就地翻译”。因此我想截取I18n 我的调查让我得出了这样一个逻辑——看起来既漂亮又干净:基于这个逻辑和一些“它怎么可能工作”的反复试验Ruby 拦截I18n转换/扩展Module.new{..}做什么?,ruby,ruby-on-rails-3.2,Ruby,Ruby On Rails 3.2,我有一个很小的逻辑,就是直接在页面上使用AJAX进行I18n“就地翻译”。因此我想截取I18n 我的调查让我得出了这样一个逻辑——看起来既漂亮又干净:基于这个逻辑和一些“它怎么可能工作”的反复试验 module I18n extend Module.new { old_translate=I18n.method(:translate) define_method(:translate) do |*args| InplaceTrans
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
及
Translator.new.translate()
只是一个技巧,所以在开发时我不必重新启动rails服务器
所有这些都工作得很好很稳定,但我真的不知道我在做什么
问题:
这是一种有效的(干净的)方法吗
扩展Model.new{…}
做什么
扩展Model.new DO与扩展Model.new有什么区别。。。结束?(对我来说似乎什么都不做)编辑:回答我自己:根据问题的结尾: 为什么
InplaceTrans.translate
内部I18n.新定义的\u方法()
解析为我的匿名模块。根据以下内容进行翻译:
创建一个新的匿名模块。如果给定一个块,它将通过
模块对象,并在该对象的上下文中计算该块
模块使用模块评估
所以它是有效的,但我真的想知道为什么
(RoR 1.9.3,3.2)
编辑:部分答案
extend Module.new{}
演变为extend(Module.new{})
鉴于
extend Module.new do/end
演变为extend(Module.new)do/end
因此,使用do/end,块将绑定到extend的结果。如果要使用do/end,则必须使用大括号:
extend(Module.new do/end)
与extend Module.new{}相同,下面是我想说的,我不知道是否还有其他(副作用)我不知道
让我们从一个模块开始:
module NiceOne
def self.init_param(param)
@base_param=param
end
def self.read_param
@base_param
end
def util_func(in_string)
in_string+NiceOne.read_param
end
end
让我们把它包含在一个类中
class HomeController < SiteController
...
include NiceOne
def sandbox
NiceOne.init_param(' the base param')
# later:NiceOne.write_other_param(' the other param')
puts NiceOne.read_param
#later: puts NiceOne.read_other_param
puts util_func('can we read')
end
end
如果您现在“手动”扩展NiceOne,如下所示:
module NiceOne
def self.write_other_param(param)
@base_param=param
end
def self.read_other_param
@base_param
end
end
并取消对HomeController中的两行的注释:
the other param
the other param
can we read the other param
到目前为止很简单,不是问题的答案,只是介绍
如果没有更优雅的方式来实现这一点,它就不会是Ruby:
我们保持HomeController
和NiceOne
(原件)未动,但将手册“扩展”更改为:
module NiceOneNicen
def write_other_param(param)
@base_param=param
end
def read_other_param
@base_param
end
end
module NiceOne
extend NiceOneNicen
end
我们得到了和以前一样的输出。这两种方法“移动”到(扩展)OneNice
类似于utli_func
到HomeController
。如果你想用你心爱的模块扩展多个模块,这是很有用的
但如果我们只需要一次?不要更改名称空间,我们会动态创建模块,即module.new
。所以
module NiceOne
dummy=Module.new {
def write_other_param(param)
...
end
}
extend dummy
end
最后
module NiceOne
extend Module.new {
def write_other_param(param)
...
end
}
end
如果询问do/end
,如果我们不忘记大括号,我们可以使用它
module NiceOne
extend( Module.new do
def write_other_param(param)
...
end
end)
end
所以-回答最后一个问题:使用module.new创建的匿名模块“只存在很短的时间”,并且只用于将其方法推送到OneNice
这样你就可以阅读
extend Module.new { .. }
像
module NiceOne
extend( Module.new do
def write_other_param(param)
...
end
end)
end
extend Module.new { .. }
"put a self. before every method in following" { }