尝试在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>
答案 0 :(得分:39)
我怀疑你正在寻找define_singleton_method
:
define_singleton_method(symbol,method)→new_method
define_singleton_method(symbol){block}→proc在接收器中定义单例方法。 方法参数可以是
Proc
,Method
或UnboundMethod
对象。如果指定了块,则将其用作方法体。
如果在self.class
上使用define_method
,则会将新方法创建为整个类的实例方法,以便它可以作为该类的所有实例的方法。
您可以像这样使用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'
这可能不是你想要的。创建一个新实例并让整个类更改是相当奇怪的。
答案 1 :(得分:25)
执行以下操作:
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
是一个私有方法,也是一个类方法。您尝试在{的实例上调用它时,一个方法无法正常工作{1}}。您必须在C
上使用C
进行调用。
答案 2 :(得分: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"