Ruby 如何通过实例求值重写类方法?

Ruby 如何通过实例求值重写类方法?,ruby,class,instance,Ruby,Class,Instance,我有一个带有方法栏的类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可以进行覆盖,但不保留上下文假设您希望更改模块Lorem,以便无论何时包含它

我有一个带有方法栏的类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可以进行覆盖,但不保留上下文

假设您希望更改模块Lorem,以便无论何时包含它,都将使用新条,您非常接近:

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

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

为此,您需要迭代这些对象,并使用ObjectSpace重写它们的方法,如中所示

以下情况没有帮助:

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
要覆盖在执行实例评估之前创建的对象的方法,请执行以下操作:

x = Foo.new

ObjectSpace.each_object(Foo) { |obj|
  def obj.bar
    puts "bar"
  end
}
您将获得以下输出:

x.bar
bar
=> nil

有什么问题吗。。然后你的问题是什么?你在上面所做的是有效的。。有什么问题吗?我刚试过,它确实盖过了福的bar@Abdo我比你早15分钟就糊涂了:-@ArupRakshit哈哈:-我希望一切都好,伙计:-j,是不是你想改变模块Lorem,以便无论何时包含它,您的新bar将被使用?class_eval不起作用,因为Lorem::Foo具有在classI中评估的实例和需求。我希望每次调用Lorem::Foo.new.bar都评估我的覆盖版本的bar,尽管先前存在代码/声明的变量。我刚才试过class_eval,切换到instance_evalI不理解你的评论。我将等待问题的澄清。@jquarin在代码的生命周期中,您如何确定Lorem::Foo的哪个实例应该具有哪个版本的barit不应该如此复杂,他想要的只是x.instance_eval{def bar;puts bar;end}是的,但您假设他引用了x。这段代码适用于Foo的所有实例。@bjhaid但是,如果他只想重写x的方法,那么您可能是对的=