From: "Bhardwaj, Aadarsh" Date: 2010-03-01T18:59:23+09:00 Subject: Please Contribute Dear all Please contribute in enhancing the functionality of my website - please visit - http://techie.bewhizkid.com I need your valuable comments, if any one wants to contribute please let me know. On 3/1/10, Robert Klemme wrote: > 2010/2/28 Glenn Ritz : >> Robert Klemme wrote: >>> 2010/2/24 Xavier Noria : >>>>>> >>>>> {'en' => {'A' => Fixnum, 'B' => {'C' => Fixnum, 'D' => String }} >>>> � �newh[k] = v.is_a?(Hash) ? classify_values(v) : v.class >>>> �end >>>> �newh >>>> end >>>> >>>> p classify_values({'en' => {'A' => 1, 'B' => {'C' => 3, 'D' => 'four' >>>> }}}) >>> >>> I would do it a tad differently: >>> >>> def classify(o) >>> case o >>> when Hash >>> h = {} >>> o.each {|k,v| h[k] = classify(v)} >>> h >>> else >>> o.class >>> end >>> end >>> >>> Advantage is that you can stuff anything in the method while your >>> variant requires the argument to be a Hash. The difference may seem >>> subtle but if you add more collection types for special treatment, >>> you'll will notice a difference in effort to implement it. I can >>> simply do >>> >>> def classify(o) >>> case o >>> when Hash >>> h = {} >>> o.each {|k,v| h[k] = classify(v)} >>> h >>> when Array >>> o.map {|v| classify(v)} >>> else >>> o.class >>> end >>> end >>> >>> while you need to do a more complicated code change. >>> >>> Kind regards >>> >>> robert >> >> Thanks, this is very helpful. >> >> I am trying to adapt this a bit, but with no luck so far. >> >> What I'd like to do is to start with a hash and have the above code be >> additive. >> >> In other words, if I have the following code: >> >> h0 = {} >> h1 = {'en' => {'A' => 5, 'B' => { 'C' => 'xxx', 'D' => { 'E' => 4 }}}} >> h2 = {'en' => {'F' => 'yyy'}} >> >> >> I'd like to be able to call the classify method like this: >> >> puts h0.classify(h1).classify(h2).inspect >> >> And get the following result: >> >> {'en' => {'A' => Fixnum, 'B' => { 'C' => String, 'D' => { 'E' => Fixnum >> }}, 'F' => String }} >> >> So I figured it would be something like this: >> >> class Hash >> def classify(o) >> case o >> when Hash >> h = self >> o.each {|k,v| h[k] = classify(v)} >> h >> when Array >> o.map {|v| classify(v)} >> else >> o.class >> end >> end >> end >> >> But this is probably wrong in a few ways. Any suggestions would be >> appreciated. > > I would separate this in two steps: > > 1. merge Hashes intelligently (i.e. with a bit more logic than > Hash#merge default behavior). > > 2. classify. > > So this would probably be something like > > class Hash > def merge_deep!(hs) > merge! hs do |key,old_val,new_val| > case old_val > when Hash > old_val.merge_deep! new_val > else > new_val > end > end > end > end > > see > http://www.ruby-doc.org/ruby-1.9/classes/Hash.html#M000406 > > Kind regards > > robert > > -- > remember.guy do |as, often| as.you_can - without end > http://blog.rubybestpractices.com/ > > -- With Regards, Adarsh Bhardwaj