Can one YAML object refer to another?

后端 未结 2 1022
面向向阳花
面向向阳花 2020-12-18 05:18

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          


        
相关标签:
2条回答
  • 2020-12-18 05:51

    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?

    0 讨论(0)
  • 2020-12-18 05:55

    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!"
    }
    
    0 讨论(0)
提交回复
热议问题