2016-07-30 7 views
-3

実際に手動で挿入することなくクラスとサブクラスの各メソッドの先頭に動的に簡単にコードを挿入できますか?私はマクロのようなものが欲しい。クラスの各メソッドの先頭にコードを挿入

class C1 
    def m1 
    @i_am = __method__ 
    end 

    def m2 
     @i_am = __method__ 
    end 
end 

これは繰り返しを避けたい例の1つです。

+0

例の意図は明確ではありません。 – sawa

+0

@澤、そうではありません。 – Ramano

+1

Ramano、askersは質問が読者にはっきりしているかどうかを判断するのに最適な立場にはありません。私はこれで@sawaと一緒にいます。 –

答えて

1

私は最初、質問を誤って解釈しました(ただし、下の水平線の後に私の元の答えが残っています)。私は次のことがあなたが探しているものかもしれないと信じています。

class C1 
    [:m1, :m2].each do |m| 
    define_method(m) do |name| 
     @i_am = __method__ 
     puts "I'm #{name} from method #{@i_am}" 
    end 
    end 
end 

C1.instance_methods(false) 
    #=> [:m1, :m2] 
c1 = C1.new 
    #=> #<C1:0x007f94a10c0b60> 
c1.m1 "Bob" 
    # I'm Bob from method m1 
c1.m2 "Lucy" 
    # I'm Lucy from method m2 

私のオリジナルのソリューションは、以下の通りです。

​​

Module#alias_methodModule#define_methodはプライベートです。したがって、sendを使用する必要があります。

c = C1.new 
    #=> #<C1:0x007ff5e3023650> 
C1.instance_methods(false) 
    #=> [:m1, :m2, :add_code_to_beginning] 

c.add_code_to_beginning(:m1) do 
    puts "hiya" 
end 

C1.instance_methods(false) 
    #=> [:m1, :m2, :add_code_to_beginning, :old_m1] 
c.m1 
    # hiya 
    #=> :m1 
+0

と誤解するだけで、どのように簡単に各メソッドに同じコードを挿入するより簡単ですか? – Ramano

+0

良い点。コードをメソッドにパッケージ化しました。 –

+0

はクラス内に新しいパブリックメソッドを作成しますが、私はそれを望んでいません。 – Ramano

-1

関数が同じであるとすると、モジュールを作成してクラスに含めることができます。

例:

module MyModule 
    def test_method 
    puts "abc" 
    end 
end 

class MyClass 
    include MyModule 
    def my_method 
    puts "my method" 
    end 
end 

inst = MyClass.new 
inst.test_method # => should print "abc" 
inst.my_method # => should print "my method" 
0

あなたはそれにクラスデコレーターのようなレールを使用することができます。以下のコードは、ActiveRecordモジュールのBaseクラスに定義されたbefore_actionというメソッドをレンダリングしています。 TestクラスはActiveRecordから継承されています。 define_methodは、Baseクラスから明示的に何かを呼び出す場合に使用されます。

module ActiveRecord 
    class Base 

     def self.before_action(name) 
      puts "#{name}" 
      puts "inside before_action of class Base" 

      define_method(name) do 
       puts "Base: rendering code from Base class" 
      end 
     end 
    end 
end 

class Test < ActiveRecord::Base 

    before_action :hola 

    def render() 
     puts "inside render of class Test" 
    end 

end 

test = Test.new 
test.render 
test.hola 

それはBaseクラスのbefore_actionメソッドを実行しますrender方法を実行する前に、だから、出力

hola 
inside before_action of class Base 
inside render of class Test 
Base: rendering code from Base class 

を持っています。 Testクラスの他のすべてのメソッドに適用できます。これは、ルビのマクロを表現する方法です。

関連する問題