2011-08-30 8 views
7

私はモジュールの一部でStringクラスを拡張したいと思います。基本メタプログラミング:モジュールを使用して既存のクラスを拡張するか?

これは

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

include MyModule 

string = "this is a string" 
string.exclaim 

#=> NoMethodError 

を動作しません。しかし、これは私がMyModuleというの他のすべての機能を文字列に置き去りにされたくない

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

class String 
    include MyModule 
end 

string = "this is a string" 
string.exclaim 

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

を行います。最高レベルで再びそれを含むことは醜いようです。確かにこれを行うためのより純粋な方法がありますか?

答えて

25

最初の例のexclaimメソッドは、標準Stringクラスとは関係のないMyModule::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 
+0

非常に便利です。ありがとうございました。 – djb

+0

コメントの引用のためにUpvoted :-) – vijucat

1

私は私はあなたの質問を理解してきたかわからないが、なぜ、ファイル内のオープン文字列をしませんexclaim.rbを言う、そしてあなたがそれを必要なときにそれを必要とします。

exclaim.rb

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

、その後

require "exclaim" 

"hello".exclaim 

しかし、多分私は何かが欠けていますか?

+0

はいこの作品:

あなたのモジュールの内部では、このように(グローバル名前空間で)標準Stringクラスを開くことができます。しかし、私の質問は、文字列をモジュール内から直接変更できるかどうかです。 – djb

+0

ああ...今あなたの質問があります。幸いにも、@ Lars Haugsethは:) – lucapette

関連する問題