From: Benoit Daloze Date: 2011-11-23T19:31:20+09:00 Subject: [ruby-core:41245] [ruby-trunk - Feature #5662] inject-accumulate, or Haskell's mapAccum* Issue #5662 has been updated by Benoit Daloze. Rodrigo Rosenfeld Rosas wrote: > Interesting, I never noticed/used this method before. My only concern is about the naming "each_with_object" when you actually want to inject/accumulate. The code intention is not clear enough when you write each_with_object. Maybe a better alias could be included. I think accumulate implies an accumulator, which you don't have in this case. A Hash does not accumulate values like a growing Integer for example, it rather "register" the key/value entries. The alias of inject, reduce, is actually clear to the intention, you should not use inject with an Array for example (instead of map). each_with_object is just avoiding the explicit variable definition and returns it: h = {} [1, 2].each { |i| h[i] = 2*i } h I believe the code I showed is somewhat common in 1.9 and is clear to people knowing about it. In this particular case, you could probably also use Hash.new: Hash.new { |h,k| h[k] = k*2 } ---------------------------------------- Feature #5662: inject-accumulate, or Haskell's mapAccum* http://redmine.ruby-lang.org/issues/5662 Author: Edvard Majakari Status: Open Priority: Normal Assignee: Category: Target version: with Ruby, we often use this idiom to build a hash out of something: new_hash = enum.inject({}) { |h, thing| h[compute_key(thing) = compute_value(thing)]; h } while that last h is very easy to add, it is also easy to forget and feels logically not very injectish thing to do. I'd propose this we call 'infuse' in our project: module Enumerable # like inject, but returns accumulator instead. Instead of writing # [1, 2].inject({}) {|h, i| h[i] = 2*i; h } # just say # [1, 2].infuse({}) {|h, i| h[i] = 2*i } # -> {1 => 2, 2 => 4} def infuse(init, &block) inject(init) { |acc, i| block.call(acc, i); acc } end end Eg. [1, 2].infuse({}) { |a, i| a[i] = 2*i } # => {1 => 2, 2 => 4} Instead of infuse, maybe inject_accum or inject_acc would be more rubyish method name. -- http://redmine.ruby-lang.org