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

17
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 может создать метод экземпляра без создания новой области, но моя задача - определить метод класса .

    
задан Croplio 15.08.2010 в 14:47
источник

2 ответа

42

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

Поскольку вы уже знаете, как определять методы экземпляра (используя Module#define_method ), вы уже знаете все, что вам нужно знать. Вам просто нужно называть class_eval на одноколесный класс C вместо самого 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
    
ответ дан Jörg W Mittag 15.08.2010 в 15:53
источник
0

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

class << C
  define_method(:a_class_method) do
     # do something
  end
end
    
ответ дан Nafaa Boutefer 12.12.2016 в 22:50
источник