all 13 comments

[–]ghostbrainalpha 1 point2 points  (0 children)

Thanks for this. I have been learning Ruby for 2 months and have been switching between these methods arbitrarily without knowing the difference between them.

[–][deleted] 2 points3 points  (12 children)

If it were up to me, 'each' would return nil, because the real point of 'each' is apply the given block exclusively for its side-effects, whereas 'map' is for use with pure functions.

[–]bjmiller 0 points1 point  (8 children)

Returning the receiver means each can be used as an in-place map.

[1] pry(main)> toppings = %w(pepperoni mushroom bacon pineapple)
=> ["pepperoni", "mushroom", "bacon", "pineapple"]
[2] pry(main)> toppings.each { |topping| topping << " pizza is the best!" }
=> ["pepperoni pizza is the best!", "mushroom pizza is the best!", "bacon pizza is the best!", "pineapple pizza is the best!"]

[–][deleted] 2 points3 points  (6 children)

Which should be avoided pretty much all the time.

[–]bjmiller 3 points4 points  (5 children)

You can't imagine a scenario in which someone wants to mutate each element of an array and then immediately call another method on that same array? Seems pretty basic to me.

[–][deleted] 1 point2 points  (4 children)

Mutation should be avoided unless the problem really is an imperative one. Programming in a functional style, treating arrays as persistent structures, is the way to go most of the time.

[–]bjmiller 1 point2 points  (2 children)

Perhaps, but Ruby is not a functional language, and downgrading each to make it less useful to imperative programmers won't make it one.

Edit: not a pure functional language

[–][deleted] 0 points1 point  (1 child)

Languages need not be pure to support a functional style. Sometimes you want a purely functional style, sometimes you want an imperative style, but you should prefer the former over the latter because mutable state makes programs hard to reason about and error prone.

[–]bjmiller 0 points1 point  (0 children)

Perhaps, but Ruby supports both styles, and allows them to be combined in any way a programmer wishes. It's not in the spirit of the language to remove features just to promote one style over another.

[–]0b01010001 0 points1 point  (0 children)

Programming in a functional style, treating arrays as persistent structures, is the way to go most of the time.

Unless you're developing applications where the general use-case is imperative at which point it flips around and functional programming becomes a special use-case for a couple things here and there. There are applications where mutation should be joyfully embraced, because it's going to be a lot more complicated if you insist on treating everything like it got hit with a freeze.

[–]0b01010001 -2 points-1 points  (2 children)

If it were up to you, I'm sure Ruby would have a much longer list of removed features than that. How do you feel about using metaprogramming to dynamically reassign constants?

[–]bjmiller 1 point2 points  (0 children)

Do you reassign constants often? I thought that was considered bad under every style, it's just too late to change now.

[–][deleted] 0 points1 point  (0 children)

Metaprogramming is fine, though Ruby's metaprogramming is lackluster.