我想创建一个“哈希”类,它在哈希和树之间起作用.它只是用于存储可以具有上下文的全局值.
这是我如何使用它:
Config.get("root.parent.child_b") #=> "value"
以下是该类的外观:
class Construct def get(path) # split path by "." # search tree for nodes end def set(key,value) # split path by "." # create tree node if necessary # set tree value end def tree { :root => { :parent => { :child_a => "value",:child_b => "another value" },:another_parent => { :something => { :nesting => "goes on and on" } } } } end end
在Hash和Tree(不是计算机科学专业)之间有某种名称吗?基本上是树的类似哈希的接口.
像这样输出的东西:
t = TreeHash.new t.set("root.parent.child_a","value") t.set("root.parent.child_b","another value")
所需的输出格式:
t.get("root.parent.child_a") #=> "value" t.get("root") #=> {"parent" => {"child_a" => "value","child_b" => "another value"}}
而不是这个:
t.get("root") #=> nil
或者这个(通过调用{} .value得到的价值)
t.get("root") #=> {"parent" => {"child_a" => {},"child_b" => {}}}
解决方法
您可以在任何时间实施一个:
class TreeHash < Hash attr_accessor :value def initialize block = Proc.new {|h,k| h[k] = TreeHash.new(&block)} super &block end def get(path) find_node(path).value end def set(path,value) find_node(path).value = value end private def find_node(path) path.split('.').inject(self){|h,k| h[k]} end end
您可以通过将不需要的Hash方法设置为私有方法来改进实现,但它已经按照您希望的方式工作.数据存储在哈希中,因此您可以轻松将其转换为yaml.
编辑:
为了满足进一步的期望(并且,默认情况下默认转换为toyyl),您应该使用修改版本:
class TreeHash < Hash def initialize block = Proc.new {|h,k| h[k] = TreeHash.new(&block)} super &block end def get(path) path.split('.').inject(self){|h,k| h[k]} end def set(path,value) path = path.split('.') leaf = path.pop path.inject(self){|h,k| h[k]}[leaf] = value end end
此版本是轻微的权衡,因为您无法在非叶节点中存储值.