Ruby-on-Rails
  Home arrow Ruby-on-Rails arrow Page 3 - Exploring Iteration
Dev Articles Forums 
ADO.NET  
Apache  
ASP  
ASP.NET  
C#  
C++  
ColdFusion  
COM/COM+  
Delphi-Kylix  
Design Usability  
Development Cycles  
DHTML  
Embedded Tools  
Flash  
Graphic Design  
HTML  
IIS  
Interviews  
Java  
JavaScript  
MySQL  
Oracle  
Photoshop  
PHP  
Reviews  
Ruby-on-Rails  
SQL  
SQL Server  
Style Sheets  
VB.Net  
Visual Basic  
Web Authoring  
Web Services  
Web Standards  
XML  
Moblin 
JMSL Numerical Library 
IBM® developerWorks 
Sun Developer Network 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid 
Request Media Kit
Contact Us 
Site Map 
Privacy Policy 
Support 
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
RUBY-ON-RAILS

Exploring Iteration
By: O'Reilly Media
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: 5 stars5 stars5 stars5 stars5 stars / 1
    2007-03-15

    Table of Contents:
  • Exploring Iteration
  • 7.9 Looping Through Multiple Iterables in Parallel
  • 7.10 Hiding Setup and Cleanup in a Block Method
  • 7.11 Coupling Systems Loosely with Callbacks

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      Del.ici.ous Digg
      Blink Simpy
      Google Spurl
      Y! MyWeb Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article
     
     
    ADVERTISEMENT


    Exploring Iteration - 7.10 Hiding Setup and Cleanup in a Block Method


    (Page 3 of 4 )

    Problem

    You have a setup method that always needs to run before custom code, or a cleanup method that needs to run afterwards. You don’t trust the person writing the code (possibly yourself) to remember to call the setup and cleanup methods.

    Solution

    Create a method that runs the setup code, yields to a code block (which contains the custom code), then runs the cleanup code. To make sure the cleanup code always runs, even if the custom code throws an exception, use a begin/finally block.

      def between_setup_and_cleanup
        setup
        begin
        
    yield
        finally
          cleanup
        end
      end

    Here’s a concrete example. It adds a DOCTYPE and an HTML tag to the beginning of an HTML document. At the end, it closes the HTML tag it opened earlier. This saves you a little bit of work when you’re generating HTML files.

      def write_html(out, doctype=nil)
        doctype ||= %{<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
       
    "http://www.w3.org/TR/html4/loose.dtd">}
        out.puts doctype
        out.puts '<html>'
        begin
         
    yield out
        ensure
          out.puts '</html>'
        end
      end

      write_html($stdout) do |out|
       
    out.puts '<h1>Sorry, the Web is closed.</h1>'
      end
      # <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
      # "http://www.w3.org/TR/html4/loose.dtd">
      # <html>
      # <h1>Sorry, the Web is closed.</h1>
      # </html>

    Discussion

    This useful technique shows up most often when there are scarce resources (such as file handles or database connections) that must be closed when you’re done with them, lest they all get used up. A language that makes the programmer remember these resources tends to leak those resources, because programmers are lazy. Ruby makes it easy to be lazy and still do the right thing.

    You’ve probably used this technique already, with the theKernel#openandFile#openmethods for opening files on disk. These methods accept a code block that manipulates an already open file. They open the file, call your code block, and close the file once you’re done:

      open('output.txt', 'w') do |out|
        out.puts 'Sorry, the filesystem is also closed.'
      end

    Ruby’s standardcgimodule takes thewrite_htmlexample to its logical conclusion.* You can construct an entire HTML document by nesting blocks inside each other. Here’s a small Ruby CGI that outputs much the same document as thewrite_htmlexample above.

      #!/usr/bin/ruby

      # closed_cgi.rb

      require 'cgi'
      c = CGI.new("html4")
     

      c.out do
        c.html do
          c.h1 { 'Sorry, the Web is closed.' }
        end
      end

    Note the multiple levels of blocks: the block passed intoCGI#outsimply callsCGI#htmlto generate the DOCTYPE and the<html>tags. The<html>tags contain the result of a call toCGI#h1, which encloses some plain text in<h1>tags. The program produces this output:

      Content-Type: text/html
      Content-Length: 137

      <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" 
       "http://www.w3.org/TR/html4/strict.dtd">
      <HTML><h1>Sorry, the Web is closed.
    </H1></HTML>

    TheXmlMarkup class in Ruby’sbuildergem works the same way: you can write Ruby code that resembles the structure of the document it creates:

      require 'rubygems'
      require 'builder'
      xml = Builder::XmlMarkup.new.message('type' => 'apology') do |b|
       
    b.content('Sorry, Web Services are closed.')
      end
      puts xml
      # <message type="apology">
      #  <content>Sorry, Web Services are closed.</content>
      # </message>

    See Also

    1. Recipe 6.13, “Locking a File,” uses this technique to create a method that locks a file, and automatically unlocks it when you’re done using it
    2. Recipe 11.9, “Creating and Modifying XML Documents”
    3. Recipe 20.11, “Avoiding Deadlock,” uses this technique to have your thread lock multiple resources in the right order, and unlock them when you’re done using them

    More Ruby-on-Rails Articles
    More By O'Reilly Media


       · This article is an excerpt from the book "Ruby Cookbook," published by O'Reilly. We...
     

    Buy this book now. This article is excerpted from chapter eight of the Ruby Cookbook, written by Lucas Carlson and Leonard Richardson (O'Reilly, 2006; ISBN: 0596523696). Check it out today at your favorite bookstore. Buy this book now.

    RUBY-ON-RAILS ARTICLES

    - Iterating and Incrementing Strings in Ruby
    - Comparing and Manipulating Strings in Ruby
    - Strings in Ruby
    - Ruby On Rails: Making Your First Dynamic Site
    - Ruby on Rails: Beginning Rails
    - Ruby: Modules, Mixins, Fixins, and Rails
    - Controlling Information Access with the Rail...
    - URLs, Filters and the Rails Action Controller
    - Flash and the Rails Action Controller
    - Rails Action Controller
    - Dropping and Sorting with AJAX and script.ac...
    - Drag and Drop with script.aculo.us and Rails
    - Introducing script.aculo.us
    - Ruby Classes and Objects
    - Ruby Loops






    © 2003-2008 by Developer Shed. All rights reserved. DS Cluster 2 hosted by Hostway
    Stay green...Green IT