Как использовать define_method внутри initialize()
Попытка использовать 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>
Ответы
Ответ 1
Сделайте, как показано ниже:
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
в вашем случае.
Ответ 2
Я подозреваю, что вы ищете define_singleton_method
:
define_singleton_method (символ, метод) → new_method
define_singleton_method (символ) {block} → proc
Определяет однотонный метод в приемнике. Параметр метода может быть Proc
, a Method
или UnboundMethod
. Если задан блок, он используется как тело метода.
Если вы используете define_method
в 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'
и, вероятно, не то, что вы ищете. Создание нового экземпляра и изменение всего класса в результате довольно нечетное.