Ruby 拦截I18n转换/扩展Module.new{..}做什么?

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

我有一个很小的逻辑,就是直接在页面上使用AJAX进行I18n“就地翻译”。因此我想截取I18n

我的调查让我得出了这样一个逻辑——看起来既漂亮又干净:基于这个逻辑和一些“它怎么可能工作”的反复试验

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" {  }