如何在initialize()中使用define_method

Bal*_*ala 27 ruby metaprogramming

试图在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>
Run Code Online (Sandbox Code Playgroud)

mu *_*ort 43

我怀疑你在寻找define_singleton_method:

define_singleton_method(symbol,method)→new_method
define_singleton_method(symbol){block}→proc

在接收器中定义单例方法.该方法的参数可以是Proc,一个Method或一个UnboundMethod对象.如果指定了块,则将其用作方法体.

如果使用define_methodon self.class,则将新方法创建为整个类的实例方法,以便它可以作为类的所有实例上的方法使用.

你会这样使用define_singleton_method:

class C
  def initialize(s)    
    define_singleton_method(s) { puts "some method #{s}" }    
  end
end
Run Code Online (Sandbox Code Playgroud)

然后:

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'
Run Code Online (Sandbox Code Playgroud)

如果你initialize做了:

self.class.send(:define_method,n) { puts "some method #{n}" }    
Run Code Online (Sandbox Code Playgroud)

然后你会得到:

a.a # puts 'some method a'
a.b # puts 'some method b'
b.a # puts 'some method a'
b.b # puts 'some method b'
Run Code Online (Sandbox Code Playgroud)

那可能不是你想要的.创建一个新实例并让整个类更改是相当奇怪的.


Aru*_*hit 26

请执行以下操作:

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
Run Code Online (Sandbox Code Playgroud)

Module#define_method是一个私有方法,也是一个 method.Your一个没有工作,因为你试图调用它的实例C.你必须调用它C,用#send你的情况.

  • @Bala:请注意,`o = C.new('pancakes')` 会给你留下 `ob.abc`、`ob.pancakes`、`o.abc` 和 `o.pancakes` 作为有效的方法调用。每个人都确定这是意图吗? (2认同)