Design Pattern: Iterator Pattern
The Iterator Pattern is something that is so common in Ruby that it seems odd that it merits its own pattern. What the Iterator pattern does is provide us with a way to “access the elements of an aggregate object sequentially” (Design Patterns in Ruby, 27). The most common appearance of it in Ruby is the humble but powerful each
method that we call on arrays and hashes. The each method is an internal iterator that takes a block of code (inside the do-end
or the {}
symbols). For example samplearray.each {|n|print "#{n}"}
would print out each element of an array.
The each
method is an internal iterator because we pass the action down into the array and the array calls the code block for each item. All of the action takes place internally.
An external iterator is one in which the client drives the call to the next object, as opposed to when we call the each
method and the block goes through each item until it gets to the end. Another advantage of the external iterator is that they can be reused and passed around, but it adds in a layer of complexity that can also be dangerous.
There is one big danger in using both internal and external iterators, and that is if the aggregate object were to change while you’re iterating through it. The easy solution is to make a shallow copy of the aggregate object- that way there is an exact snapshot to iterate through.