Yaml und Ruby


Sie sind hier: RubyYaml


Mit dem Paket yaml.rb ist es sehr einfach Konfigurationen o.ä. zu pflegen und in Ruby zu verwenden. Die Analyse übernimmt die Klasse YAML

Näheres zu dem Format unter http://yaml.org oder http://yaml4r.sourceforge.net/

Beispiele

Die folgenden Beispiele sind eigenständig laufende kleine Testprogramme, die jeweils zum Download bereitstehen.

Jedes Beispiel besteht aus:

  1. Das Beispielprogramm: Mit YAML.load wird der übergebene String (oder wahlweise ein IO-Objekt) analysiert und Ergebnisse ausgegeben.
  2. Verwendete Testdaten
  3. Das Ergebnis:
    1. Ausgabe des Ergebnisses via #inspect
    2. Ausgabe der einzelnen Daten des Ergebnisses .
    3. YAML-Rückübersetzung: Das Ergebnis wird erneut in eine YAML-Strukur rücküberführt.
  4. Anmerkungen

Eine einfache Liste

Das Beispielprogramm:

require 'yaml' 
props = YAML.load( DATA )

puts props.inspect
props.each{|value| puts value.inspect }

puts "\n===Yaml-Rückübersetzung:==="
puts props.to_yaml

Verwendete Testdaten:

- "Kommentar" 
- 1
- !str 1
- 1.1
- !ruby/symbol symbol
- !ruby/sym another symbol

Das Ergebnis:

["Kommentar", 1, "1", 1.1, :symbol, :"another symbol"]
"Kommentar"
1
"1"
1.1
:symbol
:"another symbol"

===Yaml-Rückübersetzung:===
--- 
- Kommentar
- 1
- "1"
- 1.1
- :symbol
- :"another symbol"

Beispielprogramm zum selbst testen

Anmerkungen:

Ein einfacher Hash

Das Beispielprogramm:

require 'yaml' 
props = YAML.load( DATA )

puts props.inspect
props.each{|key, value| puts "#{key}: #{value}" }

puts "\n===Yaml-Rückübersetzung:==="
puts props.to_yaml

Verwendete Testdaten:

key1: value1 
key2: value2 

Das Ergebnis:

{"key1"=>"value1", "key2"=>"value2"}
key1: value1
key2: value2

===Yaml-Rückübersetzung:===
--- 
key1: value1
key2: value2

Beispielprogramm zum selbst testen

Ein Hash mit doppelt verwendeten Key

In der Regel ist das auf einen Eingabefehler zurückzuführen.

Das Beispielprogramm:

require 'yaml' 
props = YAML.load( DATA )

puts props.inspect
props.each{|key, value| puts "#{key}: #{value}" }

puts "\n===Yaml-Rückübersetzung:==="
puts props.to_yaml

Verwendete Testdaten:

key: value1 
key: value2 

Das Ergebnis:

{"key"=>"value2"}
key: value2

===Yaml-Rückübersetzung:===
--- 
key: value2

Beispielprogramm zum selbst testen

Anmerkung:

Hash mit Liste

Das Beispielprogramm:

require 'yaml' 

props = YAML.load( DATA )
puts props.inspect
props.each{|key, value| puts "#{key}: #{value.inspect}" }

puts "\n===Yaml-Rückübersetzung:==="
puts props.to_yaml

Verwendete Testdaten:

value: value1 
list1:
- "Kommentar" 
- 1
- 1.1
list2: [1, 2, 3, 4, 5]

Das Ergebnis:

{"list1"=>["Kommentar", 1, 1.1], "list2"=>[1, 2, 3, 4, 5], "value"=>"value1"}
list1: ["Kommentar", 1, 1.1]
list2: [1, 2, 3, 4, 5]
value: "value1"

===Yaml-Rückübersetzung:===
--- 
list1: 
- Kommentar
- 1
- 1.1
list2: 
- 1
- 2
- 3
- 4
- 5
value: value1

Beispielprogramm zum selbst testen

String in Yaml

Das Beispielprogramm:

require 'yaml' 
props = YAML.load( DATA )

puts props.inspect
props.each{|value| puts value.inspect }

puts "\n===Yaml-Rückübersetzung:==="
puts props.to_yaml

Verwendete Testdaten:

- Kommentar 1
- "Kommentar 2" 
- 'Kommentar 3' 
- "Zeile eins
Zeile 2"

Das Ergebnis:

["Kommentar 1", "Kommentar 2", "Kommentar 3", "Zeile eins Zeile 2"]
"Kommentar 1"
"Kommentar 2"
"Kommentar 3"
"Zeile eins Zeile 2"

===Yaml-Rückübersetzung:===
--- 
- Kommentar 1
- Kommentar 2
- Kommentar 3
- Zeile eins Zeile 2

Beispielprogramm zum selbst testen

Das Beispielprogramm:

require 'yaml' 
props = YAML.load( DATA )

puts props.inspect
props.each{|value| puts value.inspect }

puts "\n===Yaml-Rückübersetzung:==="
puts props.to_yaml

Verwendete Testdaten:

1: >
 Zeile eins
 Zeile zwei
2: >
 Zwei
3: >
 Zeile eins
 Zeile zwei

 Neuer Absatz

Das Ergebnis:

{1=>"Zeile eins Zeile zwei\n", 2=>"Zwei\n", 3=>"Zeile eins Zeile zwei\nNeuer Absatz"}
[1, "Zeile eins Zeile zwei\n"]
[2, "Zwei\n"]
[3, "Zeile eins Zeile zwei\nNeuer Absatz"]

===Yaml-Rückübersetzung:===
--- 
1: |
  Zeile eins Zeile zwei

2: |
  Zwei

3: |-
  Zeile eins Zeile zwei
  Neuer Absatz

Beispielprogramm zum selbst testen

Hat man längere Texte, kann man mit > mehrzeilige Strings definieren. Einmalige Zeilenumbrüche werden dabei ignoriert.

Das Beispielprogramm:

require 'yaml' 
props = YAML.load( DATA )

puts props.inspect
props.each{|value| puts value.inspect }

puts "\n===Yaml-Rückübersetzung:==="
puts props.to_yaml

Verwendete Testdaten:

1: |
 Zeile eins
 Zeile zwei
2: |
 Zwei
3: |
 Zeile eins
 Zeile zwei

 Neuer Absatz

Das Ergebnis:

{1=>"Zeile eins\nZeile zwei\n", 2=>"Zwei\n", 3=>"Zeile eins\nZeile zwei\n\nNeuer Absatz\n"}
[1, "Zeile eins\nZeile zwei\n"]
[2, "Zwei\n"]
[3, "Zeile eins\nZeile zwei\n\nNeuer Absatz\n"]

===Yaml-Rückübersetzung:===
--- 
1: |
  Zeile eins
  Zeile zwei

2: |
  Zwei

3: |
  Zeile eins
  Zeile zwei
  
  Neuer Absatz

Beispielprogramm zum selbst testen

Sollen Zeilenumbrüche erhalten bleiben können Strings mit | definiert werden.

to_yaml: YAML-Code erzeugen

Hat man Listen und Hashes (oder auch andere Objekte) kann mit der Methode to_yaml YAML-Code erzeugt werden.

Der Methode to_yaml können in einem Hash Optionen mitgegeben werden.

Aus der Doku:
Indent: The default indentation to use when emitting (defaults to 2)
Separator: The default separator to use between documents (defaults to '---')
SortKeys: Sort Hash keys when emitting? (defaults to false)
UseHeader: Display the YAML header when emitting? (defaults to false)
UseVersion: Display the YAML version when emitting? (defaults to false)
AnchorFormat: A formatting string for anchor IDs when emitting (defaults to 'id%03d')
ExplicitTypes: Use explicit types when emitting? (defaults to false)
BestWidth: The character width to use when folding text (defaults to 80)
UseFold: Force folding of text when emitting? (defaults to false)
UseBlock: Force all text to be literal when emitting? (defaults to false)
Encoding: Unicode format to encode with (defaults to :Utf8; requires Iconv)

Die Optionen scheinen zumindest unter 1.8.4. nicht unterstützt zu sein.

Das Beispielprogramm:

require 'yaml'

list = [ 1,2,3, [ 9, 8] ]
puts list.to_yaml()
puts list.to_yaml( :Indent	=>	4 )
puts list.to_yaml( :UseHeader	=>	true )

hash = { 'eins' => 1, 'zwei' => 2, 'drei' => 3 }
puts hash.to_yaml( )
puts hash.to_yaml( :SortKeys	=>	true )

Verwendete Testdaten:

Das Ergebnis:

--- 
- 1
- 2
- 3
- - 9
  - 8
--- 
- 1
- 2
- 3
- - 9
  - 8
--- 
- 1
- 2
- 3
- - 9
  - 8
--- 
zwei: 2
eins: 1
drei: 3
--- 
zwei: 2
eins: 1
drei: 3

Beispielprogramm zum selbst testen

Siehe auch:

Das Beispielprogramm:

require 'yaml'

hash = { 'eins' => 1, 'zwei' => 2, 'drei' => 3 }
puts hash.to_yaml( )

class Hash 
# Unfortenatly the option
#		:SortKeys	=>	true
#isn't supported.
#
#Source: http://groups.google.de/group/comp.lang.ruby/browse_thread/thread/813cd7086e37f004/3057ffb1ebd96a8d
   def to_yaml( opts = {} ) 
     YAML::quick_emit( object_id, opts ) do |out| 
       out.map( taguri, to_yaml_style ) do |map| 
#        if opts[:SortKeys] ## fails in nesting, so let's just always sort 
           sorted_keys = keys 
           sorted_keys = begin 
             sorted_keys.sort 
           rescue 
             sorted_keys.sort_by {|k| k.to_s} rescue sorted_keys 
           end 

           sorted_keys.each do |k| 
             map.add( k, fetch(k) ) 
           end 
#        else 
#          each do |k, v| 
#            map.add( k, v ) 
#          end 
#        end 
       end 
     end 
   end 
end

puts hash.to_yaml( )

Verwendete Testdaten:

Das Ergebnis:

--- 
zwei: 2
eins: 1
drei: 3
--- 
drei: 3
eins: 1
zwei: 2

Beispielprogramm zum selbst testen

Hinweise:

Weblinks

rdoc-doku zu YAML.rb: