Ruby模块,带有来自includer类的静态方法调用
我需要在模块中定义使用包含此模块的类中的方法的常量:
module B def self.included(base) class << base CONST = self.find end end end class A def self.find "AAA" end include B end puts A::CONST
但是编译器会在第4行给出错误。
有没有其他方法来定义常量?
在Ruby中实现这一点的更惯用的方法是:
module B def self.included(klass) klass.class_eval <<-ruby_eval CONST = find ruby_eval # note that the block form of class_eval won't work # because you can't assign a constant inside a method end end class A def self.find "AAA" end include B end puts A::CONST
你正在做什么(类<< base)实际上让你进入A的metaclass
的上下文,而不是A本身。 find
方法是A本身,而不是它的元类。 要记住的是,类本身就是对象,因此有自己的元类。
试图让它更清晰:
class Human def parent # this method is on the Human class and available # to all instances of Human. end class << self def build # this method is on the Human metaclass, and # available to its instance, Human itself. end # the "self" here is Human's metaclass, so build # cannot be called. end def self.build # exactly the same as the above end build # the "self" here is Human itself, so build can # be called end
不确定这是否有帮助,但是如果你不理解它,你仍然可以使用上面的class_eval习语。
在你的具体情况下。
module B def self.included(base) base.const_set("CONST", base.find) end end class A def self.find "AAA" end include B end puts A::CONST
尽管它有效,但它有点乱。 您确定不能以不同的方式实现目标吗?
module B def self.included(base) class << base CONST = self.find end end end class A class << self def self.find "AAA" end end include B end
那么编译错误是固定的,请试试。