动态添加ruby类方法或实例方法

时间:2011-09-12 18:57:24

标签: ruby class metaprogramming instance

我对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 个答案:

答案 0 :(得分:25)

要动态创建实例方法,请尝试

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)

答案 1 :(得分:8)

对象单例类的实例方法是对象本身的单例方法。所以,如果你这样做

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

(编辑:根据Lars Haugseth的评论补充B.run:foo)

答案 2 :(得分:1)

以下是使用类方法重新编写的内容:

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

更新:使用Ruby 1.9中的define_singleton_method正确分配给eigenclass