Forum: Ruby ordered hashes/ yaml?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
3d46d8c82d2167ffef81fac65ec92838?d=identicon&s=25 David Collier (d3ntaku)
on 2007-08-02 07:57
(Received via mailing list)
hi -

i understand hashes dont keep their order in ruby, so wondering what the
most elegant way to create some YAML that i want to maintain order is...

for a simple menu system, i have a YAML file currently as:

section1:
  link1: home
  link2: my page
  link3: logout

section2:
  ... etc

but after reading in thru YAML::load  this can come out as a different
order. eg the logout button first...

but to keep this as an array, it seems nasty to step thru and read
pairs/skip in twos thru the array:

section:
 { link1, home, link2, mypage ... }


on the subject, what do people like as a clear examples site? the spec
does
its best to make YAML as unreadable as XML...
http://yaml.org/spec/current.html#id2540046


http://yaml4r.sourceforge.net/cookbook/
seems good

thanks!

/dc
47b1910084592eb77a032bc7d8d1a84e?d=identicon&s=25 Joel VanderWerf (Guest)
on 2007-08-02 08:20
(Received via mailing list)
d c wrote:
> i understand hashes dont keep their order in ruby, so wondering what the
> most elegant way to create some YAML that i want to maintain order is...

You can monkey-patch Hash to do it:

class Hash
   def to_yaml( opts = {} )
     YAML::quick_emit( object_id, opts ) do |out|
       out.map( taguri, to_yaml_style ) do |map|
         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
       end
     end
   end
end
C1bcb559f87f356698cfad9f6d630235?d=identicon&s=25 Hal Fulton (Guest)
on 2007-08-02 08:39
(Received via mailing list)
Joel VanderWerf wrote:
>
> You can monkey-patch Hash to do it:

Do you really use that term that way? I wince when I read it.  ;)

> class Hash

[snip]

But that sorts the keys... wouldn't he have to add a field to each
key on which to sort, if he wanted to preserve original order?

Hal
47b1910084592eb77a032bc7d8d1a84e?d=identicon&s=25 Joel VanderWerf (Guest)
on 2007-08-02 09:03
(Received via mailing list)
Hal Fulton wrote:
> Joel VanderWerf wrote:
>> You can monkey-patch Hash to do it:
>
> Do you really use that term that way? I wince when I read it.  ;)

Hm. Ruby-quiz: find a better term...

>> class Hash
>
> [snip]
>
> But that sorts the keys... wouldn't he have to add a field to each
> key on which to sort, if he wanted to preserve original order?

Erg. It's way too late for me to be posting. You're quite right. All
that my simian patch does is sort in an order that is probably quite
unwanted.
45196398e9685000d195ec626d477f0e?d=identicon&s=25 Trans (Guest)
on 2007-08-02 13:24
(Received via mailing list)
On Aug 1, 10:56 pm, "d c" <lis...@pikkle.com> wrote:
>   link3: logout
> section:
>  { link1, home, link2, mypage ... }
>
> on the subject, what do people like as a clear examples site? the spec does
> its best to make YAML as unreadable as XML...http://yaml.org/spec/current.html#id2540046
>
> http://yaml4r.sourceforge.net/cookbook/
> seems good
>
> thanks!

YAML has a secondary type called an omap. It is supported in the syck
implementation:

 section1: !omap
   - link1: home
   - link2: my page
   - link3: logout

The type is YAML::Omap.

T.
47b1910084592eb77a032bc7d8d1a84e?d=identicon&s=25 Joel VanderWerf (Guest)
on 2007-08-02 17:19
(Received via mailing list)
Trans wrote:
..
>> but to keep this as an array, it seems nasty to step thru and read
>> pairs/skip in twos thru the array:
...
> YAML has a secondary type called an omap. It is supported in the syck
> implementation:

That still loads as an array though:

require 'yaml'

h = YAML.load <<EOY
  section1: !omap
    - link1: home
    - link2: my page
    - link3: logout
EOY

p h

__END__

Output:

{"section1"=>[["link1", "home"], ["link2", "my page"], ["link3",
"logout"]]}


Maybe the !!omap is useful, but the thing it loads as doesn't seem to
have a #[] method (and it's not clear the data structure is any more
efficient than an array):

require 'yaml'

h = YAML.load <<EOY
  section1: !!omap
    - link1: home
    - link2: my page
    - link3: logout
EOY

p h["section1"]["link1"] # ==> undef method

Anyone have any enlightenment...?
1bac2e65d64faf472cf2ebc94f0f5ee0?d=identicon&s=25 ara.t.howard (Guest)
on 2007-08-03 03:04
(Received via mailing list)
On Aug 1, 2007, at 11:56 PM, d c wrote:

>   link1: home
>   link2: my page
>   link3: logout
>
> section2:
>   ... etc
>

http://drawohara.com/post/7519952

enjoy.

a @ http://drawohara.com/
45196398e9685000d195ec626d477f0e?d=identicon&s=25 Trans (Guest)
on 2007-08-03 03:35
(Received via mailing list)
On Aug 2, 11:17 am, Joel VanderWerf <vj...@path.berkeley.edu> wrote:
> That still loads as an array though:
> p h
>
>
> Anyone have any enlightenment...?

Syck isn't 1.1 compliant (AFAIK) so you have a typo in your last
example. It needs to be !omap, not !!omap.

  h = YAML::Omap['a',1,'b',2]
  => [["a", 1], ["b", 2]]
  h['a']
  => 1

T.
47b1910084592eb77a032bc7d8d1a84e?d=identicon&s=25 Joel VanderWerf (Guest)
on 2007-08-03 05:26
(Received via mailing list)
Trans wrote:
> Syck isn't 1.1 compliant (AFAIK) so you have a typo in your last
> example. It needs to be !omap, not !!omap.

Syck does load !!omap, but the resulting object doesn't behave very
usefully. I'm not quite sure what it's supposed to do...
45196398e9685000d195ec626d477f0e?d=identicon&s=25 Trans (Guest)
on 2007-08-03 05:58
(Received via mailing list)
On Aug 2, 11:25 pm, Joel VanderWerf <vj...@path.berkeley.edu> wrote:
> Trans wrote:
> > Syck isn't 1.1 compliant (AFAIK) so you have a typo in your last
> > example. It needs to be !omap, not !!omap.
>
> Syck does load !!omap, but the resulting object doesn't behave very
> usefully. I'm not quite sure what it's supposed to do...

It's loading it as an unknown private type.

  x = %{
    a: !!omap
      - x: 1
      - y: 2
  }
  => "\na: !!omap\n  - x: 1\n  - y: 2\n"
  r = YAML::load(x)
  => {"a"=>#<YAML::PrivateType:0xb79a5058 @type_id="omap",
@value=[{"x"=>1}, {"y"=>2}]>}

Which is why it doesn't know #[], but it knows #value:

  r["a"].value
  => [{"x"=>1}, {"y"=>2}]

T.
This topic is locked and can not be replied to.