2010-06-29 113 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]我不確定我理解'hash'中發生了什麼。 – 2010-06-29 18:47:55

+1

@John:[1]轉儲不會查看變量 - 但它確實在傳遞的對象中查找重複。 [2]在'YAML.dump([hash,hash])'中,它有一串符號散列到字符串。在對陣列的檢查中,發現這兩個哈希是指同一個對象。所以第一次打印散列時,它給出了該散列的標識符('&id001'),並且第二次,而不是再次打印整個東西,它引用了該標識符('* id001')。 – rampion 2010-06-29 20:54:04

+0

我明白了。所以這並不能讓我在任何地方重新使用yaml文件中的對象,對吧? – 2010-06-29 21:10:12

2

與其試圖在你的yaml中使用隱式引用,爲什麼不使用替換字符串(就像你上面顯示的那樣,你需要引號)並且在解析時顯式替換它們的內容?

+0

在這個意義上,我想我的問題是「標準的Ruby YAML解析器已經明確支持這個嗎?」 – 2010-06-29 14:23:51

相關問題