3

I'm walking through the example project in the Rails 5 Test Prescriptions - Build a Healthy Codebase (published date: 2018) book and encountering this method:

#pages 29-30 of the book
class Project
  .
  .
  def done?
    tasks.all?(&:complete?) #only this line confused me, especially the `&` part
  end
end

the syntax looks really strange to me since I just learned Ruby & Rails for more than one month..any hints just for pointing me to where I should read would be really appreciated

You Nguyen
  • 9,961
  • 4
  • 26
  • 52
  • 5
    It is equivalent to `tasks.all? { |task| task.complete? }`. Does that help? – spickermann Jun 30 '19 at 08:27
  • it does help, thank you so much! so, the `&:` part represents a block, right? or what? the `&:` part is what confuses me – You Nguyen Jun 30 '19 at 08:28
  • 3
    The `:` is for a symbol, `:complete?`. Prepending `&` converts it to a proc. See https://stackoverflow.com/questions/1217088/what-does-mapname-mean-in-ruby – Eric Duminil Jun 30 '19 at 08:31
  • 1
    The answer to "what does it mean?" should be pretty clear if you simply read the code out loud. – Eric Duminil Jun 30 '19 at 08:31
  • 1
    Please, read https://meta.stackoverflow.com/a/253896/2988 and https://softwareengineering.meta.stackexchange.com/a/7514/1352 to understand why "Explain this code" questions are off-topic, and what you can do to improve your question to make it on-topic. The code you posted uses about 20 different concepts of Ruby, or, almost all of the entire language. The ISO Ruby Language Specification is about 120 pages just for the language and another 200 for the library and actually only contains a small subset of what we consider to be "Ruby". We can't possibly explain all of that in a single answer. – Jörg W Mittag Jun 30 '19 at 11:30
  • Also, your question is unclear. In the title, you ask about the meaning, i.e. the semantics of the code. But, in the first part of your question, you ask about the syntax. Then, at the end, you talk about what the code does, i.e. what the programmer wanted to achieve. Those are three completely different questions. – Jörg W Mittag Jun 30 '19 at 11:32
  • @JörgWMittag I just edited the question to improve its conciseness. You're right that there're three completely different questions since what I really wanted to ask is about the syntax. – You Nguyen Jun 30 '19 at 12:02
  • 1
    @EricDuminil thank you so much! This is exactly what I was looking for. The `proc` is actually the key here. Based on that, I found the complete explanation in page 452 - the The Well-Grounded Rubyist 3rd (published date: 2019) book, which is about Using Symbol#to_proc for conciseness – You Nguyen Jun 30 '19 at 12:13

1 Answers1

1

& is for passing block to method as a block (also used the other way in parameter list to make implicit block a parameter), it implicitly calls to_proc on passed object.

Symbol#to_proc for :symbol makes a proc{|param| param.symbol }

So your code is equvalent to tasks.all?{|task| task.complete? }

Vasfed
  • 18,013
  • 10
  • 47
  • 53
  • Might be better phrased "`&` converts a symbol to a method call of the same name using `Symbol#to_proc`". – tadman Jun 30 '19 at 17:30
  • That’s a side effect of the operator, but point is in passing as block, instead of symbol there may be a proc (`block = proc{}; method(&block)`) – Vasfed Jun 30 '19 at 17:44
  • Thank you for your answer! Btw, I also found another great explanation here https://stackoverflow.com/a/14881476/7932059 – You Nguyen Jul 01 '19 at 02:38