<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>crunchlife: Category Code Snippets</title>
    <link>http://crunchlife.com/articles/category/code-snippets</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description></description>
    <item>
      <title>Installing Ruby 1.8 and 1.9 on Ubuntu from Source</title>
      <description>&lt;p&gt;&lt;img src="/files/ruby.png" class="right"&gt;I&amp;#8217;ve begun testing &lt;a href="http://crunchlife.com/articles/2008/07/03/ruby-fractal-library" target="_blank"&gt;my fractal library&lt;/a&gt; with the latest source code from the Ruby 1.9 trunk. Since 1.9 is a development release and I still need 1.8 for my Rails applications, I&amp;#8217;ve checked out both versions and configured them to run side-by-side on Ubuntu, Hardy Heron.&lt;/p&gt;

&lt;p&gt;Before you begin, make sure you have the autoconf, build-essential, and subversion packages installed.&lt;/p&gt;

&lt;p&gt;It may also be a good idea to include the Ruby1.8 and Ruby1.9 build dependencies from Ubuntu&amp;#8217;s package repository. This could prevent some headaches later on.&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;$ sudo apt-get build-dep ruby1.8 ruby1.9&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Create a directory for the Ruby source code.&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;$ mkdir /home/ryan/source
$ cd /home/ryan/source&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Check out the code from the 1.8 branch. Since this branch includes patches, you can always update your source and recompile when new patches are released.&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;$ svn co http://svn.ruby-lang.org/repos/ruby/branches/ruby_1_8 ruby1.8&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Next, create a configuration, configure, and compile.&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;$ cd ruby1.8
$ autoconf
$ ./configure --prefix=/opt/ruby1.8 --program-suffix=1.8
$ sudo make
$ sudo make install&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;One of the best parts of Ruby is &lt;a href="http://www.rubygems.org/" target="_blank"&gt;Rubygems&lt;/a&gt;! Download and install it. &lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;$ wget http://rubyforge.org/frs/download.php/38646/rubygems-1.2.0.tgz
$ tar -xvzf rubygems-1.2.0.tgz
$ cd rubygems-1.2.0
$ sudo ruby1.8 setup.rb&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Finally, link your new binaries to the /usr/local/bin directory.&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;$ sudo ln -s /opt/ruby1.8/bin/* /usr/local/bin&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Typing ruby1.8 -v in your console should yield something similar to the following:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;$ ruby1.8 -v
ruby 1.8.7 (2008-09-15 revision 19348) [i686-linux]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The current source for Ruby 1.9 requires version 1.8 to compile, but if you&amp;#8217;ve followed my directions up to this point you should be ready to download and compile the latest Ruby 1.9 source code. &lt;/p&gt;

&lt;p&gt;Go back to your source directory and check out the latest code from the 1.9 trunk.&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;$ cd /home/ryan/source
$ svn co http://svn.ruby-lang.org/repos/ruby/trunk ruby1.9
$ cd ruby1.9&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This time use the &amp;#8211;with-baseruby switch when configuring. Set this option to the new Ruby 1.8 binary and then compile.&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;$ autoconf
$ ./configure --with-baseruby=/usr/local/bin/ruby1.8 --prefix=/opt/ruby1.9 --program-suffix=1.9
$ sudo make
$ sudo make install&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Finish by linking your new Ruby 1.9 binaries to /usr/local/bin.&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;$ sudo ln -s /opt/ruby1.9/bin/* /usr/local/bin&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Typing ruby1.9 -v in your console should yield something similar to the following:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;$ ruby1.9 -v
ruby 1.9.0 (2008-09-15 revision 19351) [i686-linux]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Ruby 1.9 includes Rubygems! We&amp;#8217;re done!&lt;/p&gt;

&lt;p&gt;Since the binaries we&amp;#8217;ve created have been suffixed with either 1.8 or 1.9, you must remember to execute them with their proper name ie (gem1.8, gem1.9, ruby1.8, ri1.9).&lt;/p&gt;

&lt;p&gt;I&amp;#8217;ve written these instructions from memory so if you have any problems, please post them and I&amp;#8217;ll try to help out as best I can. Please be warned, however, that not all code written for Ruby 1.8 will work in 1.9.&lt;/p&gt;</description>
      <pubDate>Sun, 14 Sep 2008 13:30:00 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:122f8a10-a010-40fb-9010-b102dc451ac3</guid>
      <author>Ryan Baxter</author>
      <link>http://crunchlife.com/articles/2008/09/14/installing-ruby-1-8-and-1-9-on-ubuntu-from-source</link>
      <category>Code Snippets</category>
      <category>Ruby</category>
      <category>Ubuntu</category>
    </item>
    <item>
      <title>Yet Another Join Method</title>
      <description>&lt;p&gt;The .NET String type has a &lt;a href="http://msdn.microsoft.com/en-us/library/57a79xd0.aspx" target="_blank"&gt;Join method&lt;/a&gt;, but in my latest ASP.NET project I had the need for joining String array elements with additional prefix and suffix values. The method below delimits array elements with the provided separator and concatenates the elements with the prefix and suffix string parameters.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;ve found this particularly handy when creating SQL statements that require the IN keyword.&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;string[] names = { &amp;quot;Bobby&amp;quot;, &amp;quot;Suzy&amp;quot; };

sql += &amp;quot;WHERE People.FirstName IN (&amp;quot; + Utility.Join(&amp;quot;,&amp;quot;, names, &amp;quot;'&amp;quot;, &amp;quot;'&amp;quot;) + &amp;quot;)&amp;quot;;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Add this method to your utility class or extended String type.&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;public static string Join(string separator, string[] value, string
prefix, string suffix)
{
    string toReturn = String.Empty;

    int i;
    for (i = 0; i &amp;lt; value.Length; i++)
    {
        if (i != value.Length - 1)
            toReturn += prefix + value[i] + suffix + separator;
        else
            toReturn += prefix + value[i] + suffix;
    }

    return toReturn;
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
      <pubDate>Fri, 12 Sep 2008 14:27:00 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:05392c66-db31-4f67-80a6-e73740c41523</guid>
      <author>Ryan Baxter</author>
      <link>http://crunchlife.com/articles/2008/09/12/yet-another-join-method</link>
      <category>Code Snippets</category>
      <category>CSharp</category>
      <category>dotNET</category>
    </item>
    <item>
      <title>Using LoginView on HyperLinkFields within a GridView</title>
      <description>&lt;p&gt;&lt;img src="/files/aspnet.gif" class="right"&gt;The title of this post is a bit misleading. Using a LoginView to manage the security of HyperLinkFields within a GridView does not work. There are, however, other means to achieve the same result.&lt;/p&gt;

&lt;p&gt;Using the GridView&amp;#8217;s OnRowDataBound event, I&amp;#8217;ve set my Cells containing HyperLinkFields, on DataRows with a RowIndex of -1, to an empty string if the user does not belong to the &amp;#8220;Administrators&amp;#8221; role. This hides my HyperLinkFields from underprivileged users and prevents elements of my GridView&amp;#8217;s header and footer from not appearing.&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;protected void GridView1_OnRowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowIndex != -1)
    {
        if (!Page.User.IsInRole(&amp;quot;Administrators&amp;quot;))        
            e.Row.Cells[0].Text = String.Empty;
    }           
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;*Update&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I just found a &lt;a href="http://forums.asp.net/t/943849.aspx" target="_blank"&gt;thread&lt;/a&gt; on the ASP.NET forums that covers the same problem. In their solution, the GridView&amp;#8217;s RowType is checked before setting the Cell&amp;#8217;s Visibility property to false. This makes more sense than relying on the RowIndex property to determine whether or not a DataRow&amp;#8217;s Cell should be hidden. In the method below, I&amp;#8217;ve integrated the DataControlRowType enumeration as suggested by the ASP.NET forums. Since setting the Visibility property of Cells containing HyperLinkFields caused my GridView headings to not line up properly, I decided to assign the Cell&amp;#8217;s Text property to String.Empty as in my previous example.&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;protected void GridView1_OnRowDataBound(object sender, GridViewRowEventArgs e)
{                  
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        if (!Page.User.IsInRole(&amp;quot;Administrators&amp;quot;))
            e.Row.Cells[0].Text = String.Empty;
    }   
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
      <pubDate>Wed, 13 Aug 2008 12:45:00 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:95cccc69-ac5a-417a-aa72-8d64168cd1ab</guid>
      <author>Ryan Baxter</author>
      <link>http://crunchlife.com/articles/2008/08/13/using-loginview-on-hyperlinkfields-within-a-gridview</link>
      <category>Code Snippets</category>
      <category>ASPNET</category>
      <enclosure type="image/gif" url="http://crunchlife.com/files/aspnet.gif" length="3597"/>
    </item>
    <item>
      <title>Removing Duplicate Items from an Abstract Generic List</title>
      <description>&lt;p&gt;&lt;img src="/files/rocking_chair.jpg" class="right" /&gt;I&amp;#8217;ve got some explaining to do. I
was hesitant in posting this code for fear that it might be too niche
to benefit anyone. It may be, but the underlying problem affects many
programmers working in the IT industry. What do you do when the company
legacy system&amp;#8217;s data model doesn&amp;#8217;t work with your fancy &lt;a href="http://en.wikipedia.org/wiki/Object-relational_mapping" target="_blank"&gt;ORM (Object-relational mapping)&lt;/a&gt;?&lt;/p&gt;

&lt;blockquote&gt;
&amp;#8220;Any problem in computer science can be solved with another layer of indirection. But that usually will create another problem.&amp;#8221; - &lt;a href="http://en.wikipedia.org/wiki/David_Wheeler_(computer_scientist)" target="_blank"&gt;David Wheeler&lt;/a&gt;
&lt;/blockquote&gt;

&lt;p&gt;At my last job, the &lt;a href="http://en.wikipedia.org/wiki/Enterprise_resource_planning" target="_blank"&gt;ERP (Enterprise resource planning)&lt;/a&gt; system was something of mystery and voodoo. Only a few had sufficient knowledge to work with it and because of its arcane nature it was deemed untouchable. Within my first months as an employee I wrote a rudimentary ORM to serve as a layer between our client applications and the ERP system. Its performance was terrible. I wrote it off as &amp;#8220;experience&amp;#8221; and the department ultimately decided to ignore interfacing directly with the ERP system.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;m using the &lt;a href="http://subsonicproject.com/" target="_blank"&gt;SubSonic&lt;/a&gt; ORM on a few ASP.NET projects with my current employer. SubSonic has worked great, but a
few of its database requirements have left me in the dust with yet another ERP system. The ERP&amp;#8217;s tables have no primary keys, constraints, or relationships, but rather than write a complete ORM I decided to roll my own data layer.&lt;/p&gt;

&lt;p&gt;All of the strongly-typed collections in the ERP&amp;#8217;s data layer implement the AbstractList type. AbstractList implements List&lt;ItemType&gt; where ItemType implements IUniqueIdentifier. That is a mouthful, but the key (pun intended) to removing duplicate items is to make sure they&amp;#8217;re unique.&lt;/p&gt;

&lt;p&gt;The IUniqueIdentifier interface contains only one property, UniqueIdentifier.&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;public interface IUniqueIdentifier
{
    string UniqueIdentifier
    {
        get;
        set;
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; 

&lt;p&gt;If the ERP system contained a table called Customers a Customer type implementing IUniqueIdentifier would be created. &lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;public class Customer : IUniqueIdentifier
{
    private string uniqueIdentifier;

    // etc...

    public UniqueIdentifier
    {
        get { return this.uniqueIdentifier; }
        set { this.uniqueIdentifier = value; }
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I&amp;#8217;d also have a CustomerCollection class:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;public class CustomerCollection : AbstractList&amp;lt;Customer, CustomerCollection&amp;gt;
{
    // etc...
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;After such a long-winded introduction I can feel better about dumping the following code on anyone that has happened to read this far (kudos to you).&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;public abstract class AbstractList&amp;lt;ItemType, ListType&amp;gt; :
List&amp;lt;ItemType&amp;gt; where ItemType:IUniqueIdentifier where
ListType:AbstractList&amp;lt;ItemType, ListType&amp;gt;, new()
{
    public ListType RemoveDuplicates()
    {
        Dictionary&amp;lt;string, int&amp;gt; uniqueStore = new Dictionary&amp;lt;string, int&amp;gt;();
        ListType list = new ListType();

        foreach (ItemType item in this)
        {
            if (!uniqueStore.ContainsKey(item.UniqueIdentifier))
            {
                uniqueStore.Add(item.UniqueIdentifier, 0);
                list.Add(item);
            }
        }

        return list;
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I&amp;#8217;d love to hear how others have worked around legacy systems and still kept their code clean. &lt;/p&gt;</description>
      <pubDate>Thu, 31 Jul 2008 07:40:00 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:f418da7f-eb68-46f7-9192-6c8254e39b4f</guid>
      <author>Ryan Baxter</author>
      <link>http://crunchlife.com/articles/2008/07/31/removing-duplicate-items-from-an-abstract-generic-list</link>
      <category>Code Snippets</category>
      <category>Expect the Unexpected</category>
      <category>CSharp</category>
      <category>dotNET</category>
      <category>ORM</category>
      <enclosure type="image/jpeg" url="http://crunchlife.com/files/rocking_chair.jpg" length="61497"/>
      <trackback:ping>http://crunchlife.com/articles/trackback/75</trackback:ping>
    </item>
    <item>
      <title>Ruby Fractal Library</title>
      <description>&lt;p&gt;&lt;img src="/files/mandelbrot1.png" class="photo right"&gt;Last October, I wrote a small &lt;a href="http://crunchlife.com/articles/2007/10/30/code-snippet-ruby-walks-with-shoes" target="_blank"&gt;fractal rendering program&lt;/a&gt; in Ruby using the &lt;a href="http://code.whytheluckystiff.net/shoes/" target="_blank"&gt;Shoes&lt;/a&gt; windowing toolkit written by &lt;a href="http://en.wikipedia.org/wiki/Why_the_lucky_stiff" target="_blank"&gt;why the lucky stiff&lt;/a&gt;. It&amp;#8217;s sole purpose was to test Shoes. The code was painfully slow at rendering the Mandelbrot set, but it did, however, begin a small obsession of mine with fractals. &lt;/p&gt;

&lt;p&gt;Since I couldn&amp;#8217;t find a fractal library for Ruby, I decided to write one. Over the last two weeks I&amp;#8217;ve written some code to generate both the &lt;a href="http://en.wikipedia.org/wiki/Mandelbrot_set" target="_blank"&gt;Mandelbrot&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Julia_set" target="_blank"&gt;Julia set&lt;/a&gt; fractals using the escape time algorithm. The code is still slow, but within a couple weeks I hope to replace the slow portions with inline C.&lt;/p&gt;

&lt;p&gt;There may still be some bugs and I haven&amp;#8217;t added any error handling, but here it is. An &amp;#8220;almost&amp;#8221; pure Ruby fractal library. Once this is cleaned up I&amp;#8217;ll repost the code. I suppose a gem could be possible as well. Happy 4th!&lt;/p&gt;

&lt;p&gt;&lt;a href="/files/fractals.rb"&gt;fractals.rb&lt;/a&gt;&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="comment"&gt;# RB&lt;/span&gt;

&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;rubygems&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;complex&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;png&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;

&lt;span class="keyword"&gt;module &lt;/span&gt;&lt;span class="module"&gt;Fractals&lt;/span&gt;
  &lt;span class="keyword"&gt;module &lt;/span&gt;&lt;span class="module"&gt;Fractal&lt;/span&gt;
    &lt;span class="ident"&gt;attr_accessor&lt;/span&gt; &lt;span class="symbol"&gt;:begin_range&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:end_range&lt;/span&gt;

    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;initialize&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;begin_range&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;end_range&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
      &lt;span class="attribute"&gt;@begin_range&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="attribute"&gt;@end_range&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;begin_range&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;end_range&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;draw&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;height&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt;&lt;span class="number"&gt;250&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;width&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt;&lt;span class="number"&gt;250&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;m&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt;&lt;span class="number"&gt;1.0&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;save_as&lt;/span&gt;&lt;span class="punct"&gt;='&lt;/span&gt;&lt;span class="string"&gt;fractal.png&lt;/span&gt;&lt;span class="punct"&gt;')&lt;/span&gt;
        &lt;span class="ident"&gt;canvas&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;PNG&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Canvas&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;height&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;width&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;

        &lt;span class="comment"&gt;# Find the complex coordinate for each pixel.&lt;/span&gt;
        &lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;upto&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;height&lt;/span&gt; &lt;span class="punct"&gt;-&lt;/span&gt; &lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;y&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
          &lt;span class="ident"&gt;i&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;y&lt;/span&gt; &lt;span class="punct"&gt;*&lt;/span&gt; &lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="attribute"&gt;@end_range&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;image&lt;/span&gt; &lt;span class="punct"&gt;-&lt;/span&gt; &lt;span class="attribute"&gt;@begin_range&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;image&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="punct"&gt;/&lt;/span&gt; &lt;span class="ident"&gt;height&lt;/span&gt; &lt;span class="punct"&gt;+&lt;/span&gt;
          &lt;span class="attribute"&gt;@begin_range&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;image&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="punct"&gt;*&lt;/span&gt; &lt;span class="ident"&gt;m&lt;/span&gt;
          &lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;upto&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;width&lt;/span&gt; &lt;span class="punct"&gt;-&lt;/span&gt; &lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;x&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
            &lt;span class="ident"&gt;r&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;x&lt;/span&gt; &lt;span class="punct"&gt;*&lt;/span&gt; &lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="attribute"&gt;@end_range&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;real&lt;/span&gt; &lt;span class="punct"&gt;-&lt;/span&gt; &lt;span class="attribute"&gt;@begin_range&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;real&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="punct"&gt;/&lt;/span&gt; &lt;span class="ident"&gt;width&lt;/span&gt; &lt;span class="punct"&gt;+&lt;/span&gt;
            &lt;span class="attribute"&gt;@begin_range&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;real&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="punct"&gt;*&lt;/span&gt; &lt;span class="ident"&gt;m&lt;/span&gt;
            &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="constant"&gt;self&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;in_set?&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="constant"&gt;Complex&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;r&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;i&lt;/span&gt;&lt;span class="punct"&gt;))&lt;/span&gt; &lt;span class="keyword"&gt;then&lt;/span&gt;
              &lt;span class="ident"&gt;canvas&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="ident"&gt;x&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;y&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;PNG&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Color&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Black&lt;/span&gt;
            &lt;span class="keyword"&gt;else&lt;/span&gt;
              &lt;span class="ident"&gt;canvas&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="ident"&gt;x&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;y&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;fetch_color&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="constant"&gt;self&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;last_iteration&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="constant"&gt;self&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;max_iterations&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
            &lt;span class="keyword"&gt;end&lt;/span&gt;                    
          &lt;span class="punct"&gt;}&lt;/span&gt;
        &lt;span class="punct"&gt;}&lt;/span&gt;

        &lt;span class="ident"&gt;png&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;PNG&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;canvas&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
        &lt;span class="ident"&gt;png&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;save&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;save_as&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;  

    &lt;span class="ident"&gt;private&lt;/span&gt;
    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;fetch_color&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;last_iteration&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;max_iterations&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;  
      &lt;span class="ident"&gt;divisor&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="number"&gt;765&lt;/span&gt;&lt;span class="punct"&gt;*&lt;/span&gt;&lt;span class="ident"&gt;last_iteration&lt;/span&gt;&lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="ident"&gt;max_iterations&lt;/span&gt;
      &lt;span class="keyword"&gt;case&lt;/span&gt; &lt;span class="ident"&gt;divisor&lt;/span&gt;
        &lt;span class="keyword"&gt;when&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;..&lt;/span&gt;&lt;span class="number"&gt;254&lt;/span&gt; &lt;span class="keyword"&gt;then&lt;/span&gt; &lt;span class="keyword"&gt;return&lt;/span&gt; &lt;span class="constant"&gt;PNG&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Color&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;divisor&lt;/span&gt;&lt;span class="punct"&gt;%&lt;/span&gt;&lt;span class="number"&gt;255&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;255&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
        &lt;span class="keyword"&gt;when&lt;/span&gt; &lt;span class="number"&gt;255&lt;/span&gt;&lt;span class="punct"&gt;..&lt;/span&gt;&lt;span class="number"&gt;509&lt;/span&gt; &lt;span class="keyword"&gt;then&lt;/span&gt; &lt;span class="keyword"&gt;return&lt;/span&gt; &lt;span class="constant"&gt;PNG&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Color&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="number"&gt;255&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;divisor&lt;/span&gt;&lt;span class="punct"&gt;%&lt;/span&gt;&lt;span class="number"&gt;255&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;255&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
        &lt;span class="keyword"&gt;when&lt;/span&gt; &lt;span class="number"&gt;510&lt;/span&gt;&lt;span class="punct"&gt;..&lt;/span&gt;&lt;span class="number"&gt;765&lt;/span&gt; &lt;span class="keyword"&gt;then&lt;/span&gt; &lt;span class="keyword"&gt;return&lt;/span&gt; &lt;span class="constant"&gt;PNG&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Color&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="number"&gt;255&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;255&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;divisor&lt;/span&gt;&lt;span class="punct"&gt;%&lt;/span&gt;&lt;span class="number"&gt;255&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;255&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
      &lt;span class="keyword"&gt;end&lt;/span&gt;       
    &lt;span class="keyword"&gt;end&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;Julia&lt;/span&gt;
    &lt;span class="ident"&gt;include&lt;/span&gt; &lt;span class="constant"&gt;Fractal&lt;/span&gt;
    &lt;span class="ident"&gt;attr_accessor&lt;/span&gt; &lt;span class="symbol"&gt;:seed&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:bailout&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:max_iterations&lt;/span&gt;
    &lt;span class="ident"&gt;attr_reader&lt;/span&gt; &lt;span class="symbol"&gt;:last_iteration&lt;/span&gt;

    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;initialize&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;seed&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt;&lt;span class="constant"&gt;Complex&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="number"&gt;0.36&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;0.1&lt;/span&gt;&lt;span class="punct"&gt;),&lt;/span&gt; &lt;span class="ident"&gt;bailout&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt;&lt;span class="number"&gt;2&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;max_iterations&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt;&lt;span class="number"&gt;100&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt;
    &lt;span class="ident"&gt;begin_range&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt;&lt;span class="constant"&gt;Complex&lt;/span&gt;&lt;span class="punct"&gt;(-&lt;/span&gt;&lt;span class="number"&gt;2.25&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;-&lt;/span&gt;&lt;span class="number"&gt;1.5&lt;/span&gt;&lt;span class="punct"&gt;),&lt;/span&gt; &lt;span class="ident"&gt;end_range&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt;&lt;span class="constant"&gt;Complex&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="number"&gt;0.75&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;1.5&lt;/span&gt;&lt;span class="punct"&gt;))&lt;/span&gt;
      &lt;span class="keyword"&gt;super&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;begin_range&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;end_range&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
      &lt;span class="attribute"&gt;@seed&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="attribute"&gt;@bailout&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="attribute"&gt;@max_iterations&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;seed&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;bailout&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;max_iterations&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;in_set?&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;z&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
      &lt;span class="attribute"&gt;@max_iterations&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;times&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;i&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
        &lt;span class="ident"&gt;z&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;z&lt;/span&gt;&lt;span class="punct"&gt;**&lt;/span&gt;&lt;span class="number"&gt;2&lt;/span&gt; &lt;span class="punct"&gt;+&lt;/span&gt; &lt;span class="attribute"&gt;@seed&lt;/span&gt;
        &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;z&lt;/span&gt; &lt;span class="punct"&gt;&amp;gt;&lt;/span&gt; &lt;span class="attribute"&gt;@bailout&lt;/span&gt; &lt;span class="keyword"&gt;then&lt;/span&gt;
          &lt;span class="attribute"&gt;@last_iteration&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;i&lt;/span&gt;
          &lt;span class="keyword"&gt;return&lt;/span&gt; &lt;span class="constant"&gt;false&lt;/span&gt;
        &lt;span class="keyword"&gt;end&lt;/span&gt;      
      &lt;span class="punct"&gt;}&lt;/span&gt;
      &lt;span class="keyword"&gt;return&lt;/span&gt; &lt;span class="constant"&gt;true&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;Mandelbrot&lt;/span&gt;
    &lt;span class="ident"&gt;include&lt;/span&gt; &lt;span class="constant"&gt;Fractal&lt;/span&gt;  
    &lt;span class="ident"&gt;attr_accessor&lt;/span&gt; &lt;span class="symbol"&gt;:bailout&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:max_iterations&lt;/span&gt;
    &lt;span class="ident"&gt;attr_reader&lt;/span&gt; &lt;span class="symbol"&gt;:last_iteration&lt;/span&gt;

    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;initialize&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;bailout&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt;&lt;span class="number"&gt;5&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;max_iterations&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt;&lt;span class="number"&gt;100&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;begin_range&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt;&lt;span class="constant"&gt;Complex&lt;/span&gt;&lt;span class="punct"&gt;(-&lt;/span&gt;&lt;span class="number"&gt;2.25&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt;
    &lt;span class="punct"&gt;-&lt;/span&gt;&lt;span class="number"&gt;1.5&lt;/span&gt;&lt;span class="punct"&gt;),&lt;/span&gt; &lt;span class="ident"&gt;end_range&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt;&lt;span class="constant"&gt;Complex&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="number"&gt;0.75&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;1.5&lt;/span&gt;&lt;span class="punct"&gt;))&lt;/span&gt;
      &lt;span class="keyword"&gt;super&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;begin_range&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;end_range&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
      &lt;span class="attribute"&gt;@bailout&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="attribute"&gt;@max_iterations&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;bailout&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;max_iterations&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;in_set?&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;c&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
      &lt;span class="ident"&gt;z&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;
      &lt;span class="attribute"&gt;@max_iterations&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;times&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;i&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
        &lt;span class="ident"&gt;z&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;z&lt;/span&gt;&lt;span class="punct"&gt;**&lt;/span&gt;&lt;span class="number"&gt;2&lt;/span&gt; &lt;span class="punct"&gt;+&lt;/span&gt; &lt;span class="ident"&gt;c&lt;/span&gt;
        &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;z&lt;/span&gt; &lt;span class="punct"&gt;&amp;gt;&lt;/span&gt; &lt;span class="attribute"&gt;@bailout&lt;/span&gt; &lt;span class="keyword"&gt;then&lt;/span&gt;
          &lt;span class="attribute"&gt;@last_iteration&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;i&lt;/span&gt;
          &lt;span class="keyword"&gt;return&lt;/span&gt; &lt;span class="constant"&gt;false&lt;/span&gt;
        &lt;span class="keyword"&gt;end&lt;/span&gt;            
      &lt;span class="punct"&gt;}&lt;/span&gt;
      &lt;span class="keyword"&gt;return&lt;/span&gt; &lt;span class="constant"&gt;true&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Using this library is as simple as the following:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;fractals&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;

&lt;span class="ident"&gt;mandelbrot&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Fractals&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Mandelbrot&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;
&lt;span class="ident"&gt;mandelbrot&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;draw&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Any suggestions/bug fixes can be posted here. Thanks.&lt;/p&gt;</description>
      <pubDate>Thu, 03 Jul 2008 14:26:00 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:c65638d5-d30a-4340-a3f4-34b9ec4eb55f</guid>
      <author>Ryan Baxter</author>
      <link>http://crunchlife.com/articles/2008/07/03/ruby-fractal-library</link>
      <category>Code Snippets</category>
      <category>Ruby</category>
      <category>Fractals</category>
      <enclosure type="image/png" url="http://crunchlife.com/files/mandelbrot1.png" length="9532"/>
      <trackback:ping>http://crunchlife.com/articles/trackback/70</trackback:ping>
    </item>
    <item>
      <title>IE7's Inanimate GIF</title>
      <description>&lt;p&gt;Animated GIFs are most often used as activity indicators in modern &lt;a
href="http://en.wikipedia.org/wiki/Ajax_(programming)"
target="_blank"&gt;AJAX (asynchronous JavaScript and XML)&lt;/a&gt; enabled
websites. I decided to use a &lt;a
href="http://en.wikipedia.org/wiki/Gif" target="_blank"&gt;GIF (Graphic
Interchange Format)&lt;/a&gt; from &lt;a href="http://www.ajaxload.info/"
target="_blank"&gt;ajaxload.info&lt;/a&gt; on an application that I&amp;#8217;ve been
developing at work. The application performs server-side
processing on files uploaded by employees. Processing time varies depending on the size of the file. Larger files take longer.&lt;/p&gt;

&lt;p&gt;I wanted the animated GIF to appear when the file upload button was clicked so I placed the image within a &lt;a href="http://www.w3schools.com/tags/tag_DIV.asp" target="_blank"&gt;DIV&lt;/a&gt; tag and hid it by setting a blank &lt;a href="http://www.w3schools.com/css/pr_class_display.asp" target="_blank"&gt;CSS display property&lt;/a&gt;. OnClick of the upload button, a
JavaScript function toggled the display value to &amp;#8220;block&amp;#8221;, making the DIV appear. This worked as
expected in &lt;a href="http://www.mozilla.com/en-US/firefox/?utm_id=Q108&amp;amp;utm_source=google&amp;amp;utm_medium=ppc&amp;amp;gclid=CPnY35q27JMCFQtvGgodcnzhWg" target="_blank"&gt;Firefox&lt;/a&gt; and IE6, but not in IE7. The DIV appeared in IE7,
but it&amp;#8217;s GIF wasn&amp;#8217;t moving.&lt;/p&gt;

&lt;p&gt;A little googling turned up a helpful comment on &lt;a href="http://west-wind.com/WebLog/default.aspx" target="_blank"&gt;Rick Strahl&amp;#8217;s blog&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
I&amp;#8217;ve run into a problem with animated gifs inside of a hidden area of a Web page that is hidden with style.display=&amp;#8217;none&amp;#8217;. When the area is made visible again, in Internet Explorer this causes the image to not be displayed an animated GIF whatever I try. [sic] 
&lt;/blockquote&gt;

&lt;p&gt;Apparently IE7 doesn&amp;#8217;t like to animate hidden GIFs. User submitted comments on Rick Strahl&amp;#8217;s blog provided many solutions, but only a couple worked in my situation. The first uses the JavaScript setTimeout method to populate the image&amp;#8217;s SRC attribute 200 ms after the function call. The second sets the DIV&amp;#8217;s innerHTML to a string containing an &lt;a href="http://www.w3schools.com/tags/tag_IMG.asp" target="_blank"&gt;IMG&lt;/a&gt; tag with the animated GIF.&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;&amp;lt;script language='javascript'&amp;gt; 
    function ShowLoading(elementId) 
    {
        document.getElementById(elementId).style.display = &amp;quot;block&amp;quot;; 
        setTimeout('document.images[&amp;quot;loadingImage&amp;quot;].src = &amp;quot;../images/loading.gif&amp;quot;', 200); 
    } 
&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Neither solution is ideal, but setting the element&amp;#8217;s innerHTML felt a little bit cleaner to me.&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;&amp;lt;script language='javascript'&amp;gt;
    function ShowLoading(elementId)
    {   
        var element = document.getElementById(elementId);    

        element.innerHTML = &amp;quot;&amp;lt;img src='../images/loading.gif'&amp;gt;&amp;quot;;    
        element.style.display = &amp;quot;block&amp;quot;;
    }
&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;
*IE7 may have animations disabled. Go to Tools &gt; Internet Options &gt; Advanced &gt; Multimedia. Checking &amp;#8220;Play animations in webpages&amp;#8221; may affect how IE7 renders your animated GIFs.
&lt;/strong&gt;&lt;/p&gt;</description>
      <pubDate>Wed, 11 Jun 2008 05:06:00 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:a2283586-36cd-4064-8291-8155c59f2cf9</guid>
      <author>Ryan Baxter</author>
      <link>http://crunchlife.com/articles/2008/06/11/ie7s-inanimate-gif</link>
      <category>Code Snippets</category>
      <category>Expect the Unexpected</category>
      <category>ASPNET</category>
      <category>JavaScript</category>
      <trackback:ping>http://crunchlife.com/articles/trackback/68</trackback:ping>
    </item>
    <item>
      <title>Samba Network Shares with Nautilus in Hardy Heron Part 2</title>
      <description>&lt;p&gt;&lt;img src="/files/ubuntu_logo.png" class="right"&gt;Nearly a month ago I wrote about my &lt;a href="http://crunchlife.com/articles/2008/04/28/samba-network-shares-with-nautilus-in-hardy-heron" target="_blank"&gt;problems connecting to the network shares&lt;/a&gt; of my &lt;a href="http://crunchlife.com/articles/2007/08/03/review-linksys-nas200" target="_blank"&gt;Linksys NAS200&lt;/a&gt; using Nautilus in Ubuntu, Hardy Heron. My fix was simple and it worked. Unfortunately, the solution&amp;#8217;s &lt;a href="http://en.wikipedia.org/wiki/Woman_acceptance_factor" target="_blank"&gt;WAF (Wife Acceptance Factor)&lt;/a&gt; was low. Apparently she didn&amp;#8217;t think it was easy enough to execute smbmount from a Terminal window. Whatever :) I have since written a small shell script that is called from Session Startup.&lt;/p&gt;

&lt;p&gt;Initially, the script failed to connect to my network shares because my wireless network connection hadn&amp;#8217;t finished negotiating before the script was executed. I coded around this by creating a while loop that &lt;a href="http://en.wikipedia.org/wiki/Grep#Usage_as_a_conversational_verb" target="_blank"&gt;greps&lt;/a&gt; the output of a ping to my router. If successful, the mount_shares function is called. Otherwise. the thread will sleep for 10 seconds and try again.&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;#!/bin/bash

user=&amp;quot;thorbardin/ryan%password&amp;quot;
root_dir=&amp;quot;/home/ryan/Network Shares&amp;quot;

mount_shares() {
  public_dir=&amp;quot;$root_dir&amp;quot;/&amp;quot;Public on Thorbardin&amp;quot;
  home_dir=&amp;quot;$root_dir&amp;quot;/&amp;quot;Home on Thorbardin&amp;quot;

  [ -d &amp;quot;$public_dir&amp;quot; ] || mkdir -p &amp;quot;$public_dir&amp;quot;
  [ -d &amp;quot;$home_dir&amp;quot; ] || mkdir -p &amp;quot;$home_dir&amp;quot;

  smbmount &amp;quot;//192.168.1.105/public disk&amp;quot; &amp;quot;$public_dir&amp;quot; -o user=&amp;quot;$user&amp;quot;
  smbmount &amp;quot;//192.168.1.105/ryan&amp;quot; &amp;quot;$home_dir&amp;quot; -o user=&amp;quot;$user&amp;quot;
}

while [ 1 ]; do
  if ping -c2 192.168.1.1 2&amp;gt;&amp;amp;1 | grep ttl; then
    mount_shares

    exit 0   
  fi
  sleep 10
done

exit 0&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I&amp;#8217;m already thinking about rewriting this script so that it scans my network using &lt;a href="http://www.menet.umn.edu/docs/software/samba/3.0.14a/help/smbtree.1.html" target="_blank"&gt;smbtree&lt;/a&gt; and automatically mounts all available network shares. That&amp;#8217;ll be Part 3!&lt;/p&gt;</description>
      <pubDate>Sun, 01 Jun 2008 16:07:00 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:d387ed9b-c3b3-469c-8052-8514021774bc</guid>
      <author>Ryan Baxter</author>
      <link>http://crunchlife.com/articles/2008/06/01/samba-network-shares-with-nautilus-in-hardy-heron-part-2</link>
      <category>Code Snippets</category>
      <category>NAS</category>
      <category>Ubuntu</category>
      <category>Oops</category>
      <category>Bash</category>
      <trackback:ping>http://crunchlife.com/articles/trackback/67</trackback:ping>
    </item>
    <item>
      <title>Temporary Identity Impersonation in ASP.NET</title>
      <description>&lt;p&gt;Uploading files in an ASP.NET application is relatively easy to do. Uploading to a remote machine is a little bit trickier, but certainly doable. I followed a &lt;a href="http://aspalliance.com/336_Upload_Files_Using_ASPNET_Impersonation_and_UNC_Share.all" target="_blank"&gt;set of instructions&lt;/a&gt; on aspalliance.com, but rather than declare an account to impersonate in my web.config file, I decided to do it in code. That way I could use impersonation only when needed and encapsulate it for later use.&lt;/p&gt;

&lt;p&gt;I referred to an &lt;a href="http://support.microsoft.com/kb/306158#4" target="_blank"&gt;article&lt;/a&gt; on Microsoft&amp;#8217;s Help and Support website about how to implement impersonation. Their code worked great, but I decided to put it in a class to help keep things &lt;a href="http://en.wikipedia.org/wiki/DRY" target="_blank"&gt;DRY&lt;/a&gt;.&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;using System;
using System.Web;
using System.Web.Security;
using System.Security.Principal;
using System.Runtime.InteropServices;

namespace Utilities
{    
    public class ImpersonateUser
    {
        public const int LOGON32_LOGON_INTERACTIVE = 2;
        public const int LOGON32_PROVIDER_DEFAULT = 0;

        WindowsImpersonationContext impersonationContext;

        [DllImport(&amp;quot;advapi32.dll&amp;quot;)]
        public static extern int LogonUserA(String lpszUserName,
            String lpszDomain,
            String lpszPassword,
            int dwLogonType,
            int dwLogonProvider,
            ref IntPtr phToken);
        [DllImport(&amp;quot;advapi32.dll&amp;quot;, CharSet = CharSet.Auto, SetLastError = true)]
        public static extern int DuplicateToken(IntPtr hToken,
            int impersonationLevel,
            ref IntPtr hNewToken);

        [DllImport(&amp;quot;advapi32.dll&amp;quot;, CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool RevertToSelf();

        [DllImport(&amp;quot;kernel32.dll&amp;quot;, CharSet = CharSet.Auto)]
        public static extern bool CloseHandle(IntPtr handle);

        public bool ImpersonateValidUser(String userName, String domain, String password)
        {
            WindowsIdentity tempWindowsIdentity;
            IntPtr token = IntPtr.Zero;
            IntPtr tokenDuplicate = IntPtr.Zero;

            if (RevertToSelf())
            {
                if (LogonUserA(userName, domain, password, LOGON32_LOGON_INTERACTIVE,
                    LOGON32_PROVIDER_DEFAULT, ref token) != 0)
                {
                    if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
                    {
                        tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
                        impersonationContext = tempWindowsIdentity.Impersonate();
                        if (impersonationContext != null)
                        {
                            CloseHandle(token);
                            CloseHandle(tokenDuplicate);
                            return true;
                        }
                    }
                }
            }
            if (token != IntPtr.Zero)
                CloseHandle(token);
            if (tokenDuplicate != IntPtr.Zero)
                CloseHandle(tokenDuplicate);
            return false;
        }

        public void UndoImpersonation()
        {
            impersonationContext.Undo();
        }
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;After referencing my Utilities namespace I was then able to impersonate the account required for uploading:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;if (FileUpload1.HasFile)
{
    ImpersonateUser impersonateUser = new ImpersonateUser();

    if (impersonateUser.ImpersonateValidUser(&amp;quot;userName&amp;quot;, &amp;quot;&amp;quot;, &amp;quot;password&amp;quot;))
    {
        FileUpload1.SaveAs(Server.MapPath(&amp;quot;~/files/fileName.txt&amp;quot;));
        impersonateUser.UndoImpersonation();
    }
    else
    {
        throw new Exception(&amp;quot;Identity impersonation has failed.&amp;quot;);
    }   
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;*The SaveAs method of the FileUpload control requires a root path. Using Server.MapPath will provide the root path of your IIS virtual folder.&lt;/strong&gt;&lt;/p&gt;</description>
      <pubDate>Tue, 27 May 2008 09:01:00 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:9aea73ef-a3d1-4208-9128-12eb032da707</guid>
      <author>Ryan Baxter</author>
      <link>http://crunchlife.com/articles/2008/05/27/temporary-identity-impersonation-in-asp-net</link>
      <category>Code Snippets</category>
      <category>ASPNET</category>
      <category>dotNET</category>
      <enclosure type="image/jpeg" url="http://crunchlife.com/files/lock.jpg" length="60658"/>
      <trackback:ping>http://crunchlife.com/articles/trackback/66</trackback:ping>
    </item>
    <item>
      <title>A Few Date Methods</title>
      <description>&lt;p&gt;An ASP.NET project of mine recently required the calculation of the start and end date of the current date&amp;#8217;s previous month. This was more difficult putting into words than code.  It did, however, get me thinking about other common date routines.&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;public static DateTime FirstDayOfPreviousMonth
{
    get
    {
        return new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1).AddMonths(-1);
    }    
}

public static DateTime LastDayOfPreviousMonth
{
    get
    {
        return new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1).AddDays(-1);
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Being preemptive, I decided to include a few methods for determining the start and end date of the current date&amp;#8217;s fiscal quarter. I started by calculating the current date&amp;#8217;s quarter. This was accomplished with just a little division.&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;public static int CurrentQuarter
{
    get
    {
        return (DateTime.Now.Month + 2) / 3;
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Finding the start and end dates of the current quarter was harder, but could still be expressed in a single line of code (or two).&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;public static DateTime FirstDayOfCurrentQuarter
{
    get
    {
        return new DateTime(DateTime.Now.Year, 1 + ((CurrentQuarter - 1) * 3), 1);
    }
}

public static DateTime LastDayOfCurrentQuarter
{
    get
    {
        int lastMonthOfCurrentQuarter = 3 + ((CurrentQuarter - 1) * 3);

        return new DateTime(DateTime.Now.Year, lastMonthOfCurrentQuarter, DateTime.DaysInMonth(DateTime.Now.Year, lastMonthOfCurrentQuarter));
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I&amp;#8217;d like to extend this collection to include other common date routines. Feel free to post your date methods as comments if you&amp;#8217;d like to share.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;*The methods I&amp;#8217;ve created for calculating the current quarter&amp;#8217;s start and end dates assume the fiscal year starts on January 1st. This may not be suitable for your needs.&lt;/strong&gt;&lt;/p&gt;</description>
      <pubDate>Tue, 06 May 2008 11:45:00 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:0f4f646c-7a7d-42c8-b6b1-306d40200836</guid>
      <author>Ryan Baxter</author>
      <link>http://crunchlife.com/articles/2008/05/06/a-few-date-methods</link>
      <category>Code Snippets</category>
      <category>dotNET</category>
      <category>CSharp</category>
      <enclosure type="image/jpeg" url="http://crunchlife.com/files/clock.jpg" length="22591"/>
    </item>
    <item>
      <title>Setting Focus in ASP.NET Ajax Pages</title>
      <description>&lt;p&gt;&lt;a href="http://www.amazon.com/gp/product/B000YJ2OJ2?ie=UTF8&amp;amp;tag=crunchlife-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=B000YJ2OJ2"&gt;&lt;img border="0" src="/files/316ZntjzQ2L._AA_SL160_.jpg" class="photo right"&gt;&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=crunchlife-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=B000YJ2OJ2" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /&gt;At the new job I&amp;#8217;ve been using a lot of &lt;a href="http://www.asp.net/ajax/" target="_blank"&gt;ASP.NET Ajax&lt;/a&gt; to help ease the transition of users from &lt;a href="http://en.wikipedia.org/wiki/VB6" target="_blank"&gt;VB6&lt;/a&gt; desktop applications to web applications on our company &lt;a href="http://en.wikipedia.org/wiki/Intranet" target="_blank"&gt;intranet&lt;/a&gt;. In doing this, the UpdatePanel has become my new best friend. Albeit charming, my old ASP.NET 2.0 friends were not as impressed.&lt;/p&gt;

&lt;p&gt;With ASP.NET 2.0, came the long-awaited &lt;a href="http://aspnet.4guysfromrolla.com/articles/111506-1.aspx" target="_blank"&gt;Focus&lt;/a&gt; method that allowed developers to set the page focus without having to write any JavaScript. Developers loved it and all was right with the world. That is until ASP.NET Ajax showed up.&lt;/p&gt;

&lt;p&gt;I recently spent way too much time trying set the page focus on a page that contained just a few TextBox controls and an UpdatePanel. My site&amp;#8217;s ScriptManager was located in a MasterPage, but more on that later. My obligatory googling turned up many work arounds, but none as simple as the following:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;// Example

if (Page.IsPostback)
{   
    // Use the GetCurrent method if your ScriptManager is located
    // in a MasterPage. Word.
    ScriptManager.GetCurrent(this.Page).SetFocus(TextBox1);
}
else
{
    // Here is the money.
    AjaxControlToolkit.Utility.SetFocusOnLoad(TextBox2);
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The above example is a two-fer. The ScriptManager&amp;#8217;s SetFocus method is handy, but remember that only one ScriptManager is allowed per page and if you&amp;#8217;ve put your ScriptManager in a MasterPage, then you&amp;#8217;ll need to access it in code using the GetCurrent method of the ScriptManager class. &lt;/p&gt;

&lt;p&gt;Two. The ASP.NET 2.0 UpdatePanel is not the only Ajax control. Download the &lt;a href="http://www.codeplex.com/Wiki/View.aspx?ProjectName=AtlasControlToolkit" target="_blank"&gt;ASP.NET Ajax Control Toolkit&lt;/a&gt;. With this toolkit, you&amp;#8217;ll have access to dozens of controls and best of all &amp;#8211; the SetFocusOnLoad method. Located in the Utility class, the SetFocusOnLoad method is the answer to your !Page.IsPostback problems.&lt;/p&gt;</description>
      <pubDate>Mon, 31 Mar 2008 15:24:00 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:a059a73f-ed79-457f-9df5-24ab32e0fdd7</guid>
      <author>Ryan Baxter</author>
      <link>http://crunchlife.com/articles/2008/03/31/setting-focus-in-asp-net-ajax-pages</link>
      <category>Code Snippets</category>
      <category>ASPNET</category>
      <category>Ajax</category>
      <category>Oops</category>
      <enclosure type="image/jpeg" url="http://crunchlife.com/files/316ZntjzQ2L._AA_SL160_.jpg" length="9085"/>
      <trackback:ping>http://crunchlife.com/articles/trackback/52</trackback:ping>
    </item>
    <item>
      <title>Code Snippet: Ruby Walks with Shoes</title>
      <description>&lt;p&gt;&lt;img src="/files/shoes-icon.png" class="right"&gt;&lt;a href="http://en.wikipedia.org/wiki/Why_the_lucky_stiff" target="_blank"&gt;_Why&lt;/a&gt; of &lt;a href="http://www.poignantguide.net/ruby/" target="_blank"&gt;Why&amp;#8217;s (Poignant) Guide to Ruby&lt;/a&gt; has announced the publication of a 52 page comic style &lt;a href="http://www.lulu.com/content/1365064" target="_blank"&gt;book&lt;/a&gt; illustrating the ins and outs of his new windowing toolkit, &lt;a href="http://code.whytheluckystiff.net/shoes/" target="_blank"&gt;Shoes&lt;/a&gt;.  In his words, &amp;#8220;Shoes is a very informal graphics and windowing toolkit. It&amp;#8217;s for making regular old apps that run on Windows, Mac OS X and Linux. It&amp;#8217;s a blend of my favorite things from the Web, some Ruby style, and a sprinkling of cross-platform widgets.&amp;#8221;&lt;/p&gt;

&lt;p&gt;Using the the latest Shoes revision, I&amp;#8217;ve written some code to generate a &lt;a href="http://en.wikipedia.org/wiki/Mandelbrot_set" target="_blank"&gt;Mandelbrot fractal&lt;/a&gt;.  Try it out with the following command (assuming your script is located in the Shoes samples directory):&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;./shoes samples/mandelbrot.rb&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You may want to go make a sandwich while you wait.  Here is a sample of the output:&lt;/p&gt;

&lt;p&gt;&lt;center&gt;&lt;img src="/files/mandelbrot.png"&gt;&lt;/center&gt;&lt;/p&gt;

&lt;p&gt;Here is the code:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="comment"&gt;# RB&lt;/span&gt;

&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;complex&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;

&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;Mandelbrot&lt;/span&gt;  
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;initialize&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;bailout&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt;&lt;span class="number"&gt;10&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;iterations&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt;&lt;span class="number"&gt;100&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="attribute"&gt;@bailout&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="attribute"&gt;@iterations&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;bailout&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;iterations&lt;/span&gt;   
  &lt;span class="keyword"&gt;end&lt;/span&gt;  

  &lt;span class="comment"&gt;# A method for determining if a point is within&lt;/span&gt;
  &lt;span class="comment"&gt;# the Mandelbrot set.&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;in_set?&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;x&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;y&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="ident"&gt;c&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Complex&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;x&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;y&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="ident"&gt;z&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;
    &lt;span class="attribute"&gt;@iterations&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;times&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;i&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
      &lt;span class="ident"&gt;z&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;z&lt;/span&gt;&lt;span class="punct"&gt;**&lt;/span&gt;&lt;span class="number"&gt;2&lt;/span&gt; &lt;span class="punct"&gt;+&lt;/span&gt; &lt;span class="ident"&gt;c&lt;/span&gt;                       
      &lt;span class="keyword"&gt;return&lt;/span&gt; &lt;span class="constant"&gt;false&lt;/span&gt; &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;z&lt;/span&gt; &lt;span class="punct"&gt;&amp;gt;&lt;/span&gt; &lt;span class="attribute"&gt;@bailout&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;
    &lt;span class="keyword"&gt;return&lt;/span&gt; &lt;span class="constant"&gt;true&lt;/span&gt; 
  &lt;span class="keyword"&gt;end&lt;/span&gt;  
&lt;span class="keyword"&gt;end&lt;/span&gt;

&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;Generator&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt; &lt;span class="constant"&gt;Shoes&lt;/span&gt;
  &lt;span class="ident"&gt;url&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;/&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="symbol"&gt;:index&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;index&lt;/span&gt;&lt;span class="punct"&gt;()&lt;/span&gt;    
    &lt;span class="ident"&gt;render&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="number"&gt;250&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;250&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;rgb&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="number"&gt;205&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;102&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;))&lt;/span&gt;    
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;render&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;height&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt;&lt;span class="number"&gt;250&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;width&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt;&lt;span class="number"&gt;250&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;color&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt;&lt;span class="ident"&gt;rgb&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="number"&gt;255&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;))&lt;/span&gt;
    &lt;span class="ident"&gt;nostroke&lt;/span&gt;
    &lt;span class="ident"&gt;fill&lt;/span&gt; &lt;span class="ident"&gt;color&lt;/span&gt;   

    &lt;span class="ident"&gt;mandelbrot&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Mandelbrot&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;

    &lt;span class="comment"&gt;# Render the fractal.&lt;/span&gt;
    &lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;upto&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;height&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;y&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
      &lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;upto&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;width&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;x&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
        &lt;span class="ident"&gt;scaled_x&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;-&lt;/span&gt;&lt;span class="number"&gt;2&lt;/span&gt; &lt;span class="punct"&gt;+&lt;/span&gt; &lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="number"&gt;3&lt;/span&gt; &lt;span class="punct"&gt;*&lt;/span&gt; &lt;span class="ident"&gt;x&lt;/span&gt; &lt;span class="punct"&gt;/&lt;/span&gt; &lt;span class="ident"&gt;width&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;to_f&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
        &lt;span class="ident"&gt;scaled_y&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="number"&gt;1&lt;/span&gt; &lt;span class="punct"&gt;+&lt;/span&gt; &lt;span class="punct"&gt;(-&lt;/span&gt;&lt;span class="number"&gt;2&lt;/span&gt; &lt;span class="punct"&gt;*&lt;/span&gt; &lt;span class="ident"&gt;y&lt;/span&gt; &lt;span class="punct"&gt;/&lt;/span&gt; &lt;span class="ident"&gt;height&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;to_f&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
        &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;mandelbrot&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;in_set?&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;scaled_x&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;scaled_y&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="keyword"&gt;then&lt;/span&gt;        
          &lt;span class="ident"&gt;rect&lt;/span&gt; &lt;span class="symbol"&gt;:left&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ident"&gt;x&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:top&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ident"&gt;y&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:width&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:height&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="number"&gt;1&lt;/span&gt;
          &lt;span class="comment"&gt;# oval :left =&amp;gt; x, :top =&amp;gt; y, :radius =&amp;gt; 1, :center =&amp;gt; true                           &lt;/span&gt;
        &lt;span class="keyword"&gt;end&lt;/span&gt;      
      &lt;span class="keyword"&gt;end&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;

&lt;span class="constant"&gt;Shoes&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;app&lt;/span&gt; &lt;span class="symbol"&gt;:title&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;Mandelbrot&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="symbol"&gt;:height&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="number"&gt;250&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:width&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="number"&gt;250&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
      <pubDate>Tue, 30 Oct 2007 07:30:00 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:d741a6d4-d9eb-4068-893b-e5ce494f7920</guid>
      <author>Ryan Baxter</author>
      <link>http://crunchlife.com/articles/2007/10/30/code-snippet-ruby-walks-with-shoes</link>
      <category>Code Snippets</category>
      <category>Ruby</category>
      <enclosure type="image/png" url="http://crunchlife.com/files/shoes-icon.png" length="6771"/>
    </item>
    <item>
      <title>Code Snippet: Ruby Image Scraper</title>
      <description>&lt;p&gt;I stumbled upon a &lt;a href="http://en.wikipedia.org/wiki/Screen_scraping" target="_blank"&gt;screen scraping&lt;/a&gt; library for Ruby last week called &lt;a href="http://blog.labnotes.org/2006/07/11/scraping-with-style-scrapi-toolkit-for-ruby/" target="_blank"&gt;scrAPI&lt;/a&gt;.  It&amp;#8217;s extremely flexible and can be seen in action on the &lt;a href="http://co.mments.com/" target="_blank"&gt;co.mments&lt;/a&gt; blog post scraper.  The scrAPI library can be installed by issuing the following command from your console:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;gem install scrapi&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Testing scrAPI was fairly easy once I figured out how to define a scraper.  With that aside, I wrote a small script that saves images from a URL provided by the user.  The scrAPI library could be used for good or evil, but only you can decide.   &lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="comment"&gt;#!/usr/bin/ruby&lt;/span&gt;

&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;fileutils&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;open-uri&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;pathname&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;rubygems&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;scrapi&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;

&lt;span class="comment"&gt;# Get the URL input.&lt;/span&gt;
&lt;span class="ident"&gt;puts&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;Enter a URL:&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;span class="ident"&gt;url&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;gets&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;chomp&lt;/span&gt;

&lt;span class="comment"&gt;# Get the HTML source.&lt;/span&gt;
&lt;span class="ident"&gt;html&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;nil&lt;/span&gt;
&lt;span class="ident"&gt;open&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;url&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="punct"&gt;{|&lt;/span&gt;&lt;span class="ident"&gt;source&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="ident"&gt;html&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;source&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;read&lt;/span&gt;&lt;span class="punct"&gt;()}&lt;/span&gt;

&lt;span class="comment"&gt;# Define the scraper.&lt;/span&gt;
&lt;span class="ident"&gt;scraper&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Scraper&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;define&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
  &lt;span class="ident"&gt;array&lt;/span&gt; &lt;span class="symbol"&gt;:images&lt;/span&gt;
  &lt;span class="ident"&gt;process&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;img&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:images&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;@src&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
  &lt;span class="ident"&gt;result&lt;/span&gt; &lt;span class="symbol"&gt;:images&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;

&lt;span class="comment"&gt;# Scrape the HTML for images.&lt;/span&gt;
&lt;span class="ident"&gt;images&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;scraper&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;scrape&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;html&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;

&lt;span class="comment"&gt;# Create a directory to save the images in.&lt;/span&gt;
&lt;span class="ident"&gt;directory&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;url&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;gsub&lt;/span&gt;&lt;span class="punct"&gt;(/&lt;/span&gt;&lt;span class="regex"&gt;http:&lt;span class="escape"&gt;\/\/&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;/,&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;&lt;/span&gt;&lt;span class="punct"&gt;')&lt;/span&gt;
&lt;span class="constant"&gt;FileUtils&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;mkdir&lt;/span&gt; &lt;span class="ident"&gt;directory&lt;/span&gt;

&lt;span class="ident"&gt;images&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;each&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;image_path&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
  &lt;span class="comment"&gt;# Determine if image_path is absolute or relative. &lt;/span&gt;
  &lt;span class="ident"&gt;path&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Pathname&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;image_path&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;  
  &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="keyword"&gt;not&lt;/span&gt; &lt;span class="ident"&gt;path&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;relative?&lt;/span&gt; &lt;span class="keyword"&gt;then&lt;/span&gt; &lt;span class="ident"&gt;image_path&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;url&lt;/span&gt; &lt;span class="punct"&gt;+&lt;/span&gt; &lt;span class="ident"&gt;image_path&lt;/span&gt; &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="comment"&gt;# Write the image to disk.&lt;/span&gt;
  &lt;span class="ident"&gt;open&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;image_path&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;source&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
    &lt;span class="ident"&gt;file_name&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;image_path&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;split&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;/&lt;/span&gt;&lt;span class="punct"&gt;').&lt;/span&gt;&lt;span class="ident"&gt;last&lt;/span&gt;
    &lt;span class="ident"&gt;open&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;directory&lt;/span&gt; &lt;span class="punct"&gt;+&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;/&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="punct"&gt;+&lt;/span&gt; &lt;span class="ident"&gt;file_name&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;wb&lt;/span&gt;&lt;span class="punct"&gt;')&lt;/span&gt; &lt;span class="punct"&gt;{|&lt;/span&gt;&lt;span class="ident"&gt;file&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="ident"&gt;file&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;write&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;source&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;read&lt;/span&gt;&lt;span class="punct"&gt;())}&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;

&lt;span class="ident"&gt;puts&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;Finished...&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
      <pubDate>Mon, 13 Aug 2007 20:46:00 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:f2568aba-5b0b-4ca4-b4c7-f1f47c11d88d</guid>
      <author>Ryan Baxter</author>
      <link>http://crunchlife.com/articles/2007/08/13/code-snippet-ruby-image-scraper</link>
      <category>Code Snippets</category>
      <category>Ruby</category>
    </item>
    <item>
      <title>Code Snippet: Ruby Word Masher</title>
      <description>&lt;p&gt;I can be extremely indecisive about things.  So much, in fact, that I even wrote a script to help me choose a name for this website.  Is it strange that a &lt;a href="http://en.wikipedia.org/wiki/Random_number_generator"&gt;random number generator&lt;/a&gt; can make me feel better about making decisions?  My wife thinks I&amp;#8217;m crazy, but she also calls domain names, donames.  Besides, I think there is something novel in a computer choosing a name for itself.  Anyway&amp;#8230;  Given some user input, the code below will read words from a file and then mash them together to provide unique combinations.  Here is a &lt;a href="/files/words.dat" target="_blank"&gt;words.dat&lt;/a&gt; file to help get you started.  Happy mashing.&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="comment"&gt;#!/usr/bin/ruby&lt;/span&gt;

&lt;span class="ident"&gt;words&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Array&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;
&lt;span class="ident"&gt;i&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;

&lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;mash_words&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;words&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;mash_count&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
  &lt;span class="ident"&gt;new_word&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;

  &lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;upto&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;mash_count&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
    &lt;span class="ident"&gt;new_word&lt;/span&gt; &lt;span class="punct"&gt;+=&lt;/span&gt; &lt;span class="ident"&gt;words&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="ident"&gt;rand&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;words&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;length&lt;/span&gt;&lt;span class="punct"&gt;)]&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="keyword"&gt;return&lt;/span&gt; &lt;span class="ident"&gt;new_word&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;

&lt;span class="keyword"&gt;begin&lt;/span&gt;
  &lt;span class="ident"&gt;puts&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;How many mashed words would you like to create?&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
  &lt;span class="ident"&gt;word_count&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;gets&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;chomp&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;to_i&lt;/span&gt;  

  &lt;span class="ident"&gt;puts&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;How many words would you like to mash?&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
  &lt;span class="ident"&gt;mash_count&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;gets&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;chomp&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;to_i&lt;/span&gt;  

  &lt;span class="ident"&gt;input_file&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;File&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;(&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;words.dat&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;r&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;)&lt;/span&gt;
  &lt;span class="keyword"&gt;while&lt;/span&gt; &lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;line&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;input_file&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;gets&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;    
    &lt;span class="ident"&gt;words&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="ident"&gt;i&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;line&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;chomp&lt;/span&gt;    
    &lt;span class="ident"&gt;i&lt;/span&gt; &lt;span class="punct"&gt;+=&lt;/span&gt; &lt;span class="number"&gt;1&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;  

  &lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;upto&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;word_count&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;    
    &lt;span class="ident"&gt;puts&lt;/span&gt; &lt;span class="ident"&gt;mash_words&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;words&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;mash_count&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;  

  &lt;span class="ident"&gt;input_file&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;close&lt;/span&gt;  
&lt;span class="keyword"&gt;rescue&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ident"&gt;err&lt;/span&gt;
  &lt;span class="ident"&gt;puts&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;Exception: &lt;span class="expr"&gt;#{err}&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
  &lt;span class="ident"&gt;err&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
      <pubDate>Sat, 28 Jul 2007 13:54:00 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:489d4ec9-5bce-4e51-af6d-e3365a0af8e3</guid>
      <author>Ryan Baxter</author>
      <link>http://crunchlife.com/articles/2007/07/28/code-snippet-ruby-word-masher</link>
      <category>Code Snippets</category>
      <category>Ruby</category>
      <category>crunchlife</category>
      <enclosure type="chemical/x-mopac-input" url="http://crunchlife.com/files/words.dat" length="239"/>
    </item>
    <item>
      <title>Code Snippet: Fibonacci with IronRuby &amp;amp; WPF</title>
      <description>&lt;p&gt;On Tuesday, John Lam &lt;a href="http://www.iunknown.com/2007/07/a-first-look-at.html"&gt;announced&lt;/a&gt; the Pre-Alpha Release of IronRuby.  To satisfy my curiosity, I downloaded and compiled the source code found on his blog.  A simple Build.cmd file was provided and made the compilation a breeze.  Rather than write another Hello World, I decided to kick the tires by writing a simple application to calculate &lt;a href="http://en.wikipedia.org/wiki/Fibonacci_number"&gt;Fibonacci numbers&lt;/a&gt;.  I didn&amp;#8217;t use many of the niceties that make Ruby what it is, but I did, however, uncover some oddities between Ruby and .NET types.  I coded around a few of the problems only to find other features that were either broken or missing.  The release was labeled &#8220;Pre-Alpha&#8221; for a reason so don&amp;#8217;t be surprised if you have a similar experience with IronRuby.&lt;/p&gt;

&lt;p&gt;I have to admit that I felt a bit dirty hacking together bits of the Windows Presentation Foundation (WPF) with Ruby only to achieve a single, ugly window with one text box, some words, and a button.  It wouldn&amp;#8217;t have been so bad if only I could have managed to use the .NET HorizontalAlignment enumeration with the controls on my window.  Every effort I made in aligning a control caused an Exception.  Defining the Orientation of my StackPanel also resulted in an Exception.  Taking input was easy.  Performing validation on the input was not.  I could not get a string comparison to work between .NET and Ruby string types.  I tried a half dozen combinations of .ToString, to_s, and Convert.ToString with no success.  I gave up and wrapped my problem expression in a begin-rescue block.&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="keyword"&gt;begin&lt;/span&gt;
  &lt;span class="ident"&gt;fibonacci_label&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;content&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;fetch_iterative_fibonacci&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="constant"&gt;Convert&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;ToInt32&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;input_text_box&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;Text&lt;/span&gt;&lt;span class="punct"&gt;)).&lt;/span&gt;&lt;span class="ident"&gt;to_s&lt;/span&gt; 
&lt;span class="keyword"&gt;rescue&lt;/span&gt;
  &lt;span class="constant"&gt;MessageBox&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;show&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;Please enter an integer.&lt;/span&gt;&lt;span class="punct"&gt;')&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If Microsoft creating their own implementation of Ruby isn&amp;#8217;t interesting enough, John Lam has said that IronRuby will be hosted at RubyForge.  His reason for this is simple.  John believes that Open Source developers have more experience using Subversion rather than Microsoft&amp;#8217;s Team Foundation Server.  I agree and believe this decision will only benefit IronRuby by involving the whole Ruby community.  This will most likely cause those non-Microsoft developers to contribute who otherwise wouldn&amp;#8217;t if the project were hosted at CodePlex.  Check out episode &lt;a href="http://www.dotnetrocks.com/default.aspx?showNum=254"&gt;254&lt;/a&gt; of .NET Rocks! for more on this and John Lam&amp;#8217;s work on IronRuby and the Dynamic Language Runtime.&lt;/p&gt;

&lt;p&gt;I am not disappointed with the status of this release.  Since IronRuby will be open for community contribution, the code will be reviewed by many eyes and the bugs that I did encounter will be fixed quickly.  The integration of IronRuby and WPF was not pleasant, but I do believe that over time the two technologies could compliment each other nicely.  The power of the presentation foundation combined with Ruby&amp;#8217;s syntax sugar will undoubtedly make for an impressive stack that could give others a run for their money.  Now can I have this in Mono please?&lt;/p&gt;

&lt;p&gt;Both an iterative and recursive solution can be found within my source.  I provided both in the odd chance that somebody reading this might want to try a rudimentary O(2^n) performance test between the Ruby interpretor and IronRuby.  The source code for my Fibonacci example can be downloaded from the links below.&lt;/p&gt;

&lt;p&gt;&lt;a href="/files/Fibonacci.tar.gz"&gt;Fibonacci.tar.gz&lt;/a&gt;&lt;br /&gt;
&lt;a href="/files/Fibonacci.zip"&gt;Fibonacci.zip&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Wed, 25 Jul 2007 21:28:00 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:49ef81bb-2fa7-4ea4-a192-2e63932308cd</guid>
      <author>Ryan Baxter</author>
      <link>http://crunchlife.com/articles/2007/07/25/code-snippet-fibonacci-with-ironruby-wpf</link>
      <category>Code Snippets</category>
      <category>Ruby</category>
    </item>
  </channel>
</rss>
