4

我知道我可以执行以下将方法添加到 String 类

class String
  def do_something
    puts self.size
  end
end

var = "test"
var.do_something

这将返回4

我希望能够拥有一个带有接收字符串的函数的模块,但能够do_something在该字符串上调用该方法(例如见下文) - 有可能吗?

编辑:添加了不起作用的示例代码

module TestModule
  class String
    def do_something
      puts self.size
    end
  end

  def self.test(str)    
    str.do_something
  end
end

这给出了错误:undefined method 'do_something' for "hello":String (NoMethodError)

4

2 回答 2

8

编写代码的方式是定义一个名为 TestModule::String 的新类。如果要修改内置的 Ruby String 类,如果要将声明保留在模块中,则需要使用 String 的完全限定名称(带有“”::“)。

module TestModule
  class ::String
    def do_something
      puts self.size
    end
  end

  def self.test(str)  
    str.do_something
  end
end

添加 "::" 告诉 Ruby 你想要的 String 类不是 TestModule 的一部分。

在同一个文件中在 TestModule 之外声明 String 可能更干净。

如果您不想污染全局 String 类,则可以只修改要添加方法的特定 String 实例。

module TestModule
  def self.test(str)  
    do_somethingify!(str)
    str.do_something
  end

  def self.do_somethingify!(str)
    unless str.respond_to? :do_something
      str.instance_eval do
        def do_something
          puts size
        end
      end
    end
  end      
end          
于 2011-04-16T19:05:05.633 回答
3

也许这个?

module TestModule
  module_function
  def test(str)
    str.instance_eval{doSomething}
  end
end

Test.test(str)

编辑由于问题的变化而改变

只需将外部的定义放在doSomething课堂之外TestModule

class String
  def doSomething
    puts size
  end
end

module TestModule
  module_function
  def test(str)  
    str.doSomething
  end
end
于 2011-04-16T18:27:55.813 回答