2016-11-25 43 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

相关问题