2012-02-16 268 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瞭解更多。