如何通过instance_eval覆盖类方法?

时间:2014-02-17 20:54:32

标签: ruby class instance

我有一个带有方法栏的Foo类。如何用

覆盖foo的栏
Foo.instance_eval do
  def bar
    #do something a little different
  end
end

什么是被覆盖的:

module Lorem
  class Foo
    def bar
      # do something
    end
  end
end

instance_eval需要使用,class_eval适用于覆盖但不保留上下文

2 个答案:

答案 0 :(得分:0)

假设您要更改module Lorem,以便每当包含新版bar()时,您就会非常接近:

module Lorem
  class Foo
    def bar
      puts "old bar"
    end
  end
end

Lorem::Foo.class_eval do
  def bar
    puts "new bar"
  end
end

class A
  include Lorem
  Foo.new.bar #=> "new bar"
end

答案 1 :(得分:0)

我认为您尝试实现的问题是您尝试覆盖已创建的对象的方法。

为了做到这一点,你需要迭代这些对象并使用ObjectSpace覆盖他们的方法,如https://stackoverflow.com/a/14318741/226255

以下内容无效:

class Foo
  def bar
    puts "hello"
  end
end

x = Foo.new

Foo.instance_eval do
  def bar
    puts "bar"
  end
end

x.bar

您将获得以下输出:

hello
=> nil

要在执行instance_eval之前覆盖创建的对象的方法,请执行以下操作:

x = Foo.new

ObjectSpace.each_object(Foo) { |obj|
  def obj.bar
    puts "bar"
  end
}

你得到了输出:

x.bar
bar
=> nil