3

In my code I have:

class User < ActiveRecord::Base
  ...
    scope :matching, -> (column=nil, value=nil) { where("#{column} = ?", value) }
  ...
end

Assuming a valid public_id: a113f534 (not to be confused with an :id), when I do:

User.matching("pubid", "a113f534").pluck(:id)

It returns:

[1]

If I do:

User.matching("pubid", "a113f534").pluck(&:id)

It returns:

[[1, "emaildata@inmydb.com", "$blahsomehash", "moreRandomDBdata", nil, Wed, 27 Aug 2014 18:55:33 UTC +00:00, Wed, 27 Aug 2014 21:22:17 UTC +00:00]]

Why does using ampersand-colon (which I know calls to_proc on the symbol) return an array with my id as well as more database column data, as opposed to when I just pass in the symbol, which returns what I want (just the id)?

I was under the impression that for Ruby > ~2.0.0, passing in the ampersand was optional and equivalent to just passing in the symbol.

Tim Zimmermann
  • 6,132
  • 3
  • 30
  • 36
Danny Y
  • 261
  • 3
  • 9

1 Answers1

8

I was under the impression that for Ruby > ~2.0.0, passing in the ampersand was optional and equivalent to just passing in the symbol.

No, it's not.

pluck(&:id)

Is a shorthand for

pluck { |u| u.id }

i.e. you are passing a block. pluck however ignores the block, so the above is equivalent to

pluck { }

or just

pluck

which returns an array of all column values.

Stefan
  • 109,145
  • 14
  • 143
  • 218
  • 1
    Thanks for the explanation! One thing though - if the ampersand is not no longer optional, why does something like `arr.inject(:+)` produce the same results as `arr.inject(&:+)` ? – Danny Y Aug 28 '14 at 14:55
  • 3
    @DannyY Look at the [method signatures of #inject](http://ruby-doc.org/core-2.1.2/Enumerable.html#method-i-inject) - they can accept just a symbol (like `:+`), or a block (like `&:+`). So it's not that the & is optional, you can just get away with using either. – MrDanA Aug 28 '14 at 14:58