メソッドを追加するメソッド
- シンプルに考えれば、以下のようにメソッド定義の中にメソッド定義を書いても良いと気付いた。(define_methodは必要ない?)
class Test
def self.make_foo
def foo
'foo'
end
end
end
test = Test.new
Test.make_foo
test.foo
=> "foo"
- それでは、define_methodを使うと、どんな良いことがあるのだろう?
class Test
def self.make_method(method)
define_method(method) do
method
end
end
end
test = Test.new
Test.make_method('free')
test.free
=> "free"
Test.make_method('free2')
test.free2
=> "free2"
- 追加定義するメソッド名を動的に設定したい時に便利だ。さらに、もっと大事なことが...
二重の(ネストした)defの場合
class Test
def self.make_foo
def foo
'foo'
end
end
end
class TestChild < Test
make_foo
end
TestChild.new.foo
=> "foo"
Test.new.foo
=> "foo"
class Test
def foo
'Test.foo'
end
end
TestChild.new.foo
=> "Test.foo"
- 二重の(ネストした)defメソッド定義の場合は、そのメソッドを定義しているクラスに対してメソッドが追加される。(冷静に考えてみれば、当然の動きである。)
define_methodの場合
- 同じことをdefine_methodでやってみた。
class Test
def self.make_foo
define_method(:foo) do
'foo'
end
end
end
class TestChild < Test
make_foo
end
TestChild.new.foo
=> "foo"
Test.new.foo
NoMethodError: undefined method 'foo' for
class Other
Test.make_foo
end
Other.new.foo
NoMethodError: undefined method 'foo' for
Test.new.foo
=> "foo"
- define_methodは、そのメソッドが実行された時のオブジェクトに対して、メソッドを定義するのだ!(Test.make_fooとなっていれば、Testクラスに定義される。)