Как использовать 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'

и, вероятно, не то, что вы ищете. Создание нового экземпляра и изменение всего класса в результате довольно нечетное.