Symbol#to_proc – what?
While reading Advanced Rails by Brad Ediger, I’ve stumbled upon this little helper in ActiveSupport. The to_proc method is an extension to Symbol. Let me shamelessly copy Brad’s example here:
(1..5).map { |i| i.to_s } # => ["1", "2", "3", "4", "5"]
This is already pretty nice, but now look what happens when using Symbol#to_proc:
(1..5).map(&:to_s) # => ["1", "2", "3", "4", "5"]
This is even shorter and does produce exactly the same output. So what happened here?
The “&” character tells Ruby that you want to call map with “to_s” as a block argument. It will force Ruby to call the Symbol’s to_proc method. The method will create a Proc and send the symbol to the object calling the to_proc method. And this leads to iterating over the numbers specified by the range and then calling the block, passing in the numbers and converting them to strings.
Okay… This is a typical example of me not being able to figure out what some code actually means and then by accident finding the explanation somewhere else. How the heck am I supposed to know where to find the documentation to such a cool extensions? I will let you know when I’m finally able to solve this mystery…
Brad Ediger 3:15 am on August 13, 2008 Permalink |
Hi Frederik,
I’m sort of in agreement with you that this little trick can decrease readability of code, depending on context. Symbol#to_proc is fairly idiomatic in Rails now, having been part of ActiveSupport for quite some time. It’s still something one has to learn as part of one’s Ruby “dialect”. And more often than not, I choose to explicitly write my procs out in Ruby code (outside of Rails), rather than importing Symbol#to_proc. The to_proc hack is also slower (sometimes substantially slower) in Ruby 1.8 / ActiveSupport because of the overhead of building the Proc.
Incidentally, Ruby 1.9 includes Symbol#to_proc as part of the core language.
Regards,
Brad
fdietz 1:03 pm on August 13, 2008 Permalink |
Hi Brad,
it seems generally more difficult in a dynamic languages like Ruby to figure out how things work. Meta-programming, reflection, coding by convention, etc. just means that one has to simply document things explicitly. So, I haven’t found a good way yet to find documentation for particular things and instead focused on reading a lot of books about Ruby in general and Ruby on Rails in particular. I’m wondering how we could improve such a situation, for example: how should we document “method_missing” inner workings with rdoc? If would be cool to find a way to formalize this a bit and come up with tooling support. Something like annotations in rdoc pointing to documentation would already be helpful, but I haven’t really thought about it yet. Should probably write a blog entry on this some time.
Really like your book, keep up the good work!
Cheers,
-Frederik
Symbol#to_proc and Ruby’s Open Classes « Frederik’s Weblog 2:03 pm on August 21, 2008 Permalink |
[...] and Ruby’s Open Classes 21Aug08 Just saw an article related to my last post about Symbol#to_proc. Very interesting read! And even more fun is this article which explains the [...]