29

define_method内部で使用しようとしていますinitializeが、 undefined_method を取得してい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>
4

3 に答える 3

45

私はあなたが探していると思いますdefine_singleton_method

define_singleton_method(symbol, method) → new_method
define_singleton_method(symbol) { ブロック } → proc

レシーバーでシングルトン メソッドを定義します。メソッドパラメータは、、、またはオブジェクトにProcすることができます。ブロックが指定されている場合は、メソッド本体として使用されます。MethodUnboundMethod

define_methodonを使用するself.classと、新しいメソッドがクラス全体のインスタンス メソッドとして作成され、クラスのすべてのインスタンスでメソッドとして使用できるようになります。

define_singleton_method次のように使用します。

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

その後:

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'

あなたinitializeがした場合:

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'

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

于 2013-10-14T20:39:09.903 に答える
28

以下のようにしてください:

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プライベート メソッドであり、クラスメソッドでもCあります。C#send

于 2013-10-14T20:12:29.373 に答える
0

あなたはほとんどそこにいました。でクラスを指すだけでself.class、使用する必要さえありません:send

class C
  def initialize(n)    
    self.class.define_method ("#{n}") { puts "some method #{n}" }    
  end
end
ob = C.new('new_method')
ob2 = C.new('new_method2')
# Here ob and ob2 will have access to new_method and new_method2 methods

:method_missing次のような新しいメソッドをクラスに教えるためにも使用できます。

class Apprentice
  def method_missing(new_method)
    puts "I don't know this method... let me learn it :)"
    self.class.define_method(new_method) do
      return "This is a method I already learned from you: #{new_method}"
    end
  end
end
ap = Apprentice.new
ap.read
=> "I don't know this method... let me learn it :)"
ap.read
=> "This is a method I already learned from you: read"
于 2020-08-26T18:38:42.693 に答える