2009-12-13 79 views
12

我有一个类定义了一个常量。然后我定义了一个类方法来访问那个类的常量。这工作正常。一个例子:(在Ruby中)允许混合类方法访问类常量

#! /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 

红宝石解释方法从模块请求的常数,而不是该类:

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

那么,你有什么魔术技巧让同伴们不得不让方法访问类常量?非常感谢。

回答

14

这似乎工作:

#! /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 

HTH

+0

那么,这清除了事情。我还没有体验::语法:)。 – jameshfisher 2009-12-13 21:14:31

+0

现在不要停止阅读。请阅读下面的约翰内斯回应。 – Sebastian 2014-04-10 07:22:12

9

的问题是,如果你只写Const它是在模块创建时间进行评估。您必须像这样使用Module#const_getconst_get(:Const)。这是在运行时执行该方法时评估的。所以这发生在你的课堂上,而不是你的课堂上。

+0

谢谢!那是我寻找的那种方法,没有成功。 – jameshfisher 2009-12-13 21:15:23

12

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

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

红宝石具有extend关键字,有效地增加了模块接口的一类,例如

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

你仍然需要确保您使用引用或self::Constconst_get权不变,但extend <module>是更好的办法,以这些方法添加到类。

+0

又一个有用的评论。我从提出一个问题中学到了三件事。 – jameshfisher 2009-12-13 21:41:58