2009-08-29 5 views
1

私は、特定のメソッドでクラスを取り、メソッドを追加したり、既存のメソッドの仕組みを変更したりして、その動作を変更するメソッドをrubyに書きたいと思います。私は基本クラスを変更しないようにこれを行いたいので、基本的には、クラスを受け取り、初期クラスを損なうことなく新しい変更されたクラスを返す関数が必要です。私はこれが可能だと確信していますが、私はどこから始めるべきかわかりません。ruby​​ class extensions

答えて

2

あなたはカップルのオプションがありますたとえば、特定のメソッド呼び出しを記録したクラスを動的に作成する場合は、次のようになります。

class Class 
    def logging_subclass(*methods) 
    Class.new(self) do 
     methods.each do |method| 
     define_method(method) do |*args,&blk| 
      puts "calling #{method}" 
      ret = super(*args,&blk) 
      puts "#{method} returned #{ret.inspect}" 
      ret 
     end 
     end 
    end 
    end 
end 

class One 
    def foo 
    "I'm foo!" 
    end 
end 

# this prints nothing 
One.new.foo #=> returns :foo 

# this prints: 
# > calling foo 
# > foo returned "I'm foo!" 
One.logging_subclass(:foo).new.foo #=> returns :foo 

do |&blk|(ブロック引数のブロックをキャプチャ)をサポートするには、ルビ1.9が必要であることに注意してください。

+0

スーパーコールからの引数リストを完全に中断できませんか?あなたが他に何かを与えない限り、Superは現在のメソッドと同じ引数を使用することになっています。しかしClass.newはDavidが探しているものとまったく同じように聞こえる。 – Chuck

+0

通常の定義ではできますが、 'define_method'ではできません。' Runtime Error:define_method()で定義されたメソッドからのsuperを渡す暗黙の引数はサポートされていません。すべての引数を明示的に指定します.davidk01が常に同じメソッドを再定義する場合、通常の 'def meth ... end'構文が機能します。 – rampion

1

inheritanceまたはa mixinを使用することをお勧めします。私の意見では、ミックスインの使用は、継承を使用することは初心者の方が簡単ですが、より賢明なアイデアになります。

いつでもクラスから継承し、動作を変更したり、必要に応じて新しいコードでラップすることができます。

critters = [Mutated_Kitty.new] 
begin 
    critters.each { |c| c.reproduce(critters) } 
end while critters.length > 0 

をそれとも、おそらくセグメンテーションフォルトRAMを使い果たすまで、または他のあなたは長い待ち時間のためにあるでしょう:

class Mammal 
    def speak 
    "..." 
    end 
end 

class Cat < Mammal 
    def speak 
    "meow" 
    end 
end 

class Lion < Cat 
    def speak 
    "get ready for a big " + super + "!" 
    end 
end 

module Asexual_Critter 
    def reproduce(critter_list) 
    puts "*poink!*" 
    critter_list << self.clone 
    end 
end 

class Mutated_Kitty < Cat 
    include Asexual_Critter # inane example I know, but functional... 
end 

はちょうどあなたがこれを再生したい場合はやっていないことを覚えておいてください。あなたがそうDelegator

を使用することができます

  • あなたが動的にクラスを定義し、メソッド(&は新しいものを定義)をオーバーライドしx = Class.new(Parent) { def meth; puts "hello"; super; puts "bye"; end }を使用することができます
0

あなたの質問が間違っていると申し訳ございませんが、Googleの "ruby dsl"と、あなたの問題に非常に役立つことがあります。 でも、このことについてここで質問された質問をチェックしてください。

チェックアウトこの記事をuが開始する方法がわからない場合:

[http://www.jroller.com/rolsen/entry/building_a_dsl_in_ruby][1] 

私はテキストファイルに行った変更を保存して前にそのような何かをした、とするときもう一度そのファイルを読み込みますプログラムが再起動したり、設定がリロードされたりします。

関連する問題