Problem z wczytywaniem plikow YAML

Witam

Mam problem z wczytywaniem plikow .yml. Mianowicie chodzi o to ze jak je wczytuje i wyswietlam za pomoca “inspect” to kolejnosc wczytanych danych jest inna niz w pliku z ktorego wczytywalem. Uzywam podstawowej biblioteki yaml i wczytuje za pomoca YAML::load_file(plik).
Wersja ruby-iego: ruby 1.8.7 (2009-06-12 patchlevel 174)
Wie ktos moze jak to naprawic, lub zna jakis inny sposob wczytywanie plikow yml ?

Z gory dzieki za pomoc.

pokaż plik i napisz co za wersja rubiego

Jeżeli korzystasz w yamlu z hashy i korzystasz z rubiego 1.8.x to hashe(tablice asocjacyjne) nie zapamiętują kolejności.
Jeżeli chcesz żeby zachowywały użyj ActiveSupport::OrderedHash.
Aczkolwiek nie wiem jak się zachowują przy serializacji i deserializacji do yaml.

Jeżeli korzystasz z ruby 1.9.x to nie powinieneś mieć takiego problemu.

wersja rubiego to :
ruby 1.8.7 (2009-06-12 patchlevel 174)

moje ładowanie:

config = YAML::load_file("app.yml") puts config.inspect
kawalek mojego yml-a

all: menu: main: name: Main Menu class: gySpacerMenuItem children: homepage: label: Auctions route: @homepage history: label: History route: @history how_it_works: label: Help route: @how_it_works children: how_it_works: label: Help route: @how_it_works faq: label: FAQ route: @faq edit_profile: label: My account route: @edit_profile children: overview: label: Overview route: @edit_profile requires_auth: true buy_biddies: label: Buy biddies route: @list_bid_packs requires_auth: true coupon_code: label: Enter coupon route: @coupon_code requires_auth: true
Tak wyglada to co mam.
Sprawdze jeszcze to co piszesz z ActiveSupport i zmienie wersje rubiego na 1.9.x

Cytat z dokumentacji: http://www.ruby-doc.org/ruby-1.9/index.html

Jeżeli polegasz na kolejności to posortuj klucze przed iteracją po nich

[code]hash.keys.sort

zamiast

hash.keys[/code]

A podobno chcieli to zmienić w nowszych rubich. Czy to może dokumentacja jest nieaktualna?

@suleks: A po co Ci ustalona kolejność danych? Na pewno tego potrzebujesz? Może użyj tam tablicy?

Niestety potrzebuje ustalonej kolejnosci, poniewaz jest to kawalek pliku konfiguracyjnego z elementami menu, dla ktorych kolejnosc w pliku odpowiada kolejnosci na stronie. Nie moge tez posortowac kluczy, bo to tez wplynie na ich kolejnosc.
A znacie moze jakies inne rozwiazanie, zeby zmienic zawartosc odpowienich pol pliko yaml-a ?? Dosyc mocno tego potrzebuje, a nie chcialbym juz rezygnowac z rubiego ;/

[quote=Arsen7]A podobno chcieli to zmienić w nowszych rubich. Czy to może dokumentacja jest nieaktualna?

@suleks: A po co Ci ustalona kolejność danych? Na pewno tego potrzebujesz? Może użyj tam tablicy?[/quote]
z tego co czytałem w ruby1.9 hash trzyma kolejność wprowadzania

proponowałbym zainteresować się strukturami drzewiastymi. Zniknie Twój problem kolejności.

Nie pamiętam dokładnie nazwy bardzo skutecznej mtody: (byłbym wdzięczny gdyby mi ktoś przypomniał), polega ona na opisaniu lewych i prawych stron drzewa

przykład

root:
rgt: 24
lft: 1
alfa:
rgt: 9
lft: 2
beta:
rgt: 19
lft: 10
delta:
rgt: 23
lft: 20
A:
rgt: 4
lft: 3
B:
rgt: 6
lft: 5
C:
rgt: 8
lft: 7
ujemny:
rgt: 12
lft: 11
dodatni
rgt: 18
lft: 13
zerowy:
rgt: 15
lft: 14
niezerowy
rgt: 17
lft: 16

