访问模块方法::
问题描述:
我读过的文档告诉我使用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.
答
恒定分辨率总是要求您使用::
。
方法调用通常是一个句点(.
),但::
也是合法的。这不仅是真正的所谓的模块方法,但对于调用任何对象的任何方法:
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])
......但看起来不太好。
答
该::
被称为scope resolution operator
,它是用来找出在什么scope
下method, 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了解更多。
你不会感到困惑:两者都是合法的。为什么在下面看到我的扩展答案。 – Phrogz 2012-02-16 17:11:23