2013-10-24 129 views
6

考慮Ruby類Foo::Bar類與模塊的Ruby命名空間?

的約定是爲「富」的命名空間是一個模塊,但它可以很容易地被類:

module Foo; class Bar; end; end 

對戰:

class Foo; class Bar; end; end 

在第二種情況下,Bar不是Foo的內部類,它只是Foo的單例中定義的另一個常量。在這兩種情況下,超類都是Object,它們只包含Kernel模塊。他們的祖先鏈是相同的。

因此,除了可以根據類使用Foo來進行的操作(如果某個類實例化,擴展/包含模塊),名稱空間的性質是否對Bar有影響?是否有令人信服的理由選擇多個名稱間隔而不是另一個?

我看到你能做的唯一奇怪的事情分別是Foo::Bar.new.extend FooFoo.new.class::Bar

我自己最常用的一類中定義的類將是一個輔助結構/類,它是指只能由類內部使用:

class Foo 
    Bar = Struct.new(:something) do 
    def digest 
     puts "eating #{something}" 
    end 
    end 
    def eat(something) 
    Bar.new(something).digest 
    end 
end 

最近,我發現這個討論在「Using Class vs Module for packaging code in Ruby」中。

+0

有趣的是,我看到有一個相關的問題中的Rails使用const_missing http://bugs.ruby-lang.org/issues/2740 – BF4

回答

5

的最直接的好處是用模塊命名空間是可以使用include導入命名空間,並使用不合格內它聲明的常量:

module Foo; class Bar; end; end 

module Elsewhere 
    include Foo 
    Bar.new 
end 
+0

好吧,我可以看到,作爲一個令人信服的論點,使用模塊*意圖*混合英寸但如果沒有打算,像大多數寶石,混合寶石的頂部命名空間容易造成與現有常量的衝突。 – BF4

+0

順便說一句,如果我沒有得到更多的答案,我會接受這個(我確實贊成它),但我希望有更完整的東西。 – BF4

+2

當然,謝謝。我能想到的唯一其他原因是「約定」和「意向澄清」,這兩者都不如此令人滿意。 Class和Module在機械上非常接近,因爲Class實際上是Module的一個子類,它實現了實例化。我曾經想過,一個實際的獨立命名空間構造可能很好,但我不確定它實際上會添加什麼行爲,所以我可以明白爲什麼它現在都使用模塊完成。 –