Browse DevX
Sign up for e-mail newsletters from DevX


Ruby—A Diamond of a Programming Language, Part 2 : Page 6

Get ready to dive deeper into the power and elegance of the language lauded as a possible contender to replace current programming languages.

Code Blocks, Iterators, and Procedure Objects
Everything in Ruby is an object? Just about, yep! Even a chunk of code can be an object! In Ruby, code objects are called code blocks. Think of code blocks as little program suitcases. They contain Ruby code and can travel to methods where they can be executed. Python, C, and Java developers may all find similarities to Ruby code blocks in things like function pointers, anonymous functions, inner classes and callbacks.

The syntax for a Ruby code block is just to put Ruby code between curly braces or do/end commands.

	# this is a code block... 

	# ...and this is a code block
In a very simple example, { puts “hello world” } is a valid code block. How do you use these code blocks and pass them as a suitcase of code to a method? For that, first define a very simple method like the one below.

def someMethod
The command yield transfer control to the code block that is passed to the method. The code below shows you how a code block is passed to the simple method above using a simple code block.

irb(main):001:0> someMethod {puts "hello world"}
hello world
Each time yield is called, the code block passed to the method gets executed. Here is another example of a more complex method using a code block that does a little more work.

def fibonacci (stop)
	while stop < 20
=> nil
i=0; j=1; fibonacci(j) {puts i; temp = i; i = j;j = temp + j}
Code blocks are used throughout Ruby. Most importantly, code blocks are used internally by Ruby in the iterator methods of classes like Array, Hash, and even String. A code block is how you define what task to perform (typically a task on the elements) when iterating through all the elements in an array. To demonstrate code blocks and iterators, a small example is in order. Assuming you had defined a number of barn yard animal classes as those defined in Figure 3 and an Array of those animals, you could make each talk using a code block and an iterator on the array.

barnYard = [Cow.new, Duck.new, Chicken.new, Horse.new, Dog.new]
=> [#<Cow:0x58d2f48>, #<Duck:0x58d2f30>, #<Chicken:0x58d2f00>, #<Horse:0x58d2ee8>, #<Dog:0x58d2ed0>]
barnYard.each {|animal| animal.talk}
Bark bark 
Figure 3. Simple Ruby Barn Yard Classes: If your barn yard of animals was defined as represented in the Ruby code in this figure, then you could use a code block in a call to each on an array of animals to make them talk as shown below.

The method each called on barnYard is one of the iterator methods for an array. Notice the |) help to define arguments to receive parameters. In this case, the code block receives one argument; namely each successive animal in barnYard as the iterator loops through the collection of animals.

Iterators and code blocks even allow us to do something as simple and neat as the following example:

3.times {puts "Ruby is cool!"}
Ruby is cool!
Ruby is cool!
Ruby is cool!
That's right, even the Integer class offers an iterator (the times method) that uses a code block to provide a quick and dirty for-loop.

Before leaving a discussion of code blocks and iterators, you should know that code blocks can be assigned to a variable. In fact, such code blocks are actually instances of the Proc class. You can define a Proc instance using the new method or use the These Proc instances can then be invoked by using the call method.

irb(main):003:0> simpleProc.call
=> nil
irb(main):004:0> anotherProc.call("hello yourself")
hello yourself
=> nil
This allows a reusable chunk of code to be passed around as an object that can be executed anywhere. Again, a little suitcase of Ruby code ready for travel in the reuse world!

def simpleMethod(aProc)
	puts "Is Ruby cool or what?"
	aProc.call("Way cool dude!")
=> nil
Is Ruby cool or what?
Way cool dude!

Thanks for your registration, follow us on our social networks to keep up-to-date