16

According to APIdock, the Ruby method Enumerable#each_with_object is deprecated.

Unless it's mistaken (saying "deprecated on the latest stable version of Rails" makes me suspicious that maybe it's Rails' monkey-patching that's deprecated), why is it deprecated?

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Andrew Grimm
  • 78,473
  • 57
  • 200
  • 338

3 Answers3

51

This is rather an answer to a denial of the presupposition of your question, and is also to make sure what it is.


The each_with_object method saves you extra key-strokes. Suppose you are to create a hash out of an array. With inject, you need an extra h in:

array.inject({}){|h, a| do_something_to_h_using_a; h} # <= extra `h` here

but with each_with_object, you can save that typing:

array.each_with_object({}){|a, h| do_something_to_h_using_a} # <= no `h` here

So it is good to use it whenever possible, but there is a restriction. As I also answered in "How to group by count in array without using loop",

  • When the initial element is a mutable object such as an Array, Hash, String, you can use each_with_object.
  • When the initial element is an immutable object such as Numeric, you have to use inject:

    sum = (1..10).inject(0) {|sum, n| sum + n} # => 55
    
the Tin Man
  • 158,662
  • 42
  • 215
  • 303
sawa
  • 165,429
  • 45
  • 277
  • 381
  • 2
    +1 - Thanks for the clarification of the difference between each_with_object and inject! – Topher Fangio Feb 14 '13 at 15:56
  • 1
    According to [this source](http://www.bbs-software.com/blog/2013/11/22/rubys-injectreduce-and-each_with_object/), each_with_object does more than just save key strokes, it's actually a more efficient version of inject because it re-uses the same object for each iteration rather than creating a new one. – Peter Berg Aug 18 '14 at 15:26
  • you do realize that the second version has 7 extra characters, right ? so when you say that `each_with_object` saves you keystrokes, I would expect the second version to have less chars. Not the case. – Cosmin Atanasiu Aug 24 '17 at 18:18
  • @CosminAtanasiu "save keystrokes" is your word, not mine. – sawa Aug 25 '17 at 02:33
13

Well, that seems a bit weird.

Even Agile Rails writes somewhere:

"The Ruby 1.9 each_with_object method was found to be so handy that the Rails crew backported it to Ruby 1.8 for you".

This seems like an error in APIdock ? I don't see any reason why it would be.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Spyros
  • 46,820
  • 25
  • 86
  • 129
13

There's no note in the Ruby trunk source code, the method is still there (contrary to that page's claims), and there's been no talk of it on the mailing list that I can find.

APIdock is simply confused. The point where APIdock says it was deprecated is actually the earliest version with the method in the standard library (rather than just being an ActiveSupport backport extension), and Rails disables its version if you're using a Ruby that has the method, so APIdock appears to be confused by the method migrating between projects.

Chuck
  • 234,037
  • 30
  • 302
  • 389