Lan*_*ard 6 ruby tree hash computer-science construct
我想创建一个"哈希"类,它在哈希和树之间起作用.它只是用于存储可以具有上下文的全局值.
这是我如何使用它:
Config.get("root.parent.child_b") #=> "value"
Run Code Online (Sandbox Code Playgroud)
以下是该类的外观:
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
Run Code Online (Sandbox Code Playgroud)
在Hash和Tree(不是计算机科学专业)之间有某种名称吗?基本上是树的类似哈希的接口.
像这样输出的东西:
t = TreeHash.new
t.set("root.parent.child_a", "value")
t.set("root.parent.child_b", "another value")
Run Code Online (Sandbox Code Playgroud)
所需的输出格式:
t.get("root.parent.child_a") #=> "value"
t.get("root") #=> {"parent" => {"child_a" => "value", "child_b" => "another value"}}
Run Code Online (Sandbox Code Playgroud)
而不是这个:
t.get("root") #=> nil
Run Code Online (Sandbox Code Playgroud)
或者这个(通过调用得到的价值{}.value
)
t.get("root") #=> {"parent" => {"child_a" => {}, "child_b" => {}}}
Run Code Online (Sandbox Code Playgroud)
您可以在任何时间实施一个:
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
Run Code Online (Sandbox Code Playgroud)
您可以通过将不需要的Hash
方法设置为私有方法来改进实现,但它已经按照您希望的方式工作.数据存储在哈希中,因此您可以轻松将其转换为yaml.
为了满足进一步的期望(并且,to_yaml
默认情况下正确转换),您应该使用修改版本:
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
Run Code Online (Sandbox Code Playgroud)
此版本是轻微的权衡,因为您无法在非叶节点中存储值.