如何防止 类 在 Ruby 中被覆盖?

How to prevent classes to be overridden in Ruby?

我正在设置如何编写迷你测试的规则,我想防止其他程序员覆盖现有 classes 的方法,因为它会影响其他测试,而这个 class 将使用。以下是一些说明。

比如我在lib文件夹下有一个class,KlassExample。它有一个 public 方法 do_something 和自己的逻辑。在 minitest 中,有人可能想用其他逻辑覆盖此方法。如果 class 逻辑被覆盖,我不想允许 运行 测试。

代码示例:

lib/klass_example.rb

class KlassExample

  def do_something
    false
  end

end

测试/单元/lib/klass_example_test.rb

require 'unit/test_helper'
require 'klass_example'

class KlassExample

  def do_something
    true
  end

end

class KlassExampleTest < Minitest::Test

  def test_do_something
    assert_equal true, KlassExample.new.do_something
  end

end

我希望程序员使用 MiniTest::Mock 而不是 class 覆盖,所以我需要一些强制措施让他们以正确的方式编写代码.

是否有任何可能的复杂解决方案如何做?

虽然通过在 class re-opening 上设置 TracePoint 和例如从那里开始,你永远不会阻止 所有 显式和隐式地内置到 Ruby 中的可能性,以确实 允许 开发人员做他们想做的事.

覆盖 Module#prepended 回调将不允许其他人将 prepend 模块添加到您的 class:

KlassExample.prepend(Module.new { def self.prepended(*); raise end })

有一些方法可以防止 Module#define_method 调用,而且它们看起来已经很像黑客了。

但是愚弄你的警卫的可能性几乎是无限的,所以我怀疑它在一般情况下是否可行。我敢打赌,每次你会想“好吧,现在一切都被覆盖了”,我会很容易地发明另一种笨拙的方法来绕过你所有的守卫。

Ruby 不是旨在 阻止 开发人员为所欲为的语言。