代码之家  ›  专栏  ›  技术社区  ›  John Bachir

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

  •  5
  • John Bachir  · 技术社区  · 16 年前

    我想让一个yaml对象引用另一个,比如:

    intro: "Hello, dear user."
    
    registration: $intro Thanks for registering!
    
    new_message: $intro You have a new message!
    

    上面的语法只是它如何工作的一个例子(它也是如何工作的 this cpan module )

    我使用的是标准的RubyYaml解析器。

    这有可能吗?

    2 回复  |  直到 8 年前
        1
  •  7
  •   rampion    16 年前

    一些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!"
    }
    
        2
  •  2
  •   Jason S    16 年前

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