2010-06-29 2 views
5

Я хотел бы иметь один объект YAML обратитесь к другому, например, так:Может ли один объект YAML ссылаться на другой?

intro: "Hello, dear user." 

registration: $intro Thanks for registering! 

new_message: $intro You have a new message! 

Синтаксис выше является лишь примером того, как это могло бы работать

(это также, как это, кажется, работает в this cpan module.)

Я использую стандартный анализатор ruby ​​yaml.

Возможно ли это?

ответ

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!" 
} 
+0

Интересно. Два вопроса: [1] Так что дамп не просто возвращает строку, но ищет переменные в среде выполнения? [2] Я не уверен, что понимаю, что произошло в деле «хэш». –

+1

@John: [1] дамп не смотрит на переменные - но он ищет повторение w/в переданном объекте. [2] в 'YAML.dump ([hash, hash])', он имел массив хэшей символов для строк. При проверке массива он обнаружил, что два хэша ссылаются на один и тот же объект. Итак, в первый раз, когда он напечатал хэш, он дал идентификатор ('& id001') для этого хэша, а во второй раз вместо того, чтобы снова распечатать все это, он ссылался на этот идентификатор (' * id001'). – rampion

+0

Я вижу. Так что это действительно не дает мне нигде в моих поисках повторного использования объектов в файлах yaml, правильно? –

2

Вместо того, чтобы пытаться использовать неявные ссылки в вашем yaml, почему бы вам не использовать строки подстановки (например, вы показываете выше, вам нужны кавычки) и явно подставлять их содержимое во время разбора?

+0

В этом смысле, я полагаю, мой вопрос: «Является ли стандартный синтаксический анализатор Ruby YAML явным образом это подтверждением?» –

Смежные вопросы