2013-10-14 7 views
19

define_methodinitializeに入れようとしていますが、undefined_methodがdefine_methodになっています。私は間違って何をしていますか?initialize()内のdefine_methodの使い方

class C 
    def initialize(n)  
    define_method ("#{n}") { puts "some method #{n}" }  
    end 
end 

C.new("abc") #=> NoMethodError: undefined method `define_method' for #<C:0x2efae80> 
+0

あなたは何をしようとしていますか? –

+2

何も具体的ではなく、 'define_method'を使って動的にメソッドを定義する方法を見てみよう – Bala

答えて

20

次のように行います:あなたはのインスタンス上でそれを呼び出すようにしようとしたとして、

class C 
    def initialize(n)  
    self.class.send(:define_method,n) { puts "some method #{n}" }  
    end 
end 

ob = C.new("abc") 
ob.abc 
# >> some method abc 

Module#define_methodプライベートメソッドであり、またクラス method.Yourの一つが動作しませんでしたC。あなたの場合は#sendを使用してCに電話する必要があります。

+1

これは機能します。私の以前のバージョンが間違っている理由を説明できますか? – Bala

+1

@Bala: 'o = C.new( 'pancakes')'は、有効なメソッド呼び出しとして 'ob.abc'、' ob.pancakes'、 'o.abc'、' o.pancakes'を残すことに注意してください。誰もがこれが意図であると確信していますか? –

+1

@muistooshort:興味深いコメント。意図はありませんでしたが、今私はそれをオブジェクト固有(シングルトン)にする方法を考えています。 – Bala

33

私はあなたがdefine_singleton_methodを探していると思われる:

define_singleton_method(シンボル、メソッド)→NEW_METHOD
define_singleton_method(シンボル){ブロック}→procの

は、シングルトンを定義しますメソッドを呼び出します。 のメソッドのパラメータは、Proc,MethodまたはUnboundMethodオブジェクトです。ブロックが指定されている場合、ブロックはメソッド本体として使用されます。

あなたはself.classdefine_methodを使用している場合、それはクラスのすべてのインスタンス上のメソッドとして利用できるようになりますので、あなたは、クラス全体のインスタンスメソッドとして新しいメソッドを作成します。あなたのinitializeがした場合は

a = C.new('a') 
b = C.new('b') 
a.a # puts 'some method a' 
a.b # NoMethodError 
b.a # NoMethodError 
b.b # puts 'some method b' 

class C 
    def initialize(s)  
    define_singleton_method(s) { puts "some method #{s}" }  
    end 
end 

そして:

あなたはこのようdefine_singleton_methodを使用したい

self.class.send(:define_method,n) { puts "some method #{n}" }  

を、あなたが取得したい:

a.a # puts 'some method a' 
a.b # puts 'some method b' 
b.a # puts 'some method a' 
b.b # puts 'some method b' 

これはおそらくあなたが探しているものではありません。結果として新しいインスタンスを作成し、クラス全体を変更するのはむしろ奇妙です。

関連する問題