我试图通过将常用方法移动到模块或类中并将其包含/继承在不同模块下命名空间的新类中。如果我在同一个模块下有两个类命名空间,那么只要我在同一个命名空间下,我就可以在不包括模块名称的情况下调用它们。但是,如果我有一个从不同模块中包含的方法,而不是我的命名空间范围更改,我不知道为什么或如何避免它。
例如。此代码有效并返回“bar”:
module Foo
class Bar
def test_it
Helper.new.foo
end
end
end
module Foo
class Helper
def foo
'bar'
end
end
end
Foo::Bar.new.test_it
但是如果我将方法 test_it 移到一个模块中,那么它就不再起作用了:NameError: uninitialized constant Mixins::A::Helper.
module Mixins; end
module Mixins::A
def self.included(base)
base.class_eval do
def test_it
Helper.new.foo
end
end
end
end
module Foo
class Bar
include Mixins::A
end
end
module Foo
class Helper
def foo
'bar'
end
end
end
Foo::Bar.new.test_it
此外,如果 class_eval 正在评估字符串而不是块,则范围变为 Foo::Bar 而不是 Foo。
module Mixins; end
module Mixins::A
def self.included(base)
base.class_eval %q{
def test_it
Helper.new.foo
end
}
end
end
module Foo
class Bar
include Mixins::A
end
end
module Foo
class Helper
def foo
'bar'
end
end
end
Foo::Bar.new.test_it
有人有想法吗?
编辑:
多亏了 Wizard 和 Alex,我最终得到了这段代码,它并不漂亮,但可以完成工作(注意它使用的是 Rails helper constantize):
module Mixins; end
module Mixins::A
def self.included(base)
base.class_eval do
def test_it
_nesting::Helper
end
def _nesting
@_nesting ||= self.class.name.split('::')[0..-2].join('::').constantize
end
end
end
end
module Foo
class Helper
end
class Bar
include Mixins::A
end
end
module Foo2
class Helper
end
class Bar
include Mixins::A
end
end
Foo::Bar.new.test_it #=> returns Foo::Helper
Foo2::Bar.new.test_it #=> returns Foo2::Helper