0

我想使用 class_eval 扩展某些类的功能。我想强制类从其他类继承一些方法。

IE:

SomeClass.class_eval do
  # force inheritence from some other class
end

实现它的最佳方法是什么?

4

2 回答 2

1

如果在这里覆盖现有功能是一项硬性要求,您需要在包含的模块中定义这些现有方法。

class SomeClass
  include DefaultBehaviour
end

module DefaultBehaviour
  def run
    puts "ran default"
  end
end

module AlternateBehaviour
  def run
    puts "ran alternate"
  end
end

SomeClass.class_eval {
  include AlternateBehaviour
}

SomeClass.new.run #=> "ran alternate"

原因是因为 ruby​​ 的方法查找路径。

它从 SomeClass -> Object 开始。

当您包含 AlternateBehaviour 时,它变为 SomeClass -> AlternateBehaviour -> Object。所以直接在 SomeClass 上定义的方法仍然优先。

但是,如果在 DefaultBehaviour 上定义了这些方法,则查找路径将变为 SomeClass -> AlternateBehaviour -> DefaultBehaviour -> Object,因此您的替代方法优先。最近包含的模块是最高优先级的。

在您无法控制原始类的情况下,您可以改为:

module AlternateBehaviour
  def self.included(base)
    base.send(:remove_method, :run)
  end

  def run
    puts "ran alternate"
  end
end

虽然在这一点上,人们开始怀疑你是否可以通过做

SomeClass.class_eval {
  def run
    "ran alternate"
  end
end
于 2012-04-04T04:23:45.200 回答
0

尝试使用includeand extend,这里都解释。它们仅适用于模块;在 Ruby 中创建一个类之后,您就不能修改/添加它的超类。

只有一个问题:你不能覆盖一个类中已经存在的方法来解释这篇文章的第三条评论。

另请参阅主题以获取更多信息。

于 2012-04-04T02:08:11.150 回答