Подтвердить что ты не робот

Как динамически определить метод класса, который будет ссылаться на локальную переменную снаружи?

class C
end

var = "I am a local var outside"

C.class_eval do
   def self.a_class_method
     puts var 
   end
end

Я знаю, это неверно, потому что def создал новую область. Я также знаю, что использование define_method может создать метод экземпляра без создания новой области, но моя задача - определить метод класса.

4b9b3361

Ответ 1

Методы класса в Ruby действительно не существуют, это всего лишь одноэлементные методы объекта класса. Одиночные методы на самом деле не существуют, они просто обычные методы экземпляра класса Singleton класса.

Поскольку вы уже знаете, как определить методы экземпляра (используя Module#define_method), вы уже знаете все, что вам нужно знать. Вам просто нужно вызвать class_eval в C singleton class вместо C:

(class << C; self end).class_eval do
  define_method(:a_class_method) do
    puts var 
  end
end

В текущих версиях Ruby есть метод singleton_class, чтобы сделать это проще:

C.singleton_class.class_eval do
  define_method(:a_class_method) do
    puts var 
  end
end

Но на самом деле текущие версии Ruby также имеют Module#define_singleton_method, поэтому в этом конкретном случае это необязательно:

C.define_singleton_method(:a_class_method) do
  puts var 
end

Ответ 2

вы можете сделать это просто так.

class << C
  define_method(:a_class_method) do
     # do something
  end
end

Ответ 3

C.instance_eval do
  def class_method
    "This is class method"
  end
end

instance_eval: определяет одноэлементные методы для объекта (что приводит к методам класса, когда он вызывается для объекта класса).

class_eval: определяет обычные методы экземпляра