franzejr / best-ruby

Ruby Tricks, Idiomatic Ruby, Refactoring and Best Practices
http://franzejr.github.io/best-ruby/
2.39k stars 219 forks source link

Suggestion for inject #61

Open jhaungs opened 8 years ago

jhaungs commented 8 years ago

In "Idiomatic Ruby / Combine..." the first statement is extraneous.

hash = {}     # not needed, even misleading
values.inject({}) do |hash, value|
  hash.merge(value => value ** 2)
end

In older versions of ruby, the hash var would collide with the block arg; in modern ruby, they're scoped, so the hash being injected is the {} arg to inject, not the variable.

A more idiomatic version might be:

result = values.inject({}) do |hash, value|
  hash.merge(value => value ** 2)
end 

It would also be useful to note that the use of merge with inject is a bit tricky, and only works because merge returns the hash itself. If the last expression in the block doesn't return the injected value, the inject will fail in weird ways. A less error-prone way to code it is to always return the injected value:

result = values.inject({}) do |hash, value|
  hash[value] = value ** 2
  hash
end

or, as a one-liner:

result = values.inject({}) {|hash, value| hash[value] = value ** 2; hash}
franzejr commented 8 years ago

@jhaungs, look at this: https://github.com/franzejr/best-ruby/pull/60