Search code examples
ruby-on-railsrubysyntaxblock

ruby on rails block sytax using &:


So say I have a Question model and an Answer model and Question has_many Answers (it's a multiple choice question).

Suppose that questions is a collection of Question objects.

In order to collect all the answers I can do this:

questions.collect(&:answers)

Two questions:

  1. What precisely does this syntax mean? Does it expand to

    questions.collect { |q| q.answers } 
    

    or is there something else going on here?

  2. Is there a way to do

    questions.collect { |q| q.answers.shuffle } 
    

    using the same syntax?

    collect(&:answers.shuffle) 
    

    isn't doing it.

I can't seem to find this in tutorials on ruby blocks on the web and searching for it doesn't work (search engines ignore "&:"). I found it in some inherited code.

Thanks


Solution

  • Yes, the first question is N-duplicated, but regarding the second: no, you cannot chain methods. However, nothing stops you -other than writing code that may puzzle people- to create your own tool:

    class Symbol
      def to_proc
        proc do |obj| 
          self.to_s.split(/\./).inject(obj, :send)
        end
      end
    end
    
    p ["1", "2", "3"].map(&:"to_i.succ")
    # [2, 3, 4]
    

    You can even find ways to send arguments, though it won't probably be very beautiful.