On-line Guides
All Guides
eBook Store
iOS / Android
Linux for Beginners
Office Productivity
Linux Installation
Linux Security
Linux Utilities
Linux Virtualization
Linux Kernel
Programming
Scripting Languages
Development Tools
Web Development
GUI Toolkits/Desktop
Databases
Mail Systems
openSolaris
Eclipse Documentation
Techotopia.com
Virtuatopia.com

How To Guides
Virtualization
Linux Security
Linux Filesystems
Web Servers
Graphics & Desktop
PC Hardware
Windows
Problem Solutions

Ruby Programming
Previous Page Home Next Page

### Making Blocks More Dynamic

We've already seen how you can associate a block with a method call.

 ```listBones("aardvark") do |aBone|   # ... end ```

Normally, this is perfectly good enough---you associate a fixed block of code with a method, in the same way you'd have a chunk of code after an `if` or `while` statement.

Sometimes, however, you'd like to be more flexible. For example, we may be teaching math skills.[Of course, Andy and Dave would have to learn math skills first. Conrad Schneiker reminded us that there are three kinds of people: those who can count and those who can't.] The student could ask for an n-plus table or an n-times table. If the student asked for a 2-times table, we'd output 2, 4, 6, 8, and so on. (This code does not check its inputs for errors.)

 ```print "(t)imes or (p)lus: " times = gets print "number: " number = gets.to_i if times =~ /^t/   puts((1..10).collect { |n| n*number }.join(", ")) else   puts((1..10).collect { |n| n+number }.join(", ")) end ```
produces:
 ```(t)imes or (p)lus: t number: 2 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 ```

This works, but it's ugly, with virtually identical code on each branch of the `if` statement. If would be nice if we could factor out the block that does the calculation.

 ```print "(t)imes or (p)lus: " times = gets print "number: " number = gets.to_i if times =~ /^t/   calc = proc { |n| n*number } else   calc = proc { |n| n+number } end puts((1..10).collect(&calc).join(", ")) ```
produces:
 ```(t)imes or (p)lus: t number: 2 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 ```

If the last argument to a method is preceded by an ampersand, Ruby assumes that it is a `Proc` object. It removes it from the parameter list, converts the `Proc` object into a block, and associates it with the method.

This technique can also be used to add some syntactic sugar to block usage. For example, you sometimes want to take an iterator and store each value it yields into an array. We'll reuse our Fibonacci number generator from page 40.

 `a = []` `fibUpTo(20) { |val| a << val }` � `nil` `a.inspect` � `"[1, 1, 2, 3, 5, 8, 13]"`

This works, but our intention isn't quite as transparent as we may like. Instead, we'll define a method called `into`, which returns the block that fills the array. (Notice at the same time that the block returned really is a closure---it references the parameter anArray even after method `into` has returned.)

 `def into(anArray)` `  return proc { |val| anArray << val }` `end` `fibUpTo 20, &into(a = [])` `a.inspect` � `"[1, 1, 2, 3, 5, 8, 13]"`

Ruby Programming
Previous Page Home Next Page

 Published under the terms of the Open Publication License Design by Interspire