基本元编程:使用模块扩展现有类?

时间:2011-08-30 11:22:07

标签: ruby scope metaprogramming

我希望我的模块的一部分扩展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中。在最高级别再次包括它似乎很难看。当然有一种更简洁的方法吗?

2 个答案:

答案 0 :(得分:26)

第一个示例中的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

答案 1 :(得分:1)

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

exclaim.rb

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

然后

require "exclaim"

"hello".exclaim

但也许我错过了什么?