From: Guido De Rosa Date: 2010-10-07T01:05:39+09:00 Subject: Re: "map" a deeply nested structure: Object#deep_map > What about keys? Hash#map allows to map keys and values > > irb(main):001:0> h={1=>2,3=>4} > => {1=>2, 3=>4} > irb(main):002:0> h.map {|k,v| [k*10,v*100]} > => [[10, 200], [30, 400]] > > What, if the key is an Array or Hash? Wouldn't this be more > appropriate? > > out[k.deep_map(&block)] = v.deep_map(&block) I was not interested in mapping keys, but this would be a reasonable extra feature. So deep_map would be used like that: object.deep_map{|k, v| ... [result_key, result_value]} resembling Hash#map behavior and when object is not Hash-like, result_key would be simply ignored. It should not be hard to allow client code to use also "the previous API": object.deep_map{|x| ... } by checking block.arity in the implementation code. > You could remove lines "out = ..." and replace them by > > out = self.class.new Good point... apparently! What if self is a Range? Forcing to return an Array (or a Hash) is not so bad: even the standard method Enumerable#map does so! And so does Enumerable#sort and many others: it's just to avoid nonsensical situations :-) > I wonder how many use cases for this there are actually. In your > example you can uniformly treat each object since you want the > object_id. That would work for a few other methods as well (e.g. > #inspect, #to_s). In other cases you would have to discriminate > treatment of leave values in your block, e.g. > > x.deep_map |y| > case y > when String > ... > when Fixnum > ... > else > ... > end > > That list could become lengthy. Basically you implemented tree > traversal with double dispatch - only that the double dispatch must be > done manually in the block. :-) The same holds for standard Enumerable#map and Hash#map, so... I just want to write the recursive version of some Ruby core methods, resembling by many aspects pretty much the same behavior, including the fact that some checks are up to the user ;-) G. -- Posted via http://www.ruby-forum.com/.