<html> <head> <title>Ruby FAQ: Iterators </title> </head> <body> <a href="rubyfaq-2.html">Previous</a> <a href="rubyfaq-4.html">Next</a> <a href="rubyfaq.html#toc3">Table of contents</a> <hr> <h2><a name="s3">3. Iterators </a></h2> <h2><a name="ss3.1">3.1 What is an iterator? </a></h2> Those methods which utilize a block or a Proc object are called iterators. <br><br> Iterators are used for abstraction of control structures especially loops. <br><br> Let's look at an example to see what it is. Iterators are often used to repeat the same action on each element of a collection, like this: <blockquote><code><pre> data = [1, 2, 3] data.each do |i| print i, "\n" end </pre></code></blockquote> This script yields this output. <blockquote><code><pre> $ ruby test.rb 1 2 3 </pre></code></blockquote> That is, the block between <code>do</code> and <code>end</code> is repeatedly executed on each element of an array "data". <br><br> Writing in C gives this code. <blockquote><code><pre> int data[3] = {1, 2, 3}; int i; for (i = 0; i < 3; i++) { printf("%d\n", data[i]); } </pre></code></blockquote> You must be very careful on the boundary condition when using "for". You are free from such bugs with an iterator. <br><br> In place of <code>do</code>...<code>end</code>, you can use <code>{</code>...<code>}</code>. <blockquote><code><pre> data = [1, 2, 3] data.each { |i| print i, "\n" } </pre></code></blockquote> This code has the same meaning as the last example. In some cases <code>do</code>...<code>end</code> and <code>{</code>...<code>}</code> act differently. <blockquote><code><pre> foobar a, b do .. end # foobar is the iterator. foobar a, b { .. } # b is the iterator. </pre></code></blockquote> This is because <code>{ }</code> attaches stronger to the preceding expression than a <code>do</code> block. <h2><a name="ss3.2">3.2 How can I pass a block to an iterator? </a></h2> Other than to place a block after an iterator, you can pass a Proc object by prepending & to the variable or constant that refer the Proc object. <h2><a name="ss3.3">3.3 How is a block used in an iterator? </a></h2> There are three ways to execute a block from an iterator method, namely, <code>yield</code> control structure, a block argument, and <code>Proc.new</code>. ( <code>rb_yield</code> is used in C extension library.) <br><br> The <code>yield</code> statement may have arguments which are passed to the block as block parameters and the block is executed. <br><br> A block argument appears as the last formal argument with & prepended in the iterator method arguments list. The block is called by <code>method.call(args...)</code> form. <br><br> <code>Proc.new</code>, when used in an iterator definition, takes the block which is given to the method as its argument, generates a procedure object generated from the block. The same applies to <code>proc</code> and <code>lambda</code>. <blockquote><code><pre> def a (&b) yield b.call Proc.new.call proc.call lambda.call end a{print "test\n"} </pre></code></blockquote> <h2><a name="ss3.4">3.4 What does <code>Proc.new</code> without a block do? </a></h2> <code>Proc.new</code> without a block cannot generate a procedure object and an error occurs. In a method definition, <code>Proc.new</code> without a block implies the existence of a block given by the method call. <hr> <a href="rubyfaq-2.html">Previous</a> <a href="rubyfaq-4.html">Next</a> <a href="rubyfaq.html#toc3">Table of contents</a> </body> <html>