実際に手動で挿入することなくクラスとサブクラスの各メソッドの先頭に動的に簡単にコードを挿入できますか?私はマクロのようなものが欲しい。クラスの各メソッドの先頭にコードを挿入
class C1
def m1
@i_am = __method__
end
def m2
@i_am = __method__
end
end
これは繰り返しを避けたい例の1つです。
実際に手動で挿入することなくクラスとサブクラスの各メソッドの先頭に動的に簡単にコードを挿入できますか?私はマクロのようなものが欲しい。クラスの各メソッドの先頭にコードを挿入
class C1
def m1
@i_am = __method__
end
def m2
@i_am = __method__
end
end
これは繰り返しを避けたい例の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_method とModule#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
関数が同じであるとすると、モジュールを作成してクラスに含めることができます。
例:
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"
あなたはそれにクラスデコレーターのようなレールを使用することができます。以下のコードは、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
クラスの他のすべてのメソッドに適用できます。これは、ルビのマクロを表現する方法です。
例の意図は明確ではありません。 – sawa
@澤、そうではありません。 – Ramano
Ramano、askersは質問が読者にはっきりしているかどうかを判断するのに最適な立場にはありません。私はこれで@sawaと一緒にいます。 –