2012-02-16 188 views
7

我读过的文档告诉我使用Module.method来访问模块中的方法。但是,我也可以使用Module ::方法。这是句法糖,还是我困惑?访问模块方法::

module Cat 
    FURRY_LEVEL = 4 

    def self.sound 
     %w{meow purr hiss zzzz}.sample 
    end 
end 

puts Cat.sound   # This works. 
puts Cat::sound   # This also works. Why?! 

puts Cat.FURRY_LEVEL # Expected error occurs here. 
puts Cat::FURRY_LEVEL # This works. 
+1

你不会感到困惑:两者都是合法的。为什么在下面看到我的扩展答案。 – Phrogz 2012-02-16 17:11:23

回答

9

恒定分辨率总是要求您使用::

方法调用通常是一个句点(.),但::也是合法的。这不仅是真正的所谓的模块方法,但对于调用任何对象的任何方法:

class Foo 
    def bar 
    puts "hi" 
    end 
end 

Foo.new::bar 
#=> hi 

这与其说是“语法糖”,因为它只是一种语法,比如写if的能力或case陈述与新行,then和换行符,或者只是then

它是专门允许因为Ruby允许使用相同的名称为常数的方法,有时是有道理的认为他们是同一项目:

class Foo 
    class Bar 
    attr_accessor :x 
    def initialize(x) 
     self.x = x 
    end 
    end 
    def self.Bar(size) 
    Foo::Bar.new(size) 
    end 
end 

p Foo::Bar  #=> Foo::Bar     (the class) 
p Foo::Bar(42) #=> #<Foo::Bar:0x2d54fc0 @x=42> (instance result from method call) 

您在Nokogiri看到常用的红宝石库,它有(例如)Nokogiri::XML模块以及Nokogiri.XML方法。当创建一个XML文档,很多人选择写

@doc = Nokogiri::XML(my_xml) 

你看这也是在Sequel库,在那里你可以一次:再次

class User < Sequel::Model      # Simple class inheritance 
class User < Sequel::Model(DB[:regular_users]) # Set which table to use 

,我们有一个method (Sequel.Model)命名一样一个constant (Sequel::Model)。第二行也可写成

class User < Sequel.Model(DB[:regular_users]) 

......但看起来不太好。

+2

这样的一些常见的方法是'Array','Float','Integer'和'String'。 – 2012-02-16 17:16:27

+0

@Josh很好的例子(尽管我个人从未使用这些方法:) – Phrogz 2012-02-16 17:18:01

+0

只是一个旁注:)“常量解析总是要求你使用'::'”'#const_get'呢? – farnoy 2012-02-17 21:47:34

5

::被称为scope resolution operator,它是用来找出在什么scopemethod, class or constant被定义。

在下面的例子中,我们使用::访问Base类,这是下模块ActiveRecord

ActiveRecord::Base.connection_config 
# => {:pool=>5, :timeout=>5000, :database=>"db/development.sqlite3", :adapter=>"sqlite3"} 

我们使用::访问模块中定义的常量定义

> Cat::FURRY_LEVEL 
=> 4 
> Cat.FURRY_LEVEL 
=> undefined method `FURRY_LEVEL' for Cat:Module (NoMethodError) 

.运算符用于调用模块的module method(自定义)。

摘要:尽管::.在这里做了相同的工作,但它用于不同的目的。你可以从here了解更多。