27

We often shorten a block using the & notation on a symbol like this:

some_array.group_by(&:foo)

Is there a similar way to shorten expressions like {|x| x}?

some_array.group_by{|x| x}

If there were a method Object#self that returns self, then we can do

some_array.group_by(&:self)

but unfortunately, there is no such method. In terms of the number of characters, it may be longer, but readability improves.

5
  • 1
    no it as in groovy, i'm afraid Commented Jun 5, 2013 at 6:12
  • 3
    That is the Identity Function. IDENT = Proc.new {|x| x}; array.group_by(&IDENT). Commented Jun 5, 2013 at 6:15
  • Does to_proc make sense in this context? I could be wrong. Commented Jun 5, 2013 at 6:16
  • group_by(&:to_proc) does not work. Commented Jun 5, 2013 at 6:18
  • 2
    Kernel#itself was added in Ruby 2.2.0, so you can use that. See my answer for more details. The other answers are out of date and I think @sawa should accept mine. Commented Apr 13, 2015 at 17:14

3 Answers 3

30

Yes. #itself was implemented in Ruby 2.2.0.


You can access the Ruby core team discussion about this feature here.

As an interesting analogue, the #ergo method has been proposed, which would yield the receiver to a given block.

If you haven't yet upgraded to Ruby 2.2.0, you may wish to backport #itself and/or define #ergo as follows:

class Object
  def itself; self end
  def ergo
    fail ArgumentError, "Block expected!" unless block_given?
    yield self
  end
end

And then:

some_array.group_by &:itself
Sign up to request clarification or add additional context in comments.

3 Comments

Good news to hear that. Thanks for the information. Hope it will be implemented soon.
Well, they assigned it to the "next minor release", but they are already working on 2.1, and this feature is still being held back. So, maybe "next minor" does not really mean "immediately next" :-))) I guess they are very busy, and still manage to respond to suggestions.
It's worth noting that the method #itself has been implemented as of Ruby 2.2.0
18

Well, there's no built-in as far as I know, but you can make a reusable identity block:

id = Proc.new {|x| x}
some_array.group_by(&id)

And then if you really wish this were a language feature:

class Object
  def it
    Proc.new {|x| x}
  end
end

And then you can do:

some_array.group_by(&it)

wherever you like. This may void your warranty.

1 Comment

This is essentially what I was talking about in my comment. +1
14

Yes! The method Kernel#itself was added in Ruby 2.2.0. This method simply returns the object it was called on, so you can write:

some_array.group_by(&:itself)

You can see the extensive discussion of this feature here: https://bugs.ruby-lang.org/issues/6373. The patch was submitted by Rafael França in message #53. You can see it in the official Ruby source by looking in object.c.

If you are using a version of Ruby older than 2.2.0, you can easily add Kernel#itself into your project by putting this code somewhere in your project and making sure it gets required:

module Kernel
  def itself
    self
  end
end if !Kernel.instance_methods.include?(:itself)

However, monkey-patching a part of the Ruby core like that can be dangerous and I would not recommend it if you are making reusable code, like a gem. Instead I would recommend just making your own identity function, as suggested by user2246674:

module MyLibrary
  IDENT = Proc.new { |x| x }

  array.group_by(&IDENT)
end

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.