Hacker News new | ask | show | jobs
by rco8786 1094 days ago
> I'm not really a fan of those & shortcuts.

One of my favorite parts of ruby!

`collect.each(&:operation)` vs `collection.each { |thing| thing.operation }`

1 comments

> &:operation

If one is unfamiliar, this syntax will implicitly call `Symbol#to_proc` on `:operation` and pass that as a block to the method (it will work with any object which responds to `#to_proc` and returns an object which responds to `#call`). These lines are all equivalent:

  my_array.map(&:operation)
  my_array.map { |my_element| my_element.operation }
  my_array.map { |my_element| :operation.to_proc.call(my_element) }
Given that, I adore the terseness in the first line, though I can understand a certain annoyance that the shorthand can cause if one doesn't know how this works.
I find it's best to just blindly accept it in Ruby, because you can really go down the rabbit hole otherwise. For example, the first example has even more syntactic fun going on because it looks like `map` accepts an argument but it doesn't:

    irb(main)> [1,2,3].map(1)
    (irb): in `map': wrong number of arguments (given 1, expected 0)
So you get clever and think.. well, it accepts a Proc, clearly, in the shape of &:operation. Let's use a Proc:

    irb(main)> [1,2,3].map(Proc.new { })
    (irb):in `map': wrong number of arguments (given 1, expected 0)
In the context of blocks, & is doing a little more than merely providing a Proc, but it's a handy way to think about it.