From: Jean-Hugues ROBERT Date: 2004-04-24T22:04:09+09:00 Subject: Re: Array to Hash At 18:24 24/04/2004 +0900, you wrote: >So the question is wich representation Enumerable#to_h should expect - >nested or sequence? > robert I believe coercion should be as loose less as possible. As a result it is difficult to imagine that a generic solution is optimal. Only the actual class knows the optimum. Yet... One may argue that an Array is a degenerated Hash where the keys are integer indices. i.e. ["a","b"].to_h() == { 0 => "a", 1 => "b" } One may argue that the loose less convertion of a Hash to an Array is an an array of [key, value]. i.e. { 0 => "a", 1 => "b"}.to_a() == [[0,"a"],[1,"b"]] (Ruby does that today) hum... issue is a.to_h().to_a() is quite different from original a. Better: # What you get when converting a Hash into an Array, see Hash##to_a() class HashAsArray < Array def to_h() # Assume self is an array of [key, value], raise exception if not true # Error checking code skipped, ToDo: it Hash[*flatten()] end end # What you get when converting an Array into a Hash, see Array##to_h() class ArrayAsHash < Hash def to_a() # Assume keys are integers indices, raise exception if not true # Error checking code skipped, ToDo: it super().sort { |(ka,va),(kb,vb)| ka <=> kb }.collect { |(k,v)| v } # ToDo: There must be a faster solution to do that. end end # Now, have Hash.to_a() return an HashAsArray instead of an Array, # and, have Array.to_h() return an ArrayAsHash. class Hash alias ruby_to_a to_a def to_a() HashAsArray.new().replace( ruby_to_a()) end def to_h() self end end class Array def to_h() ii = 0 aa = [] self.each { |v| aa << (ii += 1); aa << v } return ArrayAsHash[*aa] end end # As a result, an_array.to_h().to_a() is OK and # a_hash.to_a().to_h() is ok too. p a = ["a", "b", "c", "d", "e", "f"] p h = a.to_h() p h.class() p h.kind_of?( Hash) p h.class() == Hash # not true anymore... but: case h when Hash then p "OK" end p aa = h.to_a() p aa.class() p a.to_h().to_a() == a p a.to_a().to_h().to_a() == a p h = { "key_a" => "a", "key_b" => "b" } p a = h.to_a() p a.class() p a.kind_of?( Array) p a.class() == Array # not true anymore... but: case a when Array then p "OK" end p hh = a.to_h() p hh.class() p h.to_a().to_h() == h p h.to_h().to_a().to_h() == h # Most visible change is about these beeing false: p Array == HashAsArray p HashAsArray == Array p Hash == ArrayAsHash p ArrayAsHash == Hash # Workaround is so ugly that I don't present it here. # I believe this only change cannot break much existing code, # but very unprobable code that would depend on Hash##to_a() # beeing of class Array precisely. Questionnable # code that does not respect the OO idea of is_a relationship # and test class for equality using == instead of # kind_of? or === (in case statements). Any drawbacks (beside minor one about .class() == changed) ? Jean-Hugues