我正在处理许多预先存在的文件、类和模块,并尝试为框架的不同组件提供更好的命名空间。我一直使用模块作为命名空间的方式,主要是因为这似乎是标准约定(并且能够“包含”框架的不同部分可能很有用)。
问题在于,全局命名空间下有大量本应存在于模块下的类。例如,假设有一个类简单定义为:
class FirstClass
def meth
puts "HELLO"
end
end
但现在我想在模块中包含此类:
使用双冒号:
module Foo; end
class Foo::FirstClass
def meth
puts 'HELLO'
end
end
使用模块块:
module Foo
class FirstClass
def meth
puts 'HELLO'
end
end
使用双冒号更简洁,也更容易实现,因为我正在更改许多类定义。这两种方式都有效,我thought它们实际上是同一件事,但显然它们不是。与模块块相比,双冒号方法似乎会在每个类中产生不同的命名空间。例如,“Foo”下面有两个类:
使用模块块:
module Foo
class FirstClass
def meth
puts 'HELLO'
end
end
class SecondClass
def meth
FirstClass.new.meth
end
end
end
Foo::SecondClass.new.meth
使用双冒号:
module Foo; end
class Foo::FirstClass
def meth
puts 'HELLO'
end
end
class Foo::SecondClass
def meth
FirstClass.new.meth
end
end
Foo::SecondClass.new.meth
该代码在使用模块块时有效,但不适用于双冒号。使用双冒号时,会引发 NameError,因为它解决了FirstClass
as Foo::SecondClass::FirstClass
(代替Foo::FirstClass
),这是不存在的。
这可以通过包含来轻松解决Foo
in SecondClass
,但是为什么默认情况下不这样做呢?
注意:我使用的是 Ruby 2.1.5,我知道它已经过时了,但我在 repl.it 上使用 ruby 2.5.5p157 得到了相同的结果:https://repl.it/@joep2/Colon-vs-Block-Namespacing https://repl.it/@joep2/Colon-vs-Block-Namespacing