我读过的文档告诉我使用 Module.method 来访问模块中的方法。但是,我也可以使用 Module::method。这是语法糖,还是我搞糊涂了?
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 中的 Ruby 中经常看到这个图书馆,它有(例如)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])
……但它看起来不太好。
关于ruby - 使用::访问模块方法:,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9314941/