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

发布于 2024-09-07 07:30:15 字数 389 浏览 4 评论 0原文

我想让一个 yaml 对象引用另一个,如下所示:

intro: "Hello, dear user."

registration: $intro Thanks for registering!

new_message: $intro You have a new message!

上面的语法只是它如何工作的一个示例(这也是它在 此 cpan 模块。)

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

这可能吗?

I'd like to have one yaml object refer to another, like so:

intro: "Hello, dear user."

registration: $intro Thanks for registering!

new_message: $intro You have a new message!

The above syntax is just an example of how it might work (it's also how it seems to work in this cpan module.)

I'm using the standard ruby yaml parser.

Is this possible?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

上课铃就是安魂曲 2024-09-14 07:30:15

一些 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

这将产生以下为插值

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

Some yaml objects do refer to the others:

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

Note that it doesn't always reuse objects (the string is just repeated) but it does sometimes (the hash is defined once and reused by reference).

YAML doesn't support string interpolation - which is what you seem to be trying to do - but there's no reason you couldn't encode it a bit more verbosely:

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

Then you can interpolate it after you load the 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

And this will yield the following for interpolated:

{
  "intro"=>"Hello, dear user", 
  "registration"=>"Hello, dear user Thanks for registering!", 
  "new_message"=>"Hello, dear user You have a new message!"
}
子栖 2024-09-14 07:30:15

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

Rather than trying to use implicit references in your yaml, why don't you use substitution strings (like you show above, you need quotes though) and explicitly substitute the contents of them at parse time?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文