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) { block } → proc

在接收器中定义一个单例方法。方法参数可以是 a 、ProcaMethodUnboundMethod对象。如果指定了块,则将其用作方法体。

如果您使用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 回答