[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

YAML and hash

Artur Merke

2/21/2005 1:53:00 PM

7 Answers

Robert Klemme

2/21/2005 2:50:00 PM

0


"Artur Merke" <merke@ls1.cs.uni-dortmund.de> schrieb im Newsbeitrag
news:Pine.LNX.4.33.0502211443370.17818-100000@as0203.cs.uni-dortmund.de...
> Hi,
>
> is there a possibility to recognize multiple keys while
> reading a hash using YAML?
>
> example:
>
> arr= YAML::load("aaa: 1\nbbb: 2\naaa: 3" )
> => {"aaa"=>3, "bbb"=>2}
>
> but I would like to get a warning or an exception when
> encountering the key 'aaa' for the second time, and not just
> get the first entry overwritten.
>
> Any ideas?

I don't have much insight into YAML internals but you'll probably be able
to do that with YAML#add_builtin_type or YAML#add_ruby_type
http://www.ruby-doc.org/core/classes/YAML.ht...

Kind regards

robert

Navindra Umanee

2/21/2005 3:12:00 PM

0

Robert Klemme <bob.news@gmx.net> wrote:
> I don't have much insight into YAML internals but you'll probably be able
> to do that with YAML#add_builtin_type or YAML#add_ruby_type
> http://www.ruby-doc.org/core/classes/YAML.ht...

I would hazard a guess that YAML is deferring to the Hash constructor
to create hashes. The Ruby Hash behaves the same way:

irb(main):017:0> {1=>2, 1=>3}
=> {1=>3}

I had the idea that by changing the behaviour of Hash, the behaviour
of YAML would automatically change. Unfortunately, re-defining
Hash.store does not seem to be enough.

Hash is implemented in C and all Hash creations/stores are handled by
rb_hash_aset. I can't figure how to redefine this in Ruby.

Cheers,
Navin.


Robert Klemme

2/21/2005 3:46:00 PM

0


"Navindra Umanee" <navindra@cs.mcgill.ca> schrieb im Newsbeitrag
news:20050221101107.A14321@cs.mcgill.ca...
> Robert Klemme <bob.news@gmx.net> wrote:
> > I don't have much insight into YAML internals but you'll probably be
able
> > to do that with YAML#add_builtin_type or YAML#add_ruby_type
> > http://www.ruby-doc.org/core/classes/YAML.ht...
>
> I would hazard a guess that YAML is deferring to the Hash constructor
> to create hashes. The Ruby Hash behaves the same way:
>
> irb(main):017:0> {1=>2, 1=>3}
> => {1=>3}
>
> I had the idea that by changing the behaviour of Hash, the behaviour
> of YAML would automatically change. Unfortunately, re-defining
> Hash.store does not seem to be enough.
>
> Hash is implemented in C and all Hash creations/stores are handled by
> rb_hash_aset. I can't figure how to redefine this in Ruby.

That's why you have to work with YAML IMHO.

robert

Artur Merke

2/21/2005 4:26:00 PM

0

why the lucky stiff

2/21/2005 6:26:00 PM

0

Artur Merke wrote:

>Hi,
>
>is there a possibility to recognize multiple keys while
>reading a hash using YAML?
>
>example:
>
>arr= YAML::load("aaa: 1\nbbb: 2\naaa: 3" )
>=> {"aaa"=>3, "bbb"=>2}
>
>but I would like to get a warning or an exception when
>encountering the key 'aaa' for the second time, and not just
>get the first entry overwritten.
>
You're right. This should throw an error or a warning (according the
YAML specification). This a simple fix, but cannot be done in Ruby.

I've added this to the bug tracker on RubyForge. Thankyou!

_why


Adriano Ferreira

2/21/2005 6:52:00 PM

0

> You're right. This should throw an error or a warning (according the
> YAML specification). This a simple fix, but cannot be done in Ruby.

I've spent some time trying to write code to make such a thing work.
I've just found that I don't know nothing about Ruby.

I wrote the following Hash subclass that I thought could be forced
into the YAML parser (maybe through a simple explicit header like '---
!ruby/hash:AngryHash' or via a directive to the YAML parser locally
use AngryHash'es rather than primitive Hash'es).

class AngryHash < Hash

def []=(key, value)
if has_key?(key)
raise "not again: duplicate key '" + key.to_s + "'"
end
super(key, value)
end

def AngryHash.[](pairs)
h = new
pairs.each_pair {|k,v| h[k] = v}
h
end

end

Well, the rationale is not to allow pairs which keys that already
appeared (AngryHash#[]= in a pair-by-pair basis) and I guessed that
something like Hash[k1 => v1, ... ] is used by YAML parser when
constructing map-like objects. This is a dead-end. If the parser uses
this form, pairs with repeated keys were already trashed (except for
the last one) and this code is good for nothing.

The fix why_ mentioned has to do with this behaviour? If I tried to
subclass YAML::Pairs, would it work?

Regards,
Adriano.


Gavin Kistner

2/22/2005 2:22:00 PM

0

On Feb 21, 2005, at 11:52 AM, Adriano Ferreira wrote:
>> You're right. This should throw an error or a warning (according the
>> YAML specification). This a simple fix, but cannot be done in Ruby.
> class AngryHash < Hash

Heh, that's a cute name :)

I use this myself, called WriteOnceHash
http://phrogz.net/RubyLibs/rdoc/classes/WriteOnc...