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という新しいクラスを定義しています。組み込みのRubyStringクラスを変更する場合、モジュール内で宣言を保持する場合は、Stringの完全修飾名( "" :: "を含む)を使用する必要があります。

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

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

「::」を追加すると、必要なStringクラスがTestModuleの一部ではないことがRubyに通知されます。

同じファイル内の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 に答える