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

18
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 ответа

44

Методы класса в 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
источник
  • Спасибо, очень! –  Croplio 15.08.2010 в 16:27
  • Отличный ответ. Не могли бы вы поделиться ссылками на рубиновскую документацию по метапрограмме методов класса? благодаря –  mattgathu 27.06.2017 в 15:20
  • @mattgathu: В Ruby нет методов класса. Существует только один вид методов: методы экземпляра. –  Jörg W Mittag 27.06.2017 в 15:22
  • Я пытаюсь реализовать метод singleton, который принимает параметры. Как мне это сделать? –  mattgathu 27.06.2017 в 15:40
  • @mattgathu: В Ruby нет такого метода, как одноэлементный метод. Метод singleton - это просто обычный метод экземпляра, определенный в одноэлементном классе. Вы определяете метод singleton с параметрами точно так же, как вы определяете метод экземпляра с параметрами, потому что существуют только методы экземпляра. Методы Singleton и методы класса ничего особенного, потому что их не существует. –  Jörg W Mittag 27.06.2017 в 16:34
0

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

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