Insta-block with Symbol#to_proc

Something that might have slipped your radar in your Ruby readings is Symbol#to_proc, something that’s been in Rails since 0.14.4.

Using this nice little tidbit of Ruby tricky you can simplify code such as:

 articles.collect { |a| a.title } articles.sort { |a| a.created_at } 

to

 articles.collect(&:title) articles.sort(&:created_at) 

…and just in case you’re wondering why &:ruby_is_the_new_black doesn’t work in the beautiful ruby shell script you just wrote, it’s because Symbol#to_proc isn’t a standard Ruby thang. To quote Mauricio Fernandez who noted it’s recent inclusion in the upcoming Ruby 1.9:

Symbol#to_proc: first discovered by some anonymous Japanese Rubyist (fairly certain), rediscovered by Florian Groß (I saw that happen back when I wasted my time on #ruby-lang), then popula rized by Pragdave and Rails, finally adopted officially. It’s been a long journey.

“That’s nice,” you say, “but I still don’t really understand what all this Proc and block stuff is about.” Well, let me indulge you in some Ruby block mumblings.

I think the best way to describe a block if you’ve come from web-design-land is to think of it like an anonymous function in Javascript.

For example, the following piece of Ruby:

 socceroos.each do |s|   s.congratulate end 

is the equivalent to the following Javascript:

 socceroos.each(function(s) {   s.congratulate(); }) 

The block passed to a function is signified by an ampersand:

 class Team   def each(&block)     for player in @players       block.call(player)     end   end end 

In fact, the above pattern of calling the block is so common Ruby takes it one step further, allowing you to simply write:

 class MyTeam   def each     for member in @members       yield member     end   end end 

yield member is another way of saying “call the associated block passing it the member”. You don’t even need to add &block to the parameter list.

You would have seen this pattern when dealing with ActiveRecord. The ActiveRecord::Base class allows you to specify a block when creating new instances. For example, if Player was an ActiveRecord subclass you could do the following:

 @player = Player.new do |p|   p.name = "Ronaldo"   p.nickname = "Porky" end 

How does ActiveRecord provide this neat API? Easy! It just checks whether you specified a block and, if so, calls the block, passing the new Player object to it.

The bare minimum logic to accomplish this would be:

 class ActiveRecord::Base   def initialize     yield self if block_given?   end end 

Replay

Category: programming Time: 2006-06-19 Views: 1
Tags:

Related post

iOS development

Android development

Python development

JAVA development

Development language

PHP development

Ruby development

search

Front-end development

Database

development tools

Open Platform

Javascript development

.NET development

cloud computing

server

Copyright (C) avrocks.com, All Rights Reserved.

processed in 0.111 (s). 12 q(s)