Issue #7297 has been updated by rosenfeld (Rodrigo Rosenfeld Rosas).


Hi Thomas,

I agree that _object is a redundant suffix and that map_with is probably a better description than each_with or each_with_object.

But it makes sense to me that each_with_object should yield(item, object) because of the name of the method. I do agree that the order of the arguments isn't very important but I would prefer to have the returning value to become first as it seems more natural to me and it also aligns well with inject like you said.

Now, what I'm not comfortable with is using map_with with {} as the default argument. I agree this is the commonest case, this is not the issue. The problem is that this doesn't read well for someone trying to understand the code:

doubles = numbers.map_with{ |n, h| h[n] = n * 2 }

This reads much better:

doubles = numbers.map_with({}){ |n, h| h[n] = n * 2 } # although I'd reorder the arguments of the closure.

So, if it was my decision to design the language I would probably deprecate each_with_object in favor of map_with, I'd replace the order of the arguments in the block and would also create another method:

def hash_map(&block)
  map_with({}, block)
end

Instead of hash_map I'd also support the idea of using to_h as suggested by someone a while back:

doubles = numbers.to_h{|h, n| h[n] = n * 2 }

----------------------------------------
Feature #7297: map_to alias for each_with_object
https://bugs.ruby-lang.org/issues/7297#change-32569

Author: nathan.f77 (Nathan Broadbent)
Status: Rejected
Priority: Normal
Assignee: 
Category: lib
Target version: 2.0.0


I would love to have a shorter alias for 'each_with_object', and would like to propose 'map_to'. Here are my arguments:

* It reads logically and clearly:

[1, 2, 3].map_to({}) {|i, hash| hash[i] = i ** 2 }
#=> {1 => 1, 2 => 4, 3 => 9}

* Rubyists are already using 'map' to build and return an array, so it should be obvious that 'map_to(object)' can be used to build and return an object.

* Given that 'each' and 'each_with_index' return the original array, I feel that the 'each_with_object' method name is slightly counterintuitive. 'map_to' might not be 100% semantically correct, but it's obvious that it will return something other than the original array.

* Many people (myself included) were using inject({}) {|hash, el| ... ; hash } instead of 'each_with_object', partly because of ignorance, but also because 'each_with_object' is so long. 'map_to' is the same length as inject, and means that you don't have to return the object at the end of the block.

* Only a single line of code is needed to implement the alias.


Best,
Nathan


-- 
http://bugs.ruby-lang.org/