【问题标题】:Basic metaprogramming: extending an existing class using a module?基本元编程:使用模块扩展现有类?
【发布时间】:2011-08-30 11:22:07
【问题描述】:

我希望我的模块的一部分可以扩展 String 类。

这不起作用

module MyModule
  class String
    def exclaim
      self << "!!!!!"
    end
  end
end

include MyModule

string = "this is a string"
string.exclaim

#=> NoMethodError 

但这确实

module MyModule
  def exclaim
    self << "!!!!!"
  end
end

class String
  include MyModule
end

string = "this is a string"
string.exclaim

#=> "this is a string!!!!!"

我不希望 MyModule 的所有其他功能在 String 中被隔离。在最高级别再次包括它似乎很难看。肯定有更简洁的方法吗?

【问题讨论】:

    标签: ruby scope metaprogramming


    【解决方案1】:

    第一个示例中的exclaim 方法是在一个名为MyModule::String 的类中定义的,它与标准String 类无关。

    在您的模块中,您可以像这样打开标准的String 类(在全局命名空间中):

    module MyModule
      class ::String
        # ‘Multiple exclamation marks,’ he went on, shaking his head,
        # ‘are a sure sign of a diseased mind.’ — Terry Pratchett, “Eric”
        def exclaim
          self << "!!!!"
        end
      end
    end
    

    【讨论】:

      【解决方案2】:

      我不确定我是否理解了你的问题,但为什么不在文件中打开字符串,比如 exclaim.rb,然后在需要时请求它:

      exclaim.rb

        class String
          def exclaim
            self << "!!!!!"
          end
        end
      

      然后

      require "exclaim"
      
      "hello".exclaim
      

      但也许我错过了什么?

      【讨论】:

      • 是的,这行得通。但我的问题是,可以直接从模块中修改 String 吗?
      • 哦...现在我有你的问题了。幸运的是,@Lars Haugseth 做到了:)
      猜你喜欢
      • 2016-07-17
      • 1970-01-01
      • 1970-01-01
      • 2015-05-14
      • 1970-01-01
      • 2011-09-25
      • 1970-01-01
      • 2015-07-14
      • 2020-10-30
      相关资源
      最近更新 更多