我在命名空间中使用一些方法获得了一个类
module Foo
module Bar
class Baz
def initialize(arg1, arg2, arg3)
# do stuff
end
def delete
File.delete(@path)
end
end
end
end
在我的测试环境中,我不希望delete
删除任何文件,所以在TestHelper
中我会这样做
class Foo::Bar::Baz
def delete
puts "no delete in test"
end
end
当我在测试中初始化此类时,我得到ArgumentError: wrong number of arguments (3 for 0)
。也就是说,Baz
的初始化方法已经消失。可以肯定的是,如果我在测试助手中查看self
,则Baz
根本没有定义任何方法。它已被class
关键字完全覆盖。
我可以使用class_eval
而不是class
来实现它,我,e。
Foo::Bar::Baz.class_eval do
def delete
# etc
end
end
我的问题是,有什么区别?为什么后者有效而不是前者?
答案 0 :(得分:1)
我可能错了,但我认为您不小心打破了自动加载器。以下是我认为您的工作案例(使用.class_eval
):
Foo::Bar
的代码(如果没有发生,您将收到其他错误)TestHelper
TestHelper
引用Foo::Bar::Baz
,但不存在foo/bar/baz.rb
TestHelper
运行class_eval
并重新定义#delete
这是我对非工作案例的猜测:
Foo::Bar
TestHelper
TestHelper
创建 Foo::Bar::Baz
,因为它尚未存在请注意,在第二种情况下,自动加载器从未被触发,因此永远不会加载您的实际类定义。
我不确定解决此问题的最佳方法。您可以在测试中执行明确的要求,或者在重新定义之前仅在助手中引用该类:
Foo::Bar::Baz # trigger autoloading before we muck with the definition
class Foo::Bar::Baz
def delete
puts "no delete in test"
end
end