Symbol#to_proc: hack or syntactical sugar?
I was recently reminded of this piece of syntax:
ids = users.collect(&:user_id)
This is equivalent to:
ids = users.collect { |u| u.user_id }
The implementation is provided by a Rails extension to Ruby’s Symbol class and hence is not available in pure Ruby environments, like irb
.
While clearly this is a handy shortcut, it makes your code quite unreadable for anyone who doesn’t understand the to_proc
extension made by the Rails team—it is not inherently obvious what you’re doing. If your code is being maintained by multiple developers, is it really wise to use it?
For those of you wondering how this little trick works: the Rails team is exploiting the nature of duck typing in Ruby. When the &
operator is used as a function parameter, you are telling Ruby to treat that parameter as the block passed to the function. In order to assure that the object is a Proc object, Ruby calls to_proc
on all such parameters. Hence, the Symbol class has been extended by the Rails team to include a to_proc
method. This method returns a Proc which calls the method by the same name as the symbol itself.