Может ли один объект YAML ссылаться на другой?
Я хотел бы, чтобы один объект yaml ссылался на другой, например:
intro: "Hello, dear user."
registration: $intro Thanks for registering!
new_message: $intro You have a new message!
Приведенный выше синтаксис является лишь примером того, как он может работать (это также, как он, кажется, работает в этом модуле cpan.)
Я использую стандартный ruby yaml parser.
Это возможно?
2 ответа
Некоторые объекты 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!"
}
Вместо того, чтобы пытаться использовать неявные ссылки в вашем yaml, почему бы вам не использовать строки подстановки (как показано выше, вам нужны кавычки) и явно подставлять их содержимое во время разбора?