1.4.1.14. fejezet, YAML
A Yet Another Markup Language mint a neve is mutatja egy másik jelölő nyelv, ami teljesen eltér pl. az XML-től. Általánosságba véve szóközök, kettőspontok és kötőjelek az elválasztásra, új objektumra, objektum tulajdonságra használt jelölések. Alkalmas string, számsor, tömb, hash tábla strukturális átalakítására. Mielőtt használatba vennénk, szükség van a yaml modulra.
require 'yaml' puts( "hello world".to_yaml ) puts( 123.to_yaml ) puts( ["a1", "a2" ].to_yaml ) puts( {:h1 => 1, :h2 => 2}.to_yaml )
Eredmények:
--- hello world --- 123 --- - a1 - a2
Most nézzük meg ugyanezt tömbre és objektumra:
require 'yaml' class CD def initialize( anArtist, aName, theNumTracks ) @artist = anArtist @name = aName @numtracks = theNumTracks end end arr1 = [["The Groovesters", "Groovy Tunes", 12 ], [ "Dolly Parton", "Greatest Hits", 38 ] ] arr2 = [ CD.new("The Beasts", "Beastly Tunes", 22), CD.new("The Strolling Bones", "Songs For Senior Citizens", 38) ] y( arr1 ) y( arr2 )
Eredmények:
--- - - The Groovesters - Groovy Tunes - 12 - - Dolly Parton - Greatest Hits - 38 --- - !ruby/object:CD artist: The Beasts name: Beastly Tunes numtracks: 22 - !ruby/object:CD artist: The Strolling Bones name: Songs For Senior Citizens numtracks: 38
YAML adatok megnése
A YAML modul dump metódusával menthetjük az adatokat:
f = File.open( 'friends.yml', 'w' ) YAML.dump( ["fred", "bert", "mary"], f ) f.close
Vagy így
File.open( 'morefriends.yml', 'w' ){ |friendsfile| YAML.dump( ["sally", "agnes", "john" ], friendsfile ) }
Ha ezt a blokk megoldást használjuk, a fájlt automatikusan megnyitja és lezárja a dump.
Visszatölteni egy tömböt a File modulon keresztül így tudjuk:
File.open( 'morefriends.yml' ){ |f| $arr= YAML.load(f) }
Ha szeretnénk saját szerializálást egy osztálynak, írjuk felül a to_yaml_properties-t
require 'yaml' class Yclass def initialize(aNum, aStr, anArray) @num = aNum @str = aStr @arr = anArray end def to_yaml_properties ["@num", "@arr"] end end ob = Yclass.new( 100, "fred", [1,2,3] ) p( ob ) yaml_ob = YAML.dump( ob ) puts( yaml_ob ) ob2 = YAML.load( yaml_ob ) p( ob2 )
#<Yclass:0x9be42dc @num=100, @str="fred", @arr=[1, 2, 3]> --- !ruby/object:Yclass num: 100 arr: - 1 - 2 - 3 #<Yclass:0x9bdee7c @num=100, @arr=[1, 2, 3]>
Több objektumot is szerializálhatunk. Például az első mintaprogramnál a tömböket így írhatjuk ki:
File.open( 'multidoc.yml', 'w' ){ |f| YAML.dump( arr1, f ) YAML.dump( arr2, f ) }
Visszatölteni pedig a YAML.load_documents metódussal lehet:
File.open( 'multidoc.yml' ) {|f| YAML.load_documents( f ) { |doc| $new_arr << doc } }
YAML adatbázis
Készítsünk egy egyszerű CD adatbázist. Legyen egy név, egy szerző, egy zenék száma tulajdonsága, és legyen két leszármazottja. Egy PopCD, ami a stílust írja le, mint pl.: rock, country tulajdonságában, és legyen egy ClassicCD, ami a karmester és a szerző tulajdonságát rögzíti.
require 'yaml' #cd objektumok tömbje $cd_arr = Array.new # file név mentésre és visszatöltésre $fn = 'cd_db.yml' # generikus(szülő) CD osztály class CD def initialize( arr ) @name = arr[0] @artist = arr[1] @numtracks = arr[2] end def getdetails return[@name, @artist, @numtracks] end end # PopCD egy leszármazott osztálya a CD-nek class PopCD < CD def initialize( arr ) super( arr ) @genre = arr[3] end def getdetails return( super << @genre ) end end class ClassicalCD < CD def initialize( arr ) super( arr ) @conductor = arr[3] @composer = arr[4] end def getdetails return( super << @conductor << @composer ) end end # Ez néhány metódus a felhasználótól kéri be az adatokat def otherCD print( "Enter CD name: " ) cd_name = gets().chomp() print( "Enter artist's name: " ) a_name = gets().chomp() print( "Enter number of tracks: " ) num_tracks = gets().chomp().to_i return [cd_name, a_name, num_tracks ] end def classicCD cdInfo = otherCD print( "Enter conductor's name: " ) con_name= gets().chomp() print( "Enter composer's name: " ) comp_name = gets().chomp() cdInfo << con_name << comp_name return cdInfo end def popCD cdInfo = otherCD print( "Enter genre of music: " ) genre = gets().chomp() cdInfo << genre return cdInfo end # A $cd_arr tömbhöz ad egy CD objekumot def addCD( aCD ) $cd_arr << aCD end # Adatokat ment YAML formában def saveDB File.open( $fn, 'w' ) { |f| f.write($cd_arr.to_yaml) } end # visszatölti az adatokat a lemezről és újra létrehozza # a cd objektumokat, és az adatok alapján a $cd_arr tömböt def loadDB input_data = File.read( $fn ) $cd_arr = YAML::load( input_data ) end # A tömbből kiírja az adatokat a képernyőre olvasható # (YAML) formában def showData puts( $cd_arr.to_yaml ) end # A program kezdete if File.exist?( $fn ) then loadDB showData else puts( "The file #{$fn} cannot be found.") end # 'main' loop ans = '' until ans == 'q' do puts( "Create (P)op CD (C)lassical CD, (O)ther CD - (S)ave or (Q)uit?" ) print( "> " ) ans = gets[0].chr().downcase() case ans when 'p' then addCD( PopCD.new( popCD() ) ) when 'c' then addCD( ClassicalCD.new( classicCD() ) ) when 'o' then addCD( CD.new( otherCD() ) ) when 's' then saveDB end showData end
Két CD rögzítése után az eredmény:
--- - !ruby/object:PopCD artist: Alpaca genre: rumba name: ACD numtracks: 15 - !ruby/object:CD artist: Stone Huge name: Salsa in the jungle numtracks: 14
Mindegyik dokumentum három kötőjellel kezdődik. Ezután egy-egy kötőjel lista elemenként. A YAML kettőspontokkal elválasztva a tulajdonságokat, mint egy hash tábla, kulcs-érték párokat tárol.
Az egymásba ágyazott tömbökre mintapélda:
require 'yaml' arr = [1,[2,3,[4,5,6,[7,8,9,10],"end3"],"end2"],"end1"] y( arr)
--- - 1 - - 2 - 3 - - 4 - 5 - 6 - - 7 - 8 - 9 - 10 - end3 - end2 - end1
JSON adatkezelés
Még egy szöveges tárolási formára felhívom a figyelmet: ez a JSON.
require 'json' class Mclass def initialize(aNum, aStr, anArray) @num = aNum @str = aStr @arr = anArray end def to_json(*a) { 'json_class' => self.class.name, 'data' => [ @num, @str, @arr ] }.to_json(*a) end def self.json_create(o) new(*o['data']) end end ob = Mclass.new( 100, "fred", [1,2,3] ) p( ob ) json_data = JSON.generate(ob) p( json_data ) ob2 = JSON.parse(json_data) p(ob2)
Eredmények:
#<Mclass:0x9831c5c @num=100, @str="fred", @arr=[1, 2, 3]> "{\"json_class\":\"Mclass\",\"data\":[100,[1,2,3],\"fred\"]}" #<Mclass:0x98317e8 @num=100, @str="fred", @arr=[1, 2, 3]>
Egy kis odafigyelést igényel a to_json metódusban a data összeállítása. Ugyan abba a sorrendbe kell lennie, mint a definiálás sorrendje, különben összekeverednek a visszatöltött tulajdonságok.
- A hozzászóláshoz be kell jelentkezni