一个YAML对象可以引用另一个吗?

时间:2010-06-29 14:06:39

标签: ruby yaml

我想让一个yaml对象引用另一个,就像这样:

intro: "Hello, dear user."

registration: $intro Thanks for registering!

new_message: $intro You have a new message!

以上语法只是它可能如何工作的一个例子(它也是this cpan module的工作方式。)

我正在使用标准的ruby yaml解析器。

这可能吗?

2 个答案:

答案 0 :(得分:7)

某些yaml对象确实引用其他对象:

irb> require 'yaml'
#=> true
irb> str = "hello"
#=> "hello"
irb> hash = { :a => str, :b => str }
#=> {:a=>"hello", :b=>"hello"}
irb> puts YAML.dump(hash)
---
:a: hello
:b: hello
#=> nil
irb> puts YAML.dump([str,str])
---
- hello
- hello
#=> nil
irb> puts YAML.dump([hash,hash])
---
- &id001
  :a: hello
  :b: hello
- *id001
#=> nil

请注意,它并不总是重复使用对象(字符串只是重复)但有时会(哈希定义一次并通过引用重用)。

YAML不支持字符串插值 - 这是你似乎想要做的 - 但没有理由你不能更详细地编码它:

intro: Hello, dear user
registration: 
- "%s Thanks for registering!"
- intro
new_message: 
- "%s You have a new message!"
- intro

然后你可以在加载YAML后插入它:

strings = YAML::load(yaml_str)
interpolated = {}
strings.each do |key,val|
  if val.kind_of? Array
    fmt, *args = *val
    val = fmt % args.map { |arg| strings[arg] }
  end
  interpolated[key] = val
end

这将产生以下interpolated

{
  "intro"=>"Hello, dear user", 
  "registration"=>"Hello, dear user Thanks for registering!", 
  "new_message"=>"Hello, dear user You have a new message!"
}

答案 1 :(得分:2)

与其尝试在yaml中使用隐式引用,为什么不使用替换字符串(如上所示,你需要引号)并在解析时显式替换它们的内容?