如何编写可生成嵌套哈希的Ruby DSL?
实现Ruby嵌套哈希DSL解决方案
问题描述
需要编写一个Ruby DSL模块,用于构建带嵌套键的哈希,期望使用如下语法:
Tree.new do node :building do string :name, 'Museum' node :address do string :street, 'Wallaby Way' string :country, 'USA' end end end.to_h
预期输出为:
{ "building": { "name": "Museum", "address": { "street": "Wallaby Way", "country": "USA" } } }
现有实现会得到扁平结构,无法正确处理嵌套节点,问题出在node方法没有为嵌套块创建独立的上下文,导致所有操作都修改顶层哈希。
修正后的实现
class Tree def initialize(&block) @tree = {} instance_eval(&block) if block_given? end def to_h # 将符号键转换为字符串,匹配预期输出格式 @tree.transform_keys(&:to_s) end def node(name, &block) # 为嵌套块创建新的Tree实例,让块在独立上下文执行 child_tree = Tree.new(&block) @tree[name] = child_tree.to_h end def string(name, value) @tree[name] = value end end
关键修改说明
- 独立上下文处理嵌套:在
node方法中,不再直接调用块,而是创建新的Tree实例并传入块。这样嵌套块里的string和node方法都会作用于新实例的哈希,而非顶层哈希。 - 键格式转换:
to_h方法中通过transform_keys(&:to_s)把符号键转为字符串,完全匹配预期输出的格式(如果不需要字符串键,可移除该转换)。
验证结果
运行示例代码后,将得到预期的嵌套哈希结构:
{ "building"=>{ "name"=>"Museum", "address"=>{ "street"=>"Wallaby Way", "country"=>"USA" } } }
内容的提问来源于stack exchange,提问作者jmb
相关产品推荐
相关产品推荐

