在多层模块中定义类或者模块一般有两种做法:
1 2 3 4 5 6 7 | |
和
1 2 3 4 5 | |
直观看,后者显然要简洁一些,所以我们常常使用这种写法,不过,其实后者更灵活。
这两种写法并不是等价的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | |
执行上述代码:
1 2 | |
改为双冒号:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
再执行就会出错了
1 2 3 | |
如果你感觉奇怪,说明对ruby的语法理解的还不充分。初学者常以为module和class这两个关键字是”定义一个类/模块”,但其实它们的意思是”打开一个类/模块”(正是这一特性让ruby具备了open class的能力),而对于打开这个概念,随之而来的自然是可以访问这个类/模块上下文的各种常量。
在前一种写法中,我们实际上是在依次打开模块A、B、C,因此X可以访问这些模块中的常量,而module A::B::C这种写法只是打开了A::B::C这个模块,于是X就不能访问 A::B 这个模块的常量了。
module中的常量,通常是一些模块级的共享对象和数据,因此,为了让我们的代码能够访问这些位置,写成层次module显然比使用双冒号的代码更有灵活性。