z prostego obliczenia wiemy że nasz root ma 11 potomków ([24 - 1] -1)/2 => wzór ([rgt-lft]-1)/2

mamy w nim poddrzewa alfa, beta, delta i odpowiednio wiemy odrazu ile zawierają potomków (ten sam wzór) => odpowiednio 3, 4, 1 z czego poddrzewo beta zawiera mniejsze poddrzewo - “dodatni” z dwoma potomkami “zerowy” i “niezerowy”

jeżeli pragniemy wybrać całe drzewo bierzemy wszystkie właściwości lft elementów mniejsze od rgt root-a i właściwości rgt elementów większe od lft root-a [select * from tree WHERE lft < 24 AND rgt > 1 (z ASC dla lft)]

dlatego o niebo lepszym miejscem na przechowanie czegoś takiego jest baza danych. Oczywiście plik też zda egzamin ale mechanizm jest chyba trudniejszy w implementacji.

taka struktura jest prosta i szybka w czytaniu, również poddrzew , jednak trudniejsza i woleniejsza w utrzymaniu/edycji… z uwagi na konieczność przekształcenia całego drzewa (lub prawie całego) przy dodawaniu i usuwaniu elementów

edit: znalazłem :slight_smile:

pozdrawiam
Piotr Mąsior

Zagnieżdżony zbiór. Frazy do gugla: nested set, acts_as_nested_set, awesome_nested_set

Nie wiem chłopaki. Nie chce mi się grzebać w dokumentacji i sprawdzać czy w ruby 1.9. hash zachowuje kolejność czy nie, ale przy odrobinie zapału można to samemu sprawdzić.

Z mojego doświadczenia wynika, że owszem zachowuje.

https://rails.lighthouseapp.com/projects/8994/tickets/4875-orderedhashinvert-returns-an-unordered-hash
tutuaj jest link do dyskusji o ActiveSupport::OrderedHash
Też wychodzi na to, że zachowuje kolejność.

Hash nigdy nie miał zachowywać kolejności. W Railsach 2.x istniała klasa ActiveSupport::OrderedHash (o której nie było ani słowa w dokumentacji) i dobrze spełniała rolę hasha z kolejnością. Coś podobnego miało być zaimplementowane w Ruby 1.9, ale tutaj moja wiedza jest mocno przestarzała (interesowałem się tematem dwa lata temu).

http://github.com/rails/rails/blob/3-0-stable/activesupport/lib/active_support/ordered_hash.rb#L24 - tutaj też wynika, że hash jest z kolejnością w 1.9

Hash nigdy nie miał zachowywać kolejności

W ruby 1.8. Tak jak Sławosz słusznie zauważył w kodzie railsów, dla 1.9 hash zawsze zachowuje kolejność.

Powracając do oryginalnego problemu można elementy hasha opakować w tablicę (jakkolwiek to brzmi ;)):

[code]-
first: pierwszy

halo: drugi[/code]
Daje [{“first”=>“pierwszy”}, {“halo”=>“drugi”}].

Tylko, że wtedy iterowanie dostaje jeden poziom więcej…

Są dwa wyjścia. Albo zgadywać czy hash w danej wersji rubiego i railsów zachowuje kolejność, albo przyjąć, że nie zachowuje i użyć obiektów, które potrafią kolejnością zarządzać.

Pytanie: jak w hashu zmienisz kolejność opcji menu?
Sugeruję jednak użyć tablicy. Mniej problemów.

http://radarek.jogger.pl/2008/11/30/nowosci-i-zmiany-w-ruby-1-9-1-ordered-hash/

Compared with arrays, hashes have one significant advantage: they can use any object as an index. And, as of Ruby 1.9, you’ll find something that might be surprising: Ruby remembers the order in which you add items to a hash. When you subsequently iterate over the entries, Ruby will return them in that order.
strona 91 Pragmatic.Bookshelf.Programming.Ruby.1.9