2016-11-25 45 views
0

考慮以下代碼:在初始化程序中使用另一個對象的構造函數?

Campus = ImmutableStruct.new(:id, :name, :timezone) do 
    def hash; id end 
    end 

    Merchant = ImmutableStruct.new(:id, :name, :campus) do 
    def hash; id end 
    end 

通知的hash方法的重複。我想用新類ImmutableStructWithId刪除這個重複項。新課改將允許2行以上將被改寫爲:

Campus = ImmutableStructWithId.new(:id, :name, :timezone) 
Merchant = ImmutableStructWithId.new(:id, :name, :campus) 

如果紅寶石的初始化工作就像工廠函數(他們不這樣做),像下面是我想要的東西:

class ImmutableStructWithId 
    def initialize(*args) 
    ImmutableStruct.new(*args) do 
     def hash; id end 
    end 
    end 
end 

我知道上面是行不通的,因爲初始化不他們創建的對象,他們只是初始化它。但如果他們做工作的工廠功能,上面是我想要做的。

在紅寶石中實現相同效果的正確方法是什麼?

+0

另外,我沒有看到任何具體構造。你只是不想重複方法定義,不是嗎? –

+0

正確。最終,我想避免重複散列定義,並只使用一個特定的類來烘焙。 – Jonah

+0

然後裝飾者/委託人。 –

回答

4

IMO這應該爲你工作:

require 'immutable-struct' 

module ImmutableStructWithId 
    def self.new(*args) 
    ImmutableStruct.new(*args) do 
     def hash; id; end 
    end 
    end 
end 

Campus = ImmutableStructWithId.new(:id, :name, :timezone) 
campus = Campus.new(id: '1', name: 'foo', timezone: 'UTC') 
#=> #<Campus:0x007f8ed581de20 @id="1", @name="foo", @timezone="UTC"> 
campus.hash 
#=> "1" 
+0

完美。不知道你可以像這樣重新定義'new'。上述內容是否僅適用於'module' - 也就是說,你有沒有在這裏使用'class'的原因? – Jonah

+0

我使用了一個模塊,因爲我知道我不想創建它的一個實例。在這種情況下,你可能想考慮另一個名字,也許'ImmutableStructWithIdFactory'? – spickermann

+0

好吧,我測試了它,它也適用於'class'。 – Jonah

相關問題