2013-06-13 106 views
0

我是Ruby新手,很抱歉,如果我的术语在这里不正确。Ruby:扩展哈希构造函数

我试图做一个哈希的子类,但我有初始化它的麻烦。我希望能够与现有的哈希值初始化它,也有一些额外的参数,例如:

x = NewHash[{:a => b}, extra_param] 

我试图做到这一点通过重写静态哈希[]操作:

class NewHash < Hash 
    def self.[](hash_values, backend = nil) 
    @backend = backend 
    super(hash_values) 
    end 
end 

这不起作用,因为[]运算符是静态的,我不能访问非静态成员变量,即@backend丢失。

有什么我可以做的吗?另一种方法是使用new,但这并不能让我接受最初的散列。

回答

1

由于[]不是哈希构造函数,这是一种工厂方法。所以,没有一种真正的干净方式可以将私人范围扩展到新的散列。

你可以做这样的事情:

class NewHash < Hash 
    def self.[](hash_values, backend = nil) 
    super(hash_values).tap do |hash| 
     hash.instance_variable_set("@backend", backend) 
    end 
    end 
end 

这需要使用instance_variable_set,这被普遍认为是臭的,但它的作品。另一种是创建公共存取:

class NewHash < Hash 
    attr_accessor :backend 
    def self.[](hash_values, backend = nil) 
    super(hash_values).tap do |hash| 
     hash.backend = backend 
    end 
    end 
end 

这当然是公开的,所以如果你想隐藏它,在smellier第一个版本可能会更好。

+0

谢谢。我认为我更喜欢第一种选择,因为它限制了对工厂方法的任何“冒险”,而不是永远不会创建具有不必要的公共变量的对象。 – Stefan