Добавляйте методы класса ruby ​​или методы экземпляра динамически - PullRequest
10 голосов
/ 12 сентября 2011

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

Вот как я генерировал методы экземпляра:

  class B
    def before_method
      puts "before method"
    end

    def self.run(method)
        send :define_method, method do
          before_method
          puts "method #{method}"
        end
    end
  end

  class A < B
    run :m
    run :n
  end

Есть идеи о лучших способах создания статических методов?

Моя последняя задача - найти лучший способ создания задач «до» и «после» для методов класса.

Ответы [ 3 ]

25 голосов
/ 22 февраля 2013

Чтобы динамически создавать методы экземпляра, попробуйте

class Foo
  LIST = %w(a b c)

  LIST.each do |x|
    define_method(x) do |arg|
      return arg+5
    end
  end
end

Теперь любой экземпляр Foo будет иметь метод "a", "b", "c". Попробуйте

Foo.new.a(10)

Чтобы определить методы класса динамически, попробуйте

class Foo
  LIST = %w(a b c)

  class << self
    LIST.each do |x|
      define_method(x) do |arg|
        return arg+5
      end
    end
  end
end

Тогда попробуйте

Foo.a(10)
8 голосов
/ 12 сентября 2011

Методы экземпляра одноэлементного класса объектов - это одноэлементные методы самого объекта. Так что если вы делаете

class B
  def self.run(method)
    singleton_class = class << self; self; end
    singleton_class.send(:define_method, method) do
        puts "Method #{method}"
    end
  end
end

теперь можно звонить

B.run :foo
B.foo 
=> Method foo

(Редактировать: добавлено B.run: foo согласно комментарию Ларса Хаугсета)

1 голос
/ 12 сентября 2011

Вот что-то переработанное для использования методов класса:

class B
   def self.before_method
     puts "before method"
   end

  def self.run(method)
    define_singleton_method(method) do
      before_method
      puts "method #{method}"
    end
  end
end

Обновление: Использование define_singleton_method из Ruby 1.9, которое правильно присваивается классу eigenclass .

...