Getting Started with Ruby: Iterators - Continued
Common Shortcut
A common pattern is to use an iterator to apply the exact
same method to each object in a collection. For
example:
['THE', 'RAIN'].map{|x| x.downcase } # => ["the", "rain"]
This pattern is so common you will often see a shortcut
used. It is possible to replace the block {|x|
x.downcase } with (&:downcase) to
save a few characters:
['THE', 'RAIN'].map(&:downcase) # => ["the", "rain"]
However, this shortcut does not work everywhere, but it
does work in Ruby on Rails. Whether or not to use this
shortcut is a matter of personal taste, but you will see it
used frequently.
Calculations
Another common pattern is to compute a calculation based
on the elements of a collection. For example, to find the
sum of a collection we can use the following loop:
sum = 0
[0,1,2,3,5].each do |i|
sum += i
end
sum # => 11
This block can be implemented in one line of Ruby code
using the inject method, borrowed from
Smalltalk.
[0,1,2,3,5].inject(0) {|s,i| s+i} # => 11
Jim Weirich provides the following tip to help remember
the name inject: think of the
inject method as injecting the provided
operator + into the collection. The
inject method is extremely powerful and can
used to implement the results of many common loops.
Disadvantages
By chaining iterators it is often possible to produce
complex behavior in a single line of Ruby code. In
addition, the resulting code is usually expressive and
readable. There is a disadvantage to this style of
programming: suboptimal performance.
For example, to find the least positive element of
[-1,2,-3,4,7,1] we used:
[-1,2,-3,4,7,1].select {|x| x > 0}.sort.first # => 1
In this example, the select method will
visit every element of the array [-1,2,-
3,4,7,1] and so will the sort method,
resulting in two loops over the entire collection. However,
it is possible to compute the same result by iterating over
the array only once. In most cases this performance penalty
is not worth the resulting reduction in code clarity, but it
is up to the developer to make this decision.
Further Reading
The common Ruby iterator methods used in practice are
implemented in the Enumerable module. Arrays
include the Enumerable module as do other collections such
as Hash and Set. Documentation for
the Enumerable` module can found at: http://www.ruby-
doc.org/core/classes/Enumerable.html.
Bio
Erik Andrejko is a web developer currently living in
Madison, WI where he enjoys sailing keelboats. He writes
about Ruby on Rails, web design and user experience at
http://railsillustrated.com and can be reached
aterik@railsillustrated.com or on Twitter as 'eandrejko'.
Ruby Iterators
Ruby Programming
|