13

我有一个为它定义了常量的类。然后我定义了一个访问该类常量的类方法。这工作正常。一个例子:

#! /usr/bin/env ruby

class NonInstantiableClass
    Const = "hello, world!"
    class << self
        def shout_my_constant
            puts Const.upcase
            end
        end
    end

NonInstantiableClass.shout_my_constant

我的问题是在尝试将此类方法移出到外部模块时出现,如下所示:

#! /usr/bin/env ruby

module CommonMethods
    def shout_my_constant
        puts Const.upcase
        end
    end

class NonInstantiableClass
    Const = "hello, world!"
    class << self
        include CommonMethods
        end
    end

NonInstantiableClass.shout_my_constant

Ruby 将该方法解释为从模块而不是类请求一个常量:

line 5:in `shout_my_constant': uninitialized constant CommonMethods::Const (NameError)

那么,小伙伴们有什么妙招让方法访问类常量呢?非常感谢。

4

3 回答 3

16

这似乎有效:

#! /usr/bin/env ruby

module CommonMethods
    def shout_my_constant
        puts self::Const.upcase
    end
end

class NonInstantiableClass
    Const = "hello, world!"
    class << self
        include CommonMethods
    end
end

NonInstantiableClass.shout_my_constant

高温高压

于 2009-12-13T21:02:16.270 回答
13

可能值得注意的是,您不需要将模块包含到元类中。

class NonInstantiableClass
    Const = "hello, world!"
    class << self
        include CommonMethods
    end
end

Ruby 具有extend有效地将模块接口添加到类的关键字,例如

class NonInstantiableClass
    Const = "hello, world!"
    extend CommonMethods
end

您仍然需要确保使用self::Constor引用正确的常量const_get,但这extend <module>是将这些方法添加到类的更好方法。

于 2009-12-13T21:28:10.193 回答
9

问题是,如果您只是编写Const它,则会根据模块创建时间进行评估。您必须Module#const_get像这样使用:const_get(:Const). 这是在执行该方法时在运行时评估的。所以这发生在你的班级而不是你的模块中。

于 2009-12-13T21:07:49.173 回答