2014-06-10 40 views
1

我有兩個模塊,FooBar。每個人都有所謂Errors一個命名空間的模塊包含錯誤的類像這樣:紅寶石 - 包括兩個模塊,都有一個子模塊同名

module Foo 
    module Errors 
    class FooError < StandardError 
     def initialize 
     super "I'm a FooError" 
     end 
    end 
    end 
end 

module Bar 
    module Errors 
    class BarError < StandardError 
     def initialize 
     super "I'm a BarError" 
     end 
    end 
    end 
end 

我想include在我的課,這些模塊被稱爲Baz雙方並能夠訪問這兩個Errors模塊。像這樣:

class Baz 
    include Foo 
    include Bar 

    p Errors::FooError.new 
    p Errors::BarError.new 
end 

紅寶石拋出一個錯誤uninitialized constant Bar::Errors::FooError當試圖實例化FooError但不是BarError

我能正確理解Bar::Errors模塊是否覆蓋了Foo:Errors模塊?如何防止發生/完成能夠引用Baz中的兩種類型的錯誤?

謝謝!

+0

您在任何給定的時間只能使用一個名稱空間。你爲什麼故意在兩個有衝突的事情上調用include?最好避免這種情況,只要用長的正式名稱來引用它們。 – tadman

+0

我猜'Foo'和'Bar'通常會有比它們更多的衝突模塊。 – Max

+0

只需搭上@tadman的答案,如果你真的需要這樣設置,你需要更明確地給他們打電話。像:'p Foo ::錯誤:: BarError.new' – Anthony

回答

4

您可以隨時重新命名模塊,不會發生衝突:

Foo::FooErrors = Foo::Errors 
Bar::BarErrors = Bar::Errors 

或者你可以跳過沖突的模塊,直接進入包括你想要的錯誤類:

class Baz 
    include Foo::Errors 
    include Bar::Errors 
end 

還是不要打擾包括任何東西,並使用全名:

p Foo::Errors::FooError.new 
p Bar::Errors::BarError.new 

在我看來,include常被用作避免輸入模塊名稱的便捷方法。這種用法並不是非常必要,可以引入錯誤(如您所見)或含糊不清。有一些東西,你可以只有完成使用include(如添加模塊實例方法),但我看到大多數用途不落在該陣營。

+0

謝謝@Max。我使用include來使'Foo'和'Bar'中定義的方法可用於'Baz'(然後用於類似於'Baz'的其他一些'主題')。看起來像重命名它們,就像你在第一個例子中顯示的是最簡單的解決方案。 – user1032752

+0

這當然是一種方法,但是在另一個名字空間中定義常量是有點尷尬的。如果你把它變成一種習慣,這種相互依賴會造成很大的破壞。你的第二和第三種方法好得多。 – tadman