<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">
 
  <title type="text">smuby: simply - marvellous - ruby</title>
  <subtitle type="html">Dedicated to the promotion of the Ruby programming language and some fabulous creations built with it</subtitle>
  
  <link href="http://smuby.org/" />
  <updated>2008-08-04T16:26:04+01:00</updated>
  <author>
    <name>Chris Duncan</name>
    <email>celldee@smuby.org</email>
  </author>
  <id>http://smuby.org/</id>
  
  <geo:lat>51.798357</geo:lat><geo:long>0.638568</geo:long><link rel="license" type="text/html" href="http://creativecommons.org/licenses/by-sa/3.0/" /><link rel="self" href="http://feeds.feedburner.com/smuby" type="application/atom+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><entry>
    <title>PDF Seafood Sauce: Prawn</title>
    <link href="http://feedproxy.google.com/~r/smuby/~3/ciN4l_ltE20/pdf_seafood_sauce_prawn.html" />
    <id>tag:smuby.org,2008-07-30:1217426301</id>
    <updated>2008-07-30T14:58:21+01:00</updated>
<content type="html">
&lt;div class="span-14"&gt;
&lt;p&gt;&lt;img src="http://smuby.org/images/prawn.jpg" title="A prawn" alt="A prawn" /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="photo_credit span-14"&gt;&lt;a href="http://www.sxc.hu/profile/leomm"&gt;PHOTO CREDIT: courtesy of leomm at sxc.hu&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;The Ruby community is privileged to have a number of very valuable utility libraries. One of these is the venerable &lt;a href="http://ruby-pdf.rubyforge.org/pdf-writer/"&gt;PDF::Writer&lt;/a&gt;, which enables the production of .pdf files with Ruby methods. Unfortunately, PDF::Writer has performance issues that can make it excruciatingly slow. The time has come for new contenders to step into the Ruby PDF ring and one of the most promising is named &lt;a href="http://prawn.lighthouseapp.com/projects/9398/home"&gt;Prawn&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This is what the Prawn project page says -&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Prawn is a PDF writing library for Ruby. It aims to be fast, tiny, and nimble, like the majestic sea creature.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Prawn is a beneficiary of the &lt;a href="http://rubymendicant.wikidot.com/"&gt;Ruby Mendicant&lt;/a&gt; project and is being driven, to a large degree, by the needs of the &lt;a href="http://rubyreports.org/"&gt;Ruport&lt;/a&gt; reporting toolset which is looking for a credible alternative to its dependency on PDF::Writer. Progress is pretty swift with a &lt;a href="http://github.com/"&gt;GitHub&lt;/a&gt; &lt;a href="http://github.com/sandal/prawn/tree/master"&gt;repository&lt;/a&gt; aiding the development effort.&lt;/p&gt;
&lt;p&gt;In a recent &lt;a href="http://www.oreillynet.com/ruby/blog/2008/07/ruby_mendicant_permian_prawn.html"&gt;article&lt;/a&gt;, Gregory Brown provided this example of PDF::Writer code vs Prawn code&lt;/p&gt;
&lt;p class="code_title"&gt;PDF::Writer&lt;/p&gt;
&lt;div class="UltraViolet"&gt;&lt;pre class="sunburst"&gt;&lt;span class="line-numbers"&gt;   1 &lt;/span&gt; 
&lt;span class="line-numbers"&gt;   2 &lt;/span&gt; pdf &lt;span class="Keyword"&gt;=&lt;/span&gt; &lt;span class="Variable"&gt;PDF&lt;/span&gt;::&lt;span class="Entity"&gt;Writer&lt;/span&gt;.&lt;span class="Entity"&gt;new&lt;/span&gt;
&lt;span class="line-numbers"&gt;   3 &lt;/span&gt; table &lt;span class="Keyword"&gt;=&lt;/span&gt; &lt;span class="Variable"&gt;PDF&lt;/span&gt;::&lt;span class="Entity"&gt;SimpleTable&lt;/span&gt;.&lt;span class="Entity"&gt;new&lt;/span&gt; &lt;span class="Keyword"&gt;do &lt;/span&gt;|&lt;span class="Variable"&gt;tab&lt;/span&gt;|
&lt;span class="line-numbers"&gt;   4 &lt;/span&gt;   tab.&lt;span class="Entity"&gt;column_order&lt;/span&gt;.&lt;span class="Entity"&gt;push&lt;/span&gt;(&lt;span class="Keyword"&gt;*&lt;/span&gt;&lt;span class="String"&gt;&lt;span class="String"&gt;%w(&lt;/span&gt;date rate&lt;span class="String"&gt;)&lt;/span&gt;&lt;/span&gt;)
&lt;span class="line-numbers"&gt;   5 &lt;/span&gt;   tab.&lt;span class="Entity"&gt;columns&lt;/span&gt;[&lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;date&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;] &lt;span class="Keyword"&gt;=&lt;/span&gt; &lt;span class="Variable"&gt;PDF&lt;/span&gt;::&lt;span class="Entity"&gt;SimpleTable&lt;/span&gt;::&lt;span class="Entity"&gt;Column&lt;/span&gt;.&lt;span class="Entity"&gt;new&lt;/span&gt;(&lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;date&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;) { |&lt;span class="Variable"&gt;col&lt;/span&gt;|
&lt;span class="line-numbers"&gt;   6 &lt;/span&gt;     col.&lt;span class="Entity"&gt;heading&lt;/span&gt; &lt;span class="Keyword"&gt;=&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;Date&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;   7 &lt;/span&gt;   }
&lt;span class="line-numbers"&gt;   8 &lt;/span&gt;   tab.&lt;span class="Entity"&gt;columns&lt;/span&gt;[&lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;rate&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;] &lt;span class="Keyword"&gt;=&lt;/span&gt; &lt;span class="Variable"&gt;PDF&lt;/span&gt;::&lt;span class="Entity"&gt;SimpleTable&lt;/span&gt;::&lt;span class="Entity"&gt;Column&lt;/span&gt;.&lt;span class="Entity"&gt;new&lt;/span&gt;(&lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;rate&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;) { |&lt;span class="Variable"&gt;col&lt;/span&gt;|
&lt;span class="line-numbers"&gt;   9 &lt;/span&gt;     col.&lt;span class="Entity"&gt;heading&lt;/span&gt; &lt;span class="Keyword"&gt;=&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;Rate&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;  10 &lt;/span&gt;   }
&lt;span class="line-numbers"&gt;  11 &lt;/span&gt;   tab.&lt;span class="Entity"&gt;orientation&lt;/span&gt;   &lt;span class="Keyword"&gt;=&lt;/span&gt; &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;center&lt;/span&gt;
&lt;span class="line-numbers"&gt;  12 &lt;/span&gt;   data &lt;span class="Keyword"&gt;=&lt;/span&gt; csv_data.&lt;span class="Entity"&gt;map&lt;/span&gt; &lt;span class="Keyword"&gt;do &lt;/span&gt;|&lt;span class="Variable"&gt;e&lt;/span&gt;|
&lt;span class="line-numbers"&gt;  13 &lt;/span&gt;     { &lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;date&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; =&amp;gt; e[&lt;span class="Constant"&gt;0&lt;/span&gt;], &lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;rate&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; =&amp;gt; e[&lt;span class="Constant"&gt;1&lt;/span&gt;] }
&lt;span class="line-numbers"&gt;  14 &lt;/span&gt;   &lt;span class="Keyword"&gt;end&lt;/span&gt;
&lt;span class="line-numbers"&gt;  15 &lt;/span&gt;   tab.&lt;span class="Entity"&gt;data&lt;/span&gt;.&lt;span class="Entity"&gt;replace&lt;/span&gt; data
&lt;span class="line-numbers"&gt;  16 &lt;/span&gt; &lt;span class="Keyword"&gt;end&lt;/span&gt;
&lt;span class="line-numbers"&gt;  17 &lt;/span&gt; table.&lt;span class="Entity"&gt;render_on&lt;/span&gt;(pdf)
&lt;span class="line-numbers"&gt;  18 &lt;/span&gt; pdf.&lt;span class="Entity"&gt;save_as&lt;/span&gt;(&lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;currency_pdf_writer.pdf&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;)
&lt;/pre&gt;&lt;/div&gt;&lt;p class="code_title"&gt;same thing with Prawn&lt;/p&gt;
&lt;div class="UltraViolet"&gt;&lt;pre class="sunburst"&gt;&lt;span class="line-numbers"&gt;   1 &lt;/span&gt; 
&lt;span class="line-numbers"&gt;   2 &lt;/span&gt; &lt;span class="Support"&gt;Prawn&lt;/span&gt;::&lt;span class="Entity"&gt;Document&lt;/span&gt;.&lt;span class="Entity"&gt;generate&lt;/span&gt;(&lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;currency_prawn.pdf&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;) &lt;span class="Keyword"&gt;do&lt;/span&gt;
&lt;span class="line-numbers"&gt;   3 &lt;/span&gt;   table csv_data, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;font_size&lt;/span&gt;          =&amp;gt; &lt;span class="Constant"&gt;10&lt;/span&gt;,
&lt;span class="line-numbers"&gt;   4 &lt;/span&gt;                   &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;vertical_padding&lt;/span&gt;   =&amp;gt; &lt;span class="Constant"&gt;2&lt;/span&gt;,
&lt;span class="line-numbers"&gt;   5 &lt;/span&gt;                   &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;horizontal_padding&lt;/span&gt; =&amp;gt; &lt;span class="Constant"&gt;5&lt;/span&gt;,
&lt;span class="line-numbers"&gt;   6 &lt;/span&gt;                   &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;position&lt;/span&gt;           =&amp;gt; &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;center&lt;/span&gt;,
&lt;span class="line-numbers"&gt;   7 &lt;/span&gt;                   &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;row_colors&lt;/span&gt;         =&amp;gt; &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;pdf_writer&lt;/span&gt;,
&lt;span class="line-numbers"&gt;   8 &lt;/span&gt;                   &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;headers&lt;/span&gt;            =&amp;gt; [&lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;Date&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;,&lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;Rate&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;]
&lt;span class="line-numbers"&gt;   9 &lt;/span&gt; &lt;span class="Keyword"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The Prawn-fu looks a lot sweeter to me and the improvement in performance with Prawn over PDF::Writer is commendable. Get your &lt;a href="http://git.or.cz/"&gt;Git&lt;/a&gt; on and download the latest Prawn version to give it a try yourself. If the bleeding edge is not for you then a gem should be appearing in the near future.&lt;/p&gt;
&lt;p&gt;Keep an eye on this one it&amp;#8217;s hot!&lt;/p&gt;
&lt;p&gt;&lt;a href="http://smuby.org/articles/2008/07/pdf_seafood_sauce_prawn.html"&gt;Permalink&lt;/a&gt; | &lt;a href="http://smuby.org/articles/2008/07/pdf_seafood_sauce_prawn.html#disqus_thread"&gt;comments(View)&lt;/a&gt;&lt;/p&gt;
&lt;script type="text/javascript" src="http://disqus.com/forums/smuby/embed.js"&gt;&lt;/script&gt;&lt;noscript&gt;&lt;a href="http://smuby.disqus.com/?url=ref"&gt;View the forum thread.&lt;/a&gt;&lt;/noscript&gt;&lt;p&gt;&lt;a href="http://disqus.com" class="dsq-brlink"&gt;blog comments powered by &lt;span class="logo-disqus"&gt;Disqus&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/smuby?a=ciN4l_ltE20:MCyuMjFXWUM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/smuby?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/smuby?a=ciN4l_ltE20:MCyuMjFXWUM:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/smuby?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/smuby?a=ciN4l_ltE20:MCyuMjFXWUM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/smuby?i=ciN4l_ltE20:MCyuMjFXWUM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/smuby/~4/ciN4l_ltE20" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://smuby.org/articles/2008/07/pdf_seafood_sauce_prawn.html</feedburner:origLink></entry>
  
  <entry>
    <title>Swing with a JRuby Wrapper: Profligacy</title>
    <link href="http://feedproxy.google.com/~r/smuby/~3/Mp-3fcZQqC0/swing_jruby_wrapper_profligacy.html" />
    <id>tag:smuby.org,2008-07-25:1217023466</id>
    <updated>2008-07-25T23:04:26+01:00</updated>
<content type="html">
&lt;div class="span-14"&gt;
&lt;p&gt;&lt;img src="http://smuby.org/images/recycle.jpg" title="recycle icon" alt="recycle icon" /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="photo_credit span-14"&gt;&lt;a href="http://www.sxc.hu/profile/resignent"&gt;PHOTO CREDIT: courtesy of resignent at sxc.hu&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;I recently whined about the dearth of sophisticated GUI builders in the Rubyverse. I still think that there&amp;#8217;s a gap in the market for a slick product with a visual interface builder that surpasses the current crop to exploit. On the other hand, if you just want to create modest GUI things with Ruby, maybe a drag n&amp;#8217; drop, wysiwyg IDE with extra code-completion sauce could be deemed a tad unnecessary.&lt;/p&gt;
&lt;p&gt;A while ago I bookmarked a site whilst perusing the works of one &lt;a href="http://www.zedshaw.com/"&gt;Zed A. Shaw&lt;/a&gt; (the biological father of &lt;a href="http://mongrel.rubyforge.org/"&gt;Mongrel&lt;/a&gt;). I forgot about it until casting my net into the Omniscient Online Ocean to trawl for Ruby GUI fish. What I snared was a reference to &lt;a href="http://ihate.rubyforge.org/profligacy/"&gt;Profligacy&lt;/a&gt;, a &lt;a href="http://jruby.codehaus.org/"&gt;JRuby&lt;/a&gt; library that helps you to put some soothing Ruby mojo into the &lt;a href="http://en.wikipedia.org/wiki/Swing_(Java)"&gt;Swing&lt;/a&gt; GUI building maelstrom.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ve really tried to enjoy creating desktop applications with Swing, sadly, I remain less than enthusiastic about drowning in a pool of unadulterated Java and Swing. I just find it intellectually painful. Swing reminds me of &lt;a href="http://en.wikipedia.org/wiki/Cod_liver_oil"&gt;Cod Liver Oil&lt;/a&gt;; I know that it&amp;#8217;s good stuff, but it tastes a whole lot more pleasant with orange flavouring. Profligacy is to Swing what orange flavouring is to Cod Liver Oil.&lt;/p&gt;
&lt;p&gt;To use Profligacy you&amp;#8217;re going to need -&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;Java 1.5+&lt;/li&gt;
	&lt;li&gt;JRuby&lt;/li&gt;
	&lt;li&gt;the Profligacy library (I recommend installing the gem via &lt;em&gt;gem install profligacy&lt;/em&gt;)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Trying to convince you of the power of Profligacy with paragraphs of pushy prose probably would not prove particularly persuasive, so &amp;#8217;ere&amp;#8217;s some code.&lt;/p&gt;
&lt;p class="code_title"&gt;profello.rb &amp;#8211; A Hello World program using Profligacy&lt;/p&gt;
&lt;div class="UltraViolet"&gt;&lt;pre class="sunburst"&gt;&lt;span class="line-numbers"&gt;   1 &lt;/span&gt; &lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt; profello.rb &lt;/span&gt;
&lt;span class="line-numbers"&gt;   2 &lt;/span&gt; &lt;span class="Keyword"&gt;require&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;rubygems&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt; 
&lt;span class="line-numbers"&gt;   3 &lt;/span&gt; &lt;span class="Keyword"&gt;require&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;profligacy/swing&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;   4 &lt;/span&gt; &lt;span class="Keyword"&gt;require&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;profligacy/lel&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;   5 &lt;/span&gt; 
&lt;span class="line-numbers"&gt;   6 &lt;/span&gt; &lt;span class="Keyword"&gt;class&lt;/span&gt; &lt;span class="JEntityNameType"&gt;TestWindow&lt;/span&gt;
&lt;span class="line-numbers"&gt;   7 &lt;/span&gt;   include_package &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;javax.swing&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;   8 &lt;/span&gt;   include_package &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;java.awt&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;   9 &lt;/span&gt;   &lt;span class="Keyword"&gt;include&lt;/span&gt; &lt;span class="Variable"&gt;Profligacy&lt;/span&gt;
&lt;span class="line-numbers"&gt;  10 &lt;/span&gt; 
&lt;span class="line-numbers"&gt;  11 &lt;/span&gt;   &lt;span class="Keyword"&gt;def&lt;/span&gt; &lt;span class="Entity"&gt;initialize&lt;/span&gt;
&lt;span class="line-numbers"&gt;  12 &lt;/span&gt;     ui &lt;span class="Keyword"&gt;=&lt;/span&gt; &lt;span class="Support"&gt;Swing&lt;/span&gt;::&lt;span class="Entity"&gt;LEL&lt;/span&gt;.&lt;span class="Entity"&gt;new&lt;/span&gt; &lt;span class="Variable"&gt;JFrame&lt;/span&gt;, &lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;[*lab][buttons]&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="Keyword"&gt;do &lt;/span&gt;|&lt;span class="Variable"&gt;c&lt;/span&gt;,&lt;span class="Variable"&gt;i&lt;/span&gt;|
&lt;span class="line-numbers"&gt;  13 &lt;/span&gt;       c.&lt;span class="Entity"&gt;lab&lt;/span&gt; &lt;span class="Keyword"&gt;=&lt;/span&gt; &lt;span class="Variable"&gt;JLabel&lt;/span&gt;.&lt;span class="Entity"&gt;new&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;Press A Button.&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;  14 &lt;/span&gt;       c.&lt;span class="Entity"&gt;lab&lt;/span&gt;.&lt;span class="Entity"&gt;preferred_size&lt;/span&gt; &lt;span class="Keyword"&gt;=&lt;/span&gt; &lt;span class="Support"&gt;Dimension&lt;/span&gt;.&lt;span class="Entity"&gt;new&lt;/span&gt;(&lt;span class="Constant"&gt;300&lt;/span&gt;, &lt;span class="Constant"&gt;0&lt;/span&gt;)
&lt;span class="line-numbers"&gt;  15 &lt;/span&gt; 
&lt;span class="line-numbers"&gt;  16 &lt;/span&gt;       c.&lt;span class="Entity"&gt;buttons&lt;/span&gt; &lt;span class="Keyword"&gt;=&lt;/span&gt; &lt;span class="Support"&gt;Swing&lt;/span&gt;::&lt;span class="Entity"&gt;LEL&lt;/span&gt;.&lt;span class="Entity"&gt;new&lt;/span&gt; &lt;span class="Variable"&gt;JPanel&lt;/span&gt;, &lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;[first | second]&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="Keyword"&gt;do &lt;/span&gt;|&lt;span class="Variable"&gt;d&lt;/span&gt;,&lt;span class="Variable"&gt;j&lt;/span&gt;|
&lt;span class="line-numbers"&gt;  17 &lt;/span&gt;         d.&lt;span class="Entity"&gt;first&lt;/span&gt; &lt;span class="Keyword"&gt;=&lt;/span&gt; &lt;span class="Variable"&gt;JButton&lt;/span&gt;.&lt;span class="Entity"&gt;new&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;First&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; 
&lt;span class="line-numbers"&gt;  18 &lt;/span&gt;         d.&lt;span class="Entity"&gt;second&lt;/span&gt; &lt;span class="Keyword"&gt;=&lt;/span&gt; &lt;span class="Variable"&gt;JButton&lt;/span&gt;.&lt;span class="Entity"&gt;new&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;Second&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;  19 &lt;/span&gt;         j.&lt;span class="Entity"&gt;first&lt;/span&gt; &lt;span class="Keyword"&gt;=&lt;/span&gt; { &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;action&lt;/span&gt; =&amp;gt; proc {|&lt;span class="Variable"&gt;t&lt;/span&gt;,&lt;span class="Variable"&gt;e&lt;/span&gt;| c.&lt;span class="Entity"&gt;lab&lt;/span&gt;.&lt;span class="Entity"&gt;text&lt;/span&gt; &lt;span class="Keyword"&gt;=&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;Hello world!&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; } }
&lt;span class="line-numbers"&gt;  20 &lt;/span&gt;         j.&lt;span class="Entity"&gt;second&lt;/span&gt; &lt;span class="Keyword"&gt;=&lt;/span&gt; { &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;action&lt;/span&gt; =&amp;gt; proc {|&lt;span class="Variable"&gt;t&lt;/span&gt;,&lt;span class="Variable"&gt;e&lt;/span&gt;| c.&lt;span class="Entity"&gt;lab&lt;/span&gt;.&lt;span class="Entity"&gt;text&lt;/span&gt; &lt;span class="Keyword"&gt;=&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;Are you ready for some GUI Profligacy?&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; } }
&lt;span class="line-numbers"&gt;  21 &lt;/span&gt;       &lt;span class="Keyword"&gt;end&lt;/span&gt;.&lt;span class="Entity"&gt;build&lt;/span&gt; &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;auto_create_container_gaps&lt;/span&gt; =&amp;gt; &lt;span class="Constant"&gt;false&lt;/span&gt;
&lt;span class="line-numbers"&gt;  22 &lt;/span&gt;     &lt;span class="Keyword"&gt;end&lt;/span&gt;
&lt;span class="line-numbers"&gt;  23 &lt;/span&gt; 
&lt;span class="line-numbers"&gt;  24 &lt;/span&gt;     ui.&lt;span class="Entity"&gt;build&lt;/span&gt;(&lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;args&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;Hello World&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;) &lt;span class="Keyword"&gt;do &lt;/span&gt;|&lt;span class="Variable"&gt;c&lt;/span&gt;|
&lt;span class="line-numbers"&gt;  25 &lt;/span&gt;       c.&lt;span class="Entity"&gt;location_relative_to&lt;/span&gt; &lt;span class="Keyword"&gt;=&lt;/span&gt; &lt;span class="Constant"&gt;nil&lt;/span&gt;
&lt;span class="line-numbers"&gt;  26 &lt;/span&gt;       c.&lt;span class="Entity"&gt;default_close_operation&lt;/span&gt; &lt;span class="Keyword"&gt;=&lt;/span&gt; &lt;span class="Variable"&gt;JFrame&lt;/span&gt;::&lt;span class="Entity"&gt;EXIT_ON_CLOSE&lt;/span&gt;
&lt;span class="line-numbers"&gt;  27 &lt;/span&gt;     &lt;span class="Keyword"&gt;end&lt;/span&gt;
&lt;span class="line-numbers"&gt;  28 &lt;/span&gt;   &lt;span class="Keyword"&gt;end&lt;/span&gt;
&lt;span class="line-numbers"&gt;  29 &lt;/span&gt; &lt;span class="Keyword"&gt;end&lt;/span&gt;
&lt;span class="line-numbers"&gt;  30 &lt;/span&gt; 
&lt;span class="line-numbers"&gt;  31 &lt;/span&gt; &lt;span class="Support"&gt;SwingUtilities&lt;/span&gt;.&lt;span class="Entity"&gt;invoke_later&lt;/span&gt; proc { &lt;span class="Support"&gt;TestWindow&lt;/span&gt;.&lt;span class="Entity"&gt;new&lt;/span&gt; }.&lt;span class="Entity"&gt;to_runnable&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Run it -&lt;/p&gt;
&lt;p class="console"&gt;jruby profello.rb&lt;/p&gt;
&lt;p class="code_title"&gt;screenshot from running profello.rb&lt;/p&gt;
&lt;div class="picture span-14"&gt;
&lt;p&gt;&lt;img src="http://smuby.org/images/profello_output.png" title="screenshot" alt="screenshot" /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;I&amp;#8217;m assuming that you installed the Profligacy gem. If you didn&amp;#8217;t, then some minor amendments to the code above will probably be required.&lt;/p&gt;
&lt;p&gt;Java + JRuby is a winning combination for cross-platform GUI creations. Profligacy eases the pain.&lt;/p&gt;
&lt;p&gt;Zed, if you are ever in the U.K. near the badlands of Essex, there is a pint of warm British beer waiting for you.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://smuby.org/articles/2008/07/swing_jruby_wrapper_profligacy.html"&gt;Permalink&lt;/a&gt; | &lt;a href="http://smuby.org/articles/2008/07/swing_jruby_wrapper_profligacy.html#disqus_thread"&gt;comments(View)&lt;/a&gt;&lt;/p&gt;
&lt;script type="text/javascript" src="http://disqus.com/forums/smuby/embed.js"&gt;&lt;/script&gt;&lt;noscript&gt;&lt;a href="http://smuby.disqus.com/?url=ref"&gt;View the forum thread.&lt;/a&gt;&lt;/noscript&gt;&lt;p&gt;&lt;a href="http://disqus.com" class="dsq-brlink"&gt;blog comments powered by &lt;span class="logo-disqus"&gt;Disqus&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/smuby?a=Mp-3fcZQqC0:XmVAPWvqU7Q:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/smuby?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/smuby?a=Mp-3fcZQqC0:XmVAPWvqU7Q:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/smuby?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/smuby?a=Mp-3fcZQqC0:XmVAPWvqU7Q:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/smuby?i=Mp-3fcZQqC0:XmVAPWvqU7Q:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/smuby/~4/Mp-3fcZQqC0" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://smuby.org/articles/2008/07/swing_jruby_wrapper_profligacy.html</feedburner:origLink></entry>
  
  <entry>
    <title>Ruby Report Templates: Documatic</title>
    <link href="http://feedproxy.google.com/~r/smuby/~3/Iy9Jd8NnsUY/ruby_report_templates_documatic.html" />
    <id>tag:smuby.org,2008-07-22:1216731738</id>
    <updated>2008-07-22T14:02:18+01:00</updated>
<content type="html">
&lt;div class="span-14"&gt;
&lt;p&gt;&lt;img src="http://smuby.org/images/print.jpg" title="Type-setting letters" alt="Type-setting letters" /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="photo_credit span-14"&gt;&lt;a href="http://www.sxc.hu/profile/biewoef"&gt;PHOTO CREDIT: courtesy of biewoef at sxc.hu&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;Report generation is a crucial part of many business applications and yet this part of the application development process is often treated like an ugly step-child. In the Ruby world, one project is well on the way to becoming the de facto standard on the not so glamorous reporting catwalk: &lt;a href="http://rubyreports.org/"&gt;Ruport&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Ruport is a great project and is undergoing substantial development in a push towards a 2.0 release. The thing is, sometimes you need to be able to visualise the report during the building process. Wouldn&amp;#8217;t it be great if you had some sort of visual report building mechanism to help you as you sculpt your Ruport management information masterpieces? Well, you do have such a beast because Ruport has teamed up with the &amp;#8216;template-driven formatter&amp;#8217;, &lt;a href="http://stonecode.svnrepository.com/documatic/trac.cgi/wiki"&gt;Documatic&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Install it like so -&lt;/p&gt;
&lt;p class="console"&gt;sudo gem install documatic&lt;/p&gt;
&lt;p&gt;Documatic allows you to create report templates in &lt;a href="http://www.openoffice.org/"&gt;OpenOffice.org&lt;/a&gt; (or in my case &lt;a href="http://www.neooffice.org/"&gt;NeoOffice&lt;/a&gt;) that are used in conjunction with Ruport to generate your reports. Ruby code is embedded in the template to specify the format of your data, then you simply tell Documatic which template to use and where you want the output to go.&lt;/p&gt;
&lt;p class="code_title"&gt;screenshot of Documatic tutorial.odt template&lt;/p&gt;
&lt;div class="picture span-14"&gt;
&lt;p&gt;&lt;a href="http://smuby.org/images/template_before.png"&gt;&lt;img src="http://smuby.org/images/sm_template_before.png" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p class="code_title"&gt;excerpt from Documatic tutorial.rb&lt;/p&gt;
&lt;div class="picture span-14"&gt;
&lt;div class="UltraViolet"&gt;&lt;pre class="sunburst"&gt;&lt;span class="Keyword"&gt;require&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;rubygems&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class="Keyword"&gt;require&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;documatic&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;

&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt; Let's make a trivial table.&lt;/span&gt;

data &lt;span class="Keyword"&gt;=&lt;/span&gt; &lt;span class="Support"&gt;Ruport&lt;/span&gt;::&lt;span class="Entity"&gt;Data&lt;/span&gt;::&lt;span class="Entity"&gt;Table&lt;/span&gt;.&lt;span class="Entity"&gt;new&lt;/span&gt;( &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;column_names&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;%w(&lt;/span&gt;Name Phone&lt;span class="String"&gt;)&lt;/span&gt;&lt;/span&gt;,
                                &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;data&lt;/span&gt; =&amp;gt;
                                [
                                 [&lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;Madchili Restaurant&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;(02) 9805 1287&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;],
                                 [&lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;Shiraz Restaurant&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;(02) 9858 2004&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;],
                                 [&lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;The Ranch Bistro Grill&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;(02) 9887 2411&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;],
                                ])

&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt; Now let's generate an OpenDocument text file using Documatic.&lt;/span&gt;
&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt; (Note: the output directory will be created if it does not exist&lt;/span&gt;
&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt; yet.  If the output file already exists it will be overwritten.)&lt;/span&gt;

data.&lt;span class="Entity"&gt;to_odt_template&lt;/span&gt;(&lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;template_file&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;tutorial.odt&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;,
                     &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;output_file&lt;/span&gt;   =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;output/tutorial.odt&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;)
&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p class="code_title"&gt;screenshot of output from Documatic tutorial.rb&lt;/p&gt;
&lt;div class="picture span-14"&gt;
&lt;p&gt;&lt;a href="http://smuby.org/images/output_after.png"&gt;&lt;img src="http://smuby.org/images/sm_output_after.png" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Just in case you are worried about having to deploy OpenOffice.org with your apps, don&amp;#8217;t be. OpenOffice.org is only required to create the templates, not to perform the generation, so the templates are deployed as standalone files.&lt;/p&gt;
&lt;p&gt;This strikes me as a significant addition to Ruport&amp;#8217;s capabilities that can only help to attract new users. Reporting could almost be getting sexy.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://smuby.org/articles/2008/07/ruby_report_templates_documatic.html"&gt;Permalink&lt;/a&gt; | &lt;a href="http://smuby.org/articles/2008/07/ruby_report_templates_documatic.html#disqus_thread"&gt;comments(View)&lt;/a&gt;&lt;/p&gt;
&lt;script type="text/javascript" src="http://disqus.com/forums/smuby/embed.js"&gt;&lt;/script&gt;&lt;noscript&gt;&lt;a href="http://smuby.disqus.com/?url=ref"&gt;View the forum thread.&lt;/a&gt;&lt;/noscript&gt;&lt;p&gt;&lt;a href="http://disqus.com" class="dsq-brlink"&gt;blog comments powered by &lt;span class="logo-disqus"&gt;Disqus&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/smuby?a=Iy9Jd8NnsUY:MaSvUcJSFjY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/smuby?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/smuby?a=Iy9Jd8NnsUY:MaSvUcJSFjY:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/smuby?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/smuby?a=Iy9Jd8NnsUY:MaSvUcJSFjY:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/smuby?i=Iy9Jd8NnsUY:MaSvUcJSFjY:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/smuby/~4/Iy9Jd8NnsUY" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://smuby.org/articles/2008/07/ruby_report_templates_documatic.html</feedburner:origLink></entry>
  
  <entry>
    <title>State of the Ruby Nation: VM Choices</title>
    <link href="http://feedproxy.google.com/~r/smuby/~3/RqT8zt_xotc/state_ruby_nation_vm.html" />
    <id>tag:smuby.org,2008-07-20:1216550813</id>
    <updated>2008-07-20T11:46:53+01:00</updated>
<content type="html">
&lt;div class="span-14"&gt;
&lt;p&gt;&lt;img src="http://smuby.org/images/robot.jpg" title="robot" alt="robot" /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="photo_credit span-14"&gt;&lt;a href="http://www.sxc.hu/profile/Maffu"&gt;PHOTO CREDIT: courtesy of Maffu at sxc.hu&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;I have a concern that&amp;#8217;s been niggling away at the back of my mind that I&amp;#8217;d like to share with you. What&amp;#8217;s concerning me is the state of the Ruby nation in respect of VMs (virtual machines). If I&amp;#8217;m going to run Ruby I need something that understands my Ruby code and translates it so that my instructions get acted upon. That&amp;#8217;s the job of a Ruby VM.&lt;/p&gt;
&lt;p&gt;At the moment, I really don&amp;#8217;t have too many choices of Ruby VM for serious, production quality endeavour. If I play for team Java, then I&amp;#8217;m looking at &lt;a href="http://jruby.codehaus.org/"&gt;JRuby&lt;/a&gt;. If Java isn&amp;#8217;t involved, then I&amp;#8217;m looking at some variant of Ruby 1.8 (&lt;a href="http://en.wikipedia.org/wiki/Ruby_MRI"&gt;MRI&lt;/a&gt;) depending on vulnerability issues. In the future this is not going to be the case.&lt;/p&gt;
&lt;p&gt;There are new kids appearing on the block, the most prominent of which seem to be: &lt;a href="http://en.wikipedia.org/wiki/YARV"&gt;MRI + YARV&lt;/a&gt;, &lt;a href="http://rubini.us/"&gt;Rubinius&lt;/a&gt; and &lt;a href="http://www.ironruby.net/"&gt;IronRuby (a.k.a Ruby.NET)&lt;/a&gt;. I&amp;#8217;m not including JRuby in this list because I consider it to be an established player.&lt;/p&gt;
&lt;p&gt;Let me make something quite clear before I continue. I am not looking at this from the perspective of a developer. As a developer I like choices and I revel in new challenges. However, if I am the Chief Technical Officer (CTO) of a corporation, my priorities are going to be different. I&amp;#8217;m going to have to make sound decisions that are good for the business and I&amp;#8217;m going to have to justify those decisions in order to get the hard cash needed to implement them. Above all, I&amp;#8217;m going to make decisions that, hopefully, won&amp;#8217;t get me fired. It is with my CTO hat on that I address the Ruby VM issue.&lt;/p&gt;
&lt;p&gt;The three VM implementations that I listed above are in development, but are making fairly rapid progress. When they are ready for prime time what am I going to choose?&lt;/p&gt;
&lt;p&gt;Will I choose the new and improved MRI with added YARV, developed by members of the original Ruby (MRI) team? Or will I choose Rubinius backed by the prodigious talents at &lt;a href="http://engineyard.com/"&gt;Engine Yard&lt;/a&gt;? Or will I go for IronRuby if I&amp;#8217;m in a .NET shop? Maybe something else will be vying for my attention and I&amp;#8217;ll plump for that.&lt;/p&gt;
&lt;p&gt;Truth is, it doesn&amp;#8217;t matter does it? I think that what matters is that Ruby code runs as expected regardless of VM. If the respective creators of Ruby VMs continue to work with that idea in mind everything will be rosy in the Ruby garden. If it gets to the point where I can&amp;#8217;t run my code reliably on any one of the major Ruby VMs, then there is going to be some significant turbulence in the Rubyverse.&lt;/p&gt;
&lt;p&gt;As a CTO, I want to know that systems can be written to do what was intended within budget and on time. With competent development teams and practicable methods, the Ruby language should enable me to achieve those goals more often than not. If things go wrong, I want to be able to call upon someone to fix them if the answers can&amp;#8217;t be found in-house. I do &lt;strong&gt;not&lt;/strong&gt; want to have to swap one Ruby VM for another, because anytime I need to do that, Ruby is off the language menu.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://smuby.org/articles/2008/07/state_ruby_nation_vm.html"&gt;Permalink&lt;/a&gt; | &lt;a href="http://smuby.org/articles/2008/07/state_ruby_nation_vm.html#disqus_thread"&gt;comments(View)&lt;/a&gt;&lt;/p&gt;
&lt;script type="text/javascript" src="http://disqus.com/forums/smuby/embed.js"&gt;&lt;/script&gt;&lt;noscript&gt;&lt;a href="http://smuby.disqus.com/?url=ref"&gt;View the forum thread.&lt;/a&gt;&lt;/noscript&gt;&lt;p&gt;&lt;a href="http://disqus.com" class="dsq-brlink"&gt;blog comments powered by &lt;span class="logo-disqus"&gt;Disqus&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/smuby?a=RqT8zt_xotc:FCBVNW11-qc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/smuby?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/smuby?a=RqT8zt_xotc:FCBVNW11-qc:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/smuby?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/smuby?a=RqT8zt_xotc:FCBVNW11-qc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/smuby?i=RqT8zt_xotc:FCBVNW11-qc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/smuby/~4/RqT8zt_xotc" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://smuby.org/articles/2008/07/state_ruby_nation_vm.html</feedburner:origLink></entry>
  
  <entry>
    <title>Ruby GUI Goodness: Missing</title>
    <link href="http://feedproxy.google.com/~r/smuby/~3/k6GgPxt0so0/ruby_gui_goodness.html" />
    <id>tag:smuby.org,2008-07-12:1215902140</id>
    <updated>2008-07-12T23:35:40+01:00</updated>
<content type="html">
&lt;div class="span-14"&gt;
&lt;p&gt;&lt;img src="http://smuby.org/images/chocolate.jpg" title="Spoonful of gooey chocolate sauce" alt="Spoonful of gooey chocolate sauce" /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="photo_credit span-14"&gt;&lt;a href="http://www.sxc.hu/profile/lusi"&gt;PHOTO CREDIT: courtesy of lusi at sxc.hu&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;I am not a happy badger. My mission was to unearth a tantalising Ruby GUI construction kit; devastatingly simple to set up and use, cross-platform, and did I mention, easy to set up and use. Well, I failed to find such a beast roaming the Rubyverse and I&amp;#8217;m turning to you, my fellow Rubyistas, for inspiration.&lt;/p&gt;
&lt;p&gt;The list of GUI prescriptions that I have tried are: &lt;a href="http://code.whytheluckystiff.net/shoes/"&gt;Shoes&lt;/a&gt;, &lt;a href="http://rubycocoa.sourceforge.net/HomePage"&gt;RubyCocoa&lt;/a&gt;, &lt;a href="http://wxruby.rubyforge.org/wiki/wiki.pl"&gt;WxRuby&lt;/a&gt;, &lt;a href="http://www.fxruby.org/"&gt;FXRuby&lt;/a&gt;, &lt;a href="http://techbase.kde.org/Development/Languages/Ruby"&gt;QtRuby&lt;/a&gt; and &lt;a href="http://monkeybars.rubyforge.org/"&gt;Monkeybars&lt;/a&gt;. I had fun trying them, but unfortunately they all left me with the feeling that there is still a vacancy for a Chief Fabricator to be filled in the Ruby GUI Construction department.&lt;/p&gt;
&lt;p&gt;All of the projects listed have to be commended for their ingenuity. I had high hopes for Shoes (and still do), although I have not been able to get the latest Mac OSX ppc releases to run at all; the earlier ones having been partially functional on my platform.&lt;/p&gt;
&lt;p&gt;RubyCocoa is targeted squarely at the Apple orchard, thus it fails to satisfy the cross-platform criterion. Nevertheless, it did introduce me to the impressive &lt;a href="http://developer.apple.com/tools/interfacebuilder.html"&gt;XCode Interface Builder&lt;/a&gt; so I&amp;#8217;m not ungrateful.&lt;/p&gt;
&lt;p&gt;WxRuby, FXRuby and QtRuby all fall at the twin hurdles of set up and/or ease of use. I&amp;#8217;ve designed GUI applications with things like &lt;a href="http://www.sybase.com/products/development/powerbuilder"&gt;Powerbuilder from Sybase&lt;/a&gt;, and for me, drag n&amp;#8217; drop is king. While IDEs do exist for the aforementioned Ruby applications, they lack polish, and simplicity is not something that was paramount in their design as far as I can see. FXRuby interfaces, though cross-platform in nature, suffer from the additional handicap of looking uniformly ugly on all platforms.&lt;/p&gt;
&lt;p&gt;Monkeybars falls into the same category as RubyCocoa for me. It is a worthy effort that strays into the Java world to make use of &lt;a href="http://jruby.codehaus.org/"&gt;JRuby&lt;/a&gt; and IDEs like &lt;a href="http://www.netbeans.org/"&gt;Netbeans&lt;/a&gt;. As with RubyCocoa, the development process seemed disjointed because it relies on the co-operation of disparate parts.&lt;/p&gt;
&lt;p&gt;My quest began because I was curious to find out whether the Ruby GUI creator was, like the &lt;a href="http://en.wikipedia.org/wiki/Bigfoot"&gt;Sasquatch (a.k.a Bigfoot)&lt;/a&gt;, the stuff of myth. I found that Ruby GUI builders do exist, though none can count me as a willing suitor &amp;#8211; at the moment.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://smuby.org/articles/2008/07/ruby_gui_goodness.html"&gt;Permalink&lt;/a&gt; | &lt;a href="http://smuby.org/articles/2008/07/ruby_gui_goodness.html#disqus_thread"&gt;comments(View)&lt;/a&gt;&lt;/p&gt;
&lt;script type="text/javascript" src="http://disqus.com/forums/smuby/embed.js"&gt;&lt;/script&gt;&lt;noscript&gt;&lt;a href="http://smuby.disqus.com/?url=ref"&gt;View the forum thread.&lt;/a&gt;&lt;/noscript&gt;&lt;p&gt;&lt;a href="http://disqus.com" class="dsq-brlink"&gt;blog comments powered by &lt;span class="logo-disqus"&gt;Disqus&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/smuby?a=k6GgPxt0so0:pC3IHgI4qiI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/smuby?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/smuby?a=k6GgPxt0so0:pC3IHgI4qiI:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/smuby?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/smuby?a=k6GgPxt0so0:pC3IHgI4qiI:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/smuby?i=k6GgPxt0so0:pC3IHgI4qiI:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/smuby/~4/k6GgPxt0so0" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://smuby.org/articles/2008/07/ruby_gui_goodness.html</feedburner:origLink></entry>
  
  <entry>
    <title>Syntax Reminders: cheat</title>
    <link href="http://feedproxy.google.com/~r/smuby/~3/nIizvS_1DHU/syntax_reminders_cheat.html" />
    <id>tag:smuby.org,2008-07-11:1215795062</id>
    <updated>2008-07-11T17:51:02+01:00</updated>
<content type="html">
&lt;div class="span-14"&gt;
&lt;p&gt;&lt;img src="http://smuby.org/images/golden_bell.jpg" title="Golden bell" alt="Golden bell" /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="photo_credit span-14"&gt;&lt;a href="http://www.sxc.hu/profile/eurok"&gt;PHOTO CREDIT: courtesy of eurok at sxc.hu&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;How many times have you racked your brain to try to remember some long lost fragment of syntax? You&amp;#8217;ve got &lt;em&gt;&amp;#8216;man&amp;#8217;&lt;/em&gt; and &lt;em&gt;&amp;#8216;gem server&amp;#8217;&lt;/em&gt; to crank up at the console, but no, they&amp;#8217;re just not immediate enough; they kinda stop you in mid flow. What you could do with, at times like that, is the equivalent of the person offstage at the theatre who prompts the actors when they forget their lines.&lt;/p&gt;
&lt;p&gt;As if by magic, the consistently creative &lt;a href="http://errtheblog.com"&gt;err.the_blog&lt;/a&gt; guys have read your mind. They have fashioned a commandline-driven cheat sheet utility, appropriately named &lt;a href="http://cheat.errtheblog.com/"&gt;cheat&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Just install in the time-honoured fashion -&lt;/p&gt;
&lt;pre class="console"&gt;
sudo gem install cheat
&lt;/pre&gt;
&lt;p&gt;Then take her for a spin. I&amp;#8217;m always forgetting some &lt;a href="http://whytheluckystiff.net/ruby/redcloth/"&gt;Textile&lt;/a&gt; snippet or other -&lt;/p&gt;
&lt;pre class="console"&gt;
chrisduncan:~$cheat textile
textile:
  Quick block modifiers:
    Header: hn.
    Blockquote: bq.
    Footnote: fnn.
    Numeric list: #
    Bulleted list: *
  
  Quick phrase modifiers:
    _emphasis_
    *strong*
    ??citation??
    -deleted text-
    +inserted text+
    ^superscript^
    ~subscript~
    %span%
  
  To apply attributes:
    (class)
    (#id)
    {style}
    [language]
  
  To align blocks:
    &amp;lt; right
    &amp;gt; left
    = center
    &amp;lt;&amp;gt; justify
  
  To insert a table:
    |a|table|row|
    |a|table|row|
  
  To insert a link:
    "linktext":url
  
  To insert an image:
    !imageurl!
  
  To define an acronym:
    ABC(Always Be Closing)
  
  To reference a footnote:
    [n]
&lt;/pre&gt;
&lt;p&gt;Of course, if there isn&amp;#8217;t a cheat sheet for your particular missing nugget of knowledge, you can always do some research elsewhere and manufacture a sheet for future use.&lt;/p&gt;
&lt;p&gt;My advice to you is: if in doubt, &lt;a href="http://cheat.errtheblog.com/"&gt;cheat&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://smuby.org/articles/2008/07/syntax_reminders_cheat.html"&gt;Permalink&lt;/a&gt; | &lt;a href="http://smuby.org/articles/2008/07/syntax_reminders_cheat.html#disqus_thread"&gt;comments(View)&lt;/a&gt;&lt;/p&gt;
&lt;script type="text/javascript" src="http://disqus.com/forums/smuby/embed.js"&gt;&lt;/script&gt;&lt;noscript&gt;&lt;a href="http://smuby.disqus.com/?url=ref"&gt;View the forum thread.&lt;/a&gt;&lt;/noscript&gt;&lt;p&gt;&lt;a href="http://disqus.com" class="dsq-brlink"&gt;blog comments powered by &lt;span class="logo-disqus"&gt;Disqus&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/smuby?a=nIizvS_1DHU:iSAbLGKkXwE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/smuby?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/smuby?a=nIizvS_1DHU:iSAbLGKkXwE:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/smuby?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/smuby?a=nIizvS_1DHU:iSAbLGKkXwE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/smuby?i=nIizvS_1DHU:iSAbLGKkXwE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/smuby/~4/nIizvS_1DHU" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://smuby.org/articles/2008/07/syntax_reminders_cheat.html</feedburner:origLink></entry>
  
  <entry>
    <title>Static is Still Cool: Webby</title>
    <link href="http://feedproxy.google.com/~r/smuby/~3/9arcab52Pv4/static_still_cool_webby.html" />
    <id>tag:smuby.org,2008-07-11:1215731030</id>
    <updated>2008-07-11T00:03:50+01:00</updated>
<content type="html">
&lt;div class="span-14"&gt;
&lt;p&gt;&lt;img src="http://smuby.org/images/info.jpg" title="info icon" alt="info icon" /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="photo_credit span-14"&gt;&lt;a href="http://bigphoto1.blogspot.com/"&gt;PHOTO CREDIT: courtesy of svilen001 at sxc.hu&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;I&amp;#8217;ve played with dynamic, database-driven web frameworks in order to create my blogs in the past and they were interesting projects to learn from. However, one thought kept nagging at me as I was carving my code &amp;#8211; &lt;em&gt;Is this overkill for a blog?&lt;/em&gt; The answer was a resounding yes. My blogging needs are really quite simple, much more suited to the calmer waters frequented by static website aficionados.&lt;/p&gt;
&lt;p&gt;It is within those tranquil waters that the fantabulous &lt;a href="http://webby.rubyforge.org"&gt;Webby&lt;/a&gt; resides. In case you haven&amp;#8217;t heard about Webby, it&amp;#8217;s a &amp;#8216;website management system&amp;#8217; that allows you to generate web pages from text-based templates. If you can handle the command line and utter the phrase &amp;#8211; &lt;strong&gt;I don&amp;#8217; need no steenkin&amp;#8217; GUI!&lt;/strong&gt; &amp;#8211; on a regular basis like a rather poor stereotype from a Spaghetti Western, Webby could well become one of your Ruby weapons of choice.&lt;/p&gt;
&lt;p&gt;A blog is basically a collection of static web pages. Once a post is written, it generally remains untouched. There may be the occasional tweak, but usually a post ain&amp;#8217;t gonna change much if at all. There seems to be a temptation to fill a blog with numerous unwarranted bells and whistles in a vain attempt to encourage readership.&lt;/p&gt;
&lt;p&gt;Does a blog really need a search capability? I&amp;#8217;m yet to be convinced. Usually, my blog visits are the result of a Google search and once there, I might even be tempted to click on a few additional links. I don&amp;#8217;t actually remember ever using a blog search box except to test if the ones that I created were working.&lt;/p&gt;
&lt;p&gt;Tag clouds are popular, nevertheless, do they really add to the blog reading experience or are they just another web developer affectation?&lt;/p&gt;
&lt;p&gt;Webby lets me publish on the web with the minimum of fuss and bother. I can use &lt;a href="http://hobix.com/textile/"&gt;Textile&lt;/a&gt;, &lt;a href="http://daringfireball.net/projects/markdown/syntax"&gt;Markdown&lt;/a&gt; and &lt;a href="http://haml.hamptoncatlin.com/"&gt;Haml&lt;/a&gt; in my pages along with trusty &lt;a href="http://www.ruby-doc.org/stdlib/libdoc/erb/rdoc/classes/ERB.html"&gt;ERB&lt;/a&gt;. I can customise and automate to my heart&amp;#8217;s content, even including some javascript like the &lt;a href="http://disqus.com"&gt;Disqus&lt;/a&gt; comment service in this site.&lt;/p&gt;
&lt;p&gt;If you&amp;#8217;re feeling the static vibe but Webby just doesn&amp;#8217;t hit the spot, you might want to try these offerings on for size (they are in no particular order) -&lt;/p&gt;
&lt;p&gt;&lt;a href="http://nanoc.stoneship.org/"&gt;nanoc&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://webgen.rubyforge.org/"&gt;webgen&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://staticmatic.rubyforge.org/"&gt;StaticMatic&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://rog.rubyforge.org/"&gt;Rog&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://snk.rubyforge.org/lib/rassmalog/output/index.html"&gt;Rassmalog&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;My assertion is that static web pages are a good fit for blogging and yes, I think they&amp;#8217;re still cool.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://smuby.org/articles/2008/07/static_still_cool_webby.html"&gt;Permalink&lt;/a&gt; | &lt;a href="http://smuby.org/articles/2008/07/static_still_cool_webby.html#disqus_thread"&gt;comments(View)&lt;/a&gt;&lt;/p&gt;
&lt;script type="text/javascript" src="http://disqus.com/forums/smuby/embed.js"&gt;&lt;/script&gt;&lt;noscript&gt;&lt;a href="http://smuby.disqus.com/?url=ref"&gt;View the forum thread.&lt;/a&gt;&lt;/noscript&gt;&lt;p&gt;&lt;a href="http://disqus.com" class="dsq-brlink"&gt;blog comments powered by &lt;span class="logo-disqus"&gt;Disqus&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/smuby?a=9arcab52Pv4:UZFAGS_qZYk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/smuby?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/smuby?a=9arcab52Pv4:UZFAGS_qZYk:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/smuby?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/smuby?a=9arcab52Pv4:UZFAGS_qZYk:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/smuby?i=9arcab52Pv4:UZFAGS_qZYk:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/smuby/~4/9arcab52Pv4" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://smuby.org/articles/2008/07/static_still_cool_webby.html</feedburner:origLink></entry>
  
  <entry>
    <title>Light Up Your Code: Ultraviolet</title>
    <link href="http://feedproxy.google.com/~r/smuby/~3/b2oaWqfQPj8/light_up_your_code_ultraviolet.html" />
    <id>tag:smuby.org,2008-07-06:1215384995</id>
    <updated>2008-07-06T23:56:35+01:00</updated>
<content type="html">
&lt;div class="span-14"&gt;
&lt;p&gt;&lt;img src="http://smuby.org/images/orbs.jpg" title="Picture of coloured orbs" alt="Picture of coloured orbs" /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="photo_credit span-14"&gt;&lt;a href="http://www.sxc.hu/profile/nookiez"&gt;PHOTO CREDIT: courtesy of nookiez at sxc.hu&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;I like the look of the output from the funky &lt;a href="http://ultraviolet.rubyforge.org/"&gt;Ultraviolet&lt;/a&gt; syntax highlighting engine for code snippets in blogs, so I figured it was about time that I actually used it.&lt;/p&gt;
&lt;p&gt;My blogging software of choice, &lt;a href="http://webby.rubyforge.org"&gt;Webby&lt;/a&gt;, comes with an Ultraviolet helper, consequently, I was feeling confident that I would be entering highlighting heaven without a struggle. I read the &lt;a href="http://webby.rubyforge.org/reference/"&gt;Webby reference material&lt;/a&gt; and saw that CSS files for the Ultraviolet themes (colour schemes) were required. Problem was that I didn&amp;#8217;t see any mention of where these vital artefacts might be obtained.&lt;/p&gt;
&lt;p&gt;Luckily, my good mate Google was able to supply a useful &lt;a href="http://blog.sunvolt.com/2008/5/21/getting-code-syntax-highlighting-working-in-mephsito-using-ultraviolet"&gt;post&lt;/a&gt; from Yak Shavings (much obliged to you Phil Barnes) that allowed me to produce the CSS files for the standard Ultraviolet themes. After installing the gem with &lt;em&gt;sudo gem install ultraviolet&lt;/em&gt;, I fired up &lt;em&gt;irb&lt;/em&gt; and did the following -&lt;/p&gt;
&lt;pre class="console"&gt;
irb(main):001:0&amp;gt; require 'uv'
=&amp;gt; true
irb(main):002:0&amp;gt; Uv.copy_files "xhtml", "css"
=&amp;gt; ["/opt/local/lib/ruby/gems/1.8/gems/ultraviolet-0.10.2/lib/.."]
&lt;/pre&gt;
&lt;p&gt;Voila, a directory named &amp;#8216;css&amp;#8217; containing the theme files appeared in my own &amp;#8216;css&amp;#8217; directory that I had specified in the call to &lt;em&gt;Uv.copy_files&lt;/em&gt; above. Magnifique.&lt;/p&gt;
&lt;p&gt;I subsequently found that Ultraviolet has a command line utility after looking at the &lt;a href="http://ultraviolet.rubyforge.org/usage.xhtml"&gt;&amp;#8216;usage&amp;#8217;&lt;/a&gt; page of the web site. If you type &lt;em&gt;uv &amp;#8212;help&lt;/em&gt; at the terminal/console you will get a helpful list of commands. I used this one to achieve a similar result to my irb excursion above -&lt;/p&gt;
&lt;pre class="console"&gt;
uv -s ruby --copy-files css
&lt;/pre&gt;
&lt;p&gt;This command did not return of its own volition and required a Ctrl-C to terminate it on my system. Has anyone else experienced this? Nonetheless, the CSS files were generated correctly when I examined them.&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s a small example of Ultraviolet&amp;#8217;s prowess -&lt;/p&gt;
&lt;p class="code_title"&gt;sunburst theme&lt;/p&gt;
&lt;div class="UltraViolet"&gt;&lt;pre class="sunburst"&gt;&lt;span class="line-numbers"&gt;   1 &lt;/span&gt; &lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt; Find the missing Ultraviolet CSS files&lt;/span&gt;
&lt;span class="line-numbers"&gt;   2 &lt;/span&gt; &lt;span class="Keyword"&gt;def&lt;/span&gt; &lt;span class="Entity"&gt;google_search&lt;/span&gt;(&lt;span class="Variable"&gt;string&lt;/span&gt;)
&lt;span class="line-numbers"&gt;   3 &lt;/span&gt;   answer &lt;span class="Keyword"&gt;=&lt;/span&gt; &lt;span class="Variable"&gt;Google&lt;/span&gt;(string)
&lt;span class="line-numbers"&gt;   4 &lt;/span&gt;   puts answer
&lt;span class="line-numbers"&gt;   5 &lt;/span&gt; &lt;span class="Keyword"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Ain&amp;#8217;t it a thing of beauty?&lt;/p&gt;
&lt;p&gt;&lt;a href="http://smuby.org/articles/2008/07/light_up_your_code_ultraviolet.html"&gt;Permalink&lt;/a&gt; | &lt;a href="http://smuby.org/articles/2008/07/light_up_your_code_ultraviolet.html#disqus_thread"&gt;comments(View)&lt;/a&gt;&lt;/p&gt;
&lt;script type="text/javascript" src="http://disqus.com/forums/smuby/embed.js"&gt;&lt;/script&gt;&lt;noscript&gt;&lt;a href="http://smuby.disqus.com/?url=ref"&gt;View the forum thread.&lt;/a&gt;&lt;/noscript&gt;&lt;p&gt;&lt;a href="http://disqus.com" class="dsq-brlink"&gt;blog comments powered by &lt;span class="logo-disqus"&gt;Disqus&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/smuby?a=b2oaWqfQPj8:uZ6Q5_veIgM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/smuby?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/smuby?a=b2oaWqfQPj8:uZ6Q5_veIgM:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/smuby?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/smuby?a=b2oaWqfQPj8:uZ6Q5_veIgM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/smuby?i=b2oaWqfQPj8:uZ6Q5_veIgM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/smuby/~4/b2oaWqfQPj8" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://smuby.org/articles/2008/07/light_up_your_code_ultraviolet.html</feedburner:origLink></entry>
  
  <entry>
    <title>Regex Library Installation on OSX: Oniguruma</title>
    <link href="http://feedproxy.google.com/~r/smuby/~3/-Qqz6blmD7Q/regex_install_oniguruma.html" />
    <id>tag:smuby.org,2008-07-05:1215296481</id>
    <updated>2008-07-05T23:21:21+01:00</updated>
<content type="html">
&lt;div class="span-14"&gt;
&lt;p&gt;&lt;img src="http://smuby.org/images/string.jpg" title="Picture of a ball of string" alt="Picture of a ball of string" /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="photo_credit span-14"&gt;&lt;a href="http://www.sxc.hu/profile/crisderaud"&gt;PHOTO CREDIT: courtesy of crisderaud at sxc.hu&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;I&amp;#8217;m running with Ruby 1.8.6 on Mac OSX 10.4.11 and normally that works well for me. However, I recently ran into a problem when I wanted to try out the highly attractive &lt;a href="http://ultraviolet.rubyforge.org/"&gt;Ultraviolet&lt;/a&gt; syntax highlighter.&lt;/p&gt;
&lt;p&gt;The command line invocation &lt;em&gt;sudo gem install ultraviolet&lt;/em&gt; just choked horribly and spat out errors. Something was up with the &lt;a href="http://oniguruma.rubyforge.org/"&gt;Oniguruma&lt;/a&gt; regular expression library gem that Ultraviolet depends on and I needed to find out what, and, more importantly, what on earth the remedy was.&lt;/p&gt;
&lt;p&gt;I googled, googled some more, and then decided to give up because the solutions that I found seemed either too complex or didn&amp;#8217;t apply to my setup. I settled for &lt;a href="http://coderay.rubychan.de/"&gt;Coderay&lt;/a&gt; instead, but my failure with Ultraviolet was bugging me.&lt;/p&gt;
&lt;p&gt;Yesterday, I resumed the search for an answer to my Oniguruma conundrum. Good God almighty! An answer leapt from my Google search like an overeager salmon. The article that saved my sanity was &lt;a href="http://www.goodbyehelicopter.com/2008/02/20/install-oniguruma-on-os-x/"&gt;this&lt;/a&gt; &amp;#8211; thank you &amp;#8216;Goodbye Helicopter&amp;#8217;.&lt;/p&gt;
&lt;p&gt;Anyway, in case there are others out there who are struggling to see the light with this problem, I figure that this information needs to be published as widely as possible, so here&amp;#8217;s what to do.&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;Download the Oniguruma &amp;#8216;C&amp;#8217; code tarball from &lt;a href="http://www.geocities.jp/kosako3/oniguruma/"&gt;this site&lt;/a&gt;. I used version 5.9.1&lt;/li&gt;
	&lt;li&gt;&amp;#8216;cd&amp;#8217; to the directory that you downloaded the tarball into and expand it.&lt;/li&gt;
	&lt;li&gt;&amp;#8216;cd&amp;#8217; to the extracted directory, in my case &lt;em&gt;onig-5.9.1&lt;/em&gt;&lt;/li&gt;
	&lt;li&gt;Configure it with the command &lt;em&gt;./configure &amp;#8212;prefix=/usr/local&lt;/em&gt;. The prefix path is where you would like to install the software. Change it to suit yourself if you need to.&lt;/li&gt;
	&lt;li&gt;Issue the command &lt;em&gt;sudo make&lt;/em&gt;&lt;/li&gt;
	&lt;li&gt;Issue the command &lt;em&gt;sudo make install&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;After this you should be able to install your Oniguruma-dependent gems with the greatest of ease. I hope these instructions work as well for you as they did for me.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://smuby.org/articles/2008/07/regex_install_oniguruma.html"&gt;Permalink&lt;/a&gt; | &lt;a href="http://smuby.org/articles/2008/07/regex_install_oniguruma.html#disqus_thread"&gt;comments(View)&lt;/a&gt;&lt;/p&gt;
&lt;script type="text/javascript" src="http://disqus.com/forums/smuby/embed.js"&gt;&lt;/script&gt;&lt;noscript&gt;&lt;a href="http://smuby.disqus.com/?url=ref"&gt;View the forum thread.&lt;/a&gt;&lt;/noscript&gt;&lt;p&gt;&lt;a href="http://disqus.com" class="dsq-brlink"&gt;blog comments powered by &lt;span class="logo-disqus"&gt;Disqus&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/smuby?a=-Qqz6blmD7Q:i-HpXE135mM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/smuby?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/smuby?a=-Qqz6blmD7Q:i-HpXE135mM:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/smuby?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/smuby?a=-Qqz6blmD7Q:i-HpXE135mM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/smuby?i=-Qqz6blmD7Q:i-HpXE135mM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/smuby/~4/-Qqz6blmD7Q" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://smuby.org/articles/2008/07/regex_install_oniguruma.html</feedburner:origLink></entry>
  
  <entry>
    <title>Rake + Sake: Thor</title>
    <link href="http://feedproxy.google.com/~r/smuby/~3/cBqMkU9LjYg/rake_and_sake_thor.html" />
    <id>tag:smuby.org,2008-07-03:1215104313</id>
    <updated>2008-07-03T17:58:33+01:00</updated>
<content type="html">
&lt;div class="span-14"&gt;
&lt;p&gt;&lt;img src="http://smuby.org/images/hammer.jpg" title="Picture of a hammer" alt="Picture of a hammer" /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="photo_credit span-14"&gt;&lt;a href="http://www.sxc.hu/profile/vierdrie"&gt;PHOTO CREDIT: courtesy of vierdrie at sxc.hu&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;Thor is a Ruby scripting framework fresh from the fevered imagination of Yehuda Katz. It allows you to do all of the things that &lt;a href="http://rake.rubyforge.org/"&gt;Rake&lt;/a&gt; and &lt;a href="http://errtheblog.com/posts/60-sake-bomb"&gt;Sake&lt;/a&gt; have become popular for, with the added bonus of letting you write it all in regular Ruby syntax.&lt;/p&gt;
&lt;p&gt;Let me show you what I mean. First install the Thor gem -&lt;/p&gt;
&lt;pre class="console"&gt;
sudo gem install thor
&lt;/pre&gt;
&lt;p&gt;Here is a Thor script that let&amp;#8217;s me open Ruby gem directories in TextMate; something that I find myself doing quite often.&lt;/p&gt;
&lt;p class="code_title"&gt;gemate.thor&lt;/p&gt;
&lt;div class="CodeRay"&gt;&lt;pre&gt;&lt;span class="no"&gt; 1&lt;/span&gt; &lt;span class="c"&gt;# module: gemate&lt;/span&gt;
&lt;span class="no"&gt; 2&lt;/span&gt; 
&lt;span class="no"&gt; 3&lt;/span&gt; &lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;Gemate&lt;/span&gt; &amp;lt; &lt;span class="co"&gt;Thor&lt;/span&gt;
&lt;span class="no"&gt; 4&lt;/span&gt;   
&lt;span class="no"&gt; 5&lt;/span&gt;   desc &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;view NAME&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;view gem directory in TextMate&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class="no"&gt; 6&lt;/span&gt;   &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;view&lt;/span&gt;(name)
&lt;span class="no"&gt; 7&lt;/span&gt;   
&lt;span class="no"&gt; 8&lt;/span&gt;     term = name + &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class="no"&gt; 9&lt;/span&gt; 
&lt;span class="no"&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;/span&gt;     puts &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Searching for '&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; + term + &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;'...&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class="no"&gt;11&lt;/span&gt; 
&lt;span class="no"&gt;12&lt;/span&gt;     &lt;span class="c"&gt;# get the path to the gem directory from rubygems and search for any matching directories&lt;/span&gt;
&lt;span class="no"&gt;13&lt;/span&gt;     path = &lt;span class="sh"&gt;&lt;span class="dl"&gt;`&lt;/span&gt;&lt;span class="k"&gt;gem env gemdir&lt;/span&gt;&lt;span class="dl"&gt;`&lt;/span&gt;&lt;/span&gt;
&lt;span class="no"&gt;14&lt;/span&gt;     new_path = &lt;span class="co"&gt;File&lt;/span&gt;.join([path.chomp, &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;gems&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;])
&lt;span class="no"&gt;15&lt;/span&gt;     &lt;span class="co"&gt;Dir&lt;/span&gt;.chdir(new_path)
&lt;span class="no"&gt;16&lt;/span&gt;     &lt;span class="iv"&gt;@d_arr&lt;/span&gt; = &lt;span class="co"&gt;Dir&lt;/span&gt;.glob(term)
&lt;span class="no"&gt;17&lt;/span&gt; 
&lt;span class="no"&gt;18&lt;/span&gt;     &lt;span class="r"&gt;if&lt;/span&gt; &lt;span class="iv"&gt;@d_arr&lt;/span&gt;.empty?
&lt;span class="no"&gt;19&lt;/span&gt;       puts &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Sorry, nothing like that found&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class="no"&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;/span&gt;     &lt;span class="r"&gt;elsif&lt;/span&gt; &lt;span class="iv"&gt;@d_arr&lt;/span&gt;.size == &lt;span class="i"&gt;1&lt;/span&gt;
&lt;span class="no"&gt;21&lt;/span&gt;       view_one()
&lt;span class="no"&gt;22&lt;/span&gt;     &lt;span class="r"&gt;else&lt;/span&gt;
&lt;span class="no"&gt;23&lt;/span&gt;       view_list()
&lt;span class="no"&gt;24&lt;/span&gt;     &lt;span class="r"&gt;end&lt;/span&gt;
&lt;span class="no"&gt;25&lt;/span&gt;   &lt;span class="r"&gt;end&lt;/span&gt;
&lt;span class="no"&gt;26&lt;/span&gt;     
&lt;span class="no"&gt;27&lt;/span&gt;   private
&lt;span class="no"&gt;28&lt;/span&gt;   
&lt;span class="no"&gt;29&lt;/span&gt;     &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;view_one&lt;/span&gt;
&lt;span class="no"&gt;&lt;strong&gt;30&lt;/strong&gt;&lt;/span&gt;       puts &lt;span class="iv"&gt;@d_arr&lt;/span&gt;.first
&lt;span class="no"&gt;31&lt;/span&gt;       print &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;Do you want to view this? [Y/n]: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class="no"&gt;32&lt;/span&gt;       resp = gets.chomp!
&lt;span class="no"&gt;33&lt;/span&gt;       &lt;span class="r"&gt;if&lt;/span&gt; resp.empty? &lt;span class="r"&gt;or&lt;/span&gt; resp.downcase == &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;y&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class="no"&gt;34&lt;/span&gt;         exec &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;mate &lt;/span&gt;&lt;span class="il"&gt;&lt;span class="idl"&gt;#{&lt;/span&gt;&lt;span class="iv"&gt;@d_arr&lt;/span&gt;.first&lt;span class="idl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class="no"&gt;35&lt;/span&gt;       &lt;span class="r"&gt;end&lt;/span&gt;
&lt;span class="no"&gt;36&lt;/span&gt;     &lt;span class="r"&gt;end&lt;/span&gt;
&lt;span class="no"&gt;37&lt;/span&gt;     
&lt;span class="no"&gt;38&lt;/span&gt;     &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;view_list&lt;/span&gt;
&lt;span class="no"&gt;39&lt;/span&gt;       &lt;span class="iv"&gt;@d_arr&lt;/span&gt;.each_with_index {|d,i| puts &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="il"&gt;&lt;span class="idl"&gt;#{&lt;/span&gt;i + &lt;span class="i"&gt;1&lt;/span&gt;&lt;span class="idl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt;: &lt;/span&gt;&lt;span class="il"&gt;&lt;span class="idl"&gt;#{&lt;/span&gt;d&lt;span class="idl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;}
&lt;span class="no"&gt;&lt;strong&gt;40&lt;/strong&gt;&lt;/span&gt;       puts
&lt;span class="no"&gt;41&lt;/span&gt;       print &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;Choose a directory or quit(q): &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class="no"&gt;42&lt;/span&gt;       idx = gets.chomp!
&lt;span class="no"&gt;43&lt;/span&gt;       &lt;span class="r"&gt;if&lt;/span&gt; idx.downcase == &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;q&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class="no"&gt;44&lt;/span&gt;         exit
&lt;span class="no"&gt;45&lt;/span&gt;       &lt;span class="r"&gt;elsif&lt;/span&gt; (&lt;span class="i"&gt;1&lt;/span&gt;..&lt;span class="iv"&gt;@d_arr&lt;/span&gt;.size).include?(idx.to_i)
&lt;span class="no"&gt;46&lt;/span&gt;         exec &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;mate &lt;/span&gt;&lt;span class="il"&gt;&lt;span class="idl"&gt;#{&lt;/span&gt;&lt;span class="iv"&gt;@d_arr&lt;/span&gt;.at(idx.to_i - &lt;span class="i"&gt;1&lt;/span&gt;)&lt;span class="idl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class="no"&gt;47&lt;/span&gt;       &lt;span class="r"&gt;else&lt;/span&gt;
&lt;span class="no"&gt;48&lt;/span&gt;         puts &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;not a valid option&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class="no"&gt;49&lt;/span&gt;       &lt;span class="r"&gt;end&lt;/span&gt;
&lt;span class="no"&gt;&lt;strong&gt;50&lt;/strong&gt;&lt;/span&gt;     &lt;span class="r"&gt;end&lt;/span&gt;
&lt;span class="no"&gt;51&lt;/span&gt; 
&lt;span class="no"&gt;52&lt;/span&gt; &lt;span class="r"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I invoke the script like this -&lt;/p&gt;
&lt;pre class="console"&gt;
thor gemate:view GEM_NAME
&lt;/pre&gt;
&lt;p&gt;Yehuda wrote a &lt;a href="http://yehudakatz.com/2008/05/12/by-thors-hammer/"&gt;blog post&lt;/a&gt; that introduces Thor and provides a brief explanation of some of it&amp;#8217;s features. There is also a &lt;a href="http://github.com/wycats/thor/tree/master"&gt;GitHub repository&lt;/a&gt; that you can take a peek at if you&amp;#8217;re interested enough.&lt;/p&gt;
&lt;p&gt;The Force is strong with this one &amp;#8230;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://smuby.org/articles/2008/07/rake_and_sake_thor.html"&gt;Permalink&lt;/a&gt; | &lt;a href="http://smuby.org/articles/2008/07/rake_and_sake_thor.html#disqus_thread"&gt;comments(View)&lt;/a&gt;&lt;/p&gt;
&lt;script type="text/javascript" src="http://disqus.com/forums/smuby/embed.js"&gt;&lt;/script&gt;&lt;noscript&gt;&lt;a href="http://smuby.disqus.com/?url=ref"&gt;View the forum thread.&lt;/a&gt;&lt;/noscript&gt;&lt;p&gt;&lt;a href="http://disqus.com" class="dsq-brlink"&gt;blog comments powered by &lt;span class="logo-disqus"&gt;Disqus&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/smuby?a=cBqMkU9LjYg:Kxt1li568B0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/smuby?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/smuby?a=cBqMkU9LjYg:Kxt1li568B0:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/smuby?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/smuby?a=cBqMkU9LjYg:Kxt1li568B0:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/smuby?i=cBqMkU9LjYg:Kxt1li568B0:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/smuby/~4/cBqMkU9LjYg" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://smuby.org/articles/2008/07/rake_and_sake_thor.html</feedburner:origLink></entry>
  
  <entry>
    <title>Ruby for Kids: Hackety Hack</title>
    <link href="http://feedproxy.google.com/~r/smuby/~3/IEGsBPZVEts/ruby_kids_hackety_hack.html" />
    <id>tag:smuby.org,2008-06-24:1214334931</id>
    <updated>2008-06-24T20:15:31+01:00</updated>
<content type="html">
&lt;div class="span-14"&gt;
&lt;p&gt;&lt;img src="http://smuby.org/images/250px-Hackety-Star-Title.png" title="Hackety Hack Star" alt="Hackety Hack Star" /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;I decided to introduce our 11-year old daughter to Ruby today, but I wanted to do it in a kid-friendly way, rather than a crusty, adulty way. So, who else in the Ruby firmament does a body turn to when in need of coding entertainment &amp;#8211; you guessed it &amp;#8211; &lt;a href="http://en.wikipedia.org/wiki/Why_the_lucky_stiff"&gt;why the lucky stiff&lt;/a&gt; and his hacktastic &lt;a href="http://hacketyhack.net/"&gt;Hackety Hack&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Hackety is a Ruby coding environment aimed at kids of all ages. It has cartoons, an interactive tutorial, help pages and other things, all wrapped up in language pitched at your youngster. You can download it for Windows (XP, Vista) and Linux at the moment; a Mac OSX version is in the works.&lt;/p&gt;
&lt;p&gt;This is a great resource and a fun introduction to the world of programming with Ruby. Let your kids loose with it and see what they create. It certainly put a smile on my daughter&amp;#8217;s face.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://smuby.org/articles/2008/06/ruby_kids_hackety_hack.html"&gt;Permalink&lt;/a&gt; | &lt;a href="http://smuby.org/articles/2008/06/ruby_kids_hackety_hack.html#disqus_thread"&gt;comments(View)&lt;/a&gt;&lt;/p&gt;
&lt;script type="text/javascript" src="http://disqus.com/forums/smuby/embed.js"&gt;&lt;/script&gt;&lt;noscript&gt;&lt;a href="http://smuby.disqus.com/?url=ref"&gt;View the forum thread.&lt;/a&gt;&lt;/noscript&gt;&lt;p&gt;&lt;a href="http://disqus.com" class="dsq-brlink"&gt;blog comments powered by &lt;span class="logo-disqus"&gt;Disqus&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/smuby?a=IEGsBPZVEts:Wb8N877W01g:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/smuby?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/smuby?a=IEGsBPZVEts:Wb8N877W01g:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/smuby?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/smuby?a=IEGsBPZVEts:Wb8N877W01g:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/smuby?i=IEGsBPZVEts:Wb8N877W01g:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/smuby/~4/IEGsBPZVEts" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://smuby.org/articles/2008/06/ruby_kids_hackety_hack.html</feedburner:origLink></entry>
  
  <entry>
    <title>Shiny New Ruby Unix Shell: rush</title>
    <link href="http://feedproxy.google.com/~r/smuby/~3/eBMO0KWn-mM/ruby_unix_shell_rush.html" />
    <id>tag:smuby.org,2008-06-17:1213739275</id>
    <updated>2008-06-17T22:47:55+01:00</updated>
<content type="html">
&lt;div class="span-14"&gt;
&lt;p&gt;&lt;img src="http://smuby.org/images/shell.jpg" title="Picture of a shell" alt="Picture of a shell" /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="photo_credit span-14"&gt;&lt;a href="http://www.sxc.hu/profile/Ale_Paiva"&gt;PHOTO CREDIT: courtesy of Ale Paiva at sxc.hu&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://rush.heroku.com/"&gt;rush&lt;/a&gt; is an ambitious attempt, by Adam Wiggins, to bring some Ruby flavour to the venerable Unix shell.&lt;/p&gt;
&lt;p&gt;The idea is that you can use your beloved Ruby syntax in the rush shell to do those command line tasks that hitherto have been the province of &lt;a href="http://www.gnu.org/software/bash/"&gt;Bash&lt;/a&gt; and siblings. Additionally, rush is intended as a way to administer remote machines.&lt;/p&gt;
&lt;p class="code_title"&gt;An example from the rush website&lt;/p&gt;
&lt;pre class="console"&gt;
local = Rush::Box.new('localhost')
remote = Rush::Box.new('my.remote.server.com')
local_dir = local['/Users/adam/myproj/']
remote_dir = remote['/home/myproj/app/']

local_dir.copy_to remote_dir
remote_dir['**/.svn/'].each { |d| d.destroy }
&lt;/pre&gt;
&lt;p&gt;rush is still a callow youth, but offers up some interesting possibilities in the shadowy world of the shell.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://smuby.org/articles/2008/06/ruby_unix_shell_rush.html"&gt;Permalink&lt;/a&gt; | &lt;a href="http://smuby.org/articles/2008/06/ruby_unix_shell_rush.html#disqus_thread"&gt;comments(View)&lt;/a&gt;&lt;/p&gt;
&lt;script type="text/javascript" src="http://disqus.com/forums/smuby/embed.js"&gt;&lt;/script&gt;&lt;noscript&gt;&lt;a href="http://smuby.disqus.com/?url=ref"&gt;View the forum thread.&lt;/a&gt;&lt;/noscript&gt;&lt;p&gt;&lt;a href="http://disqus.com" class="dsq-brlink"&gt;blog comments powered by &lt;span class="logo-disqus"&gt;Disqus&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/smuby?a=eBMO0KWn-mM:eMijVgFXXH4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/smuby?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/smuby?a=eBMO0KWn-mM:eMijVgFXXH4:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/smuby?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/smuby?a=eBMO0KWn-mM:eMijVgFXXH4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/smuby?i=eBMO0KWn-mM:eMijVgFXXH4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/smuby/~4/eBMO0KWn-mM" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://smuby.org/articles/2008/06/ruby_unix_shell_rush.html</feedburner:origLink></entry>
  
  <entry>
    <title>Devilishly Simple Background Ruby: Daemons</title>
    <link href="http://feedproxy.google.com/~r/smuby/~3/Bx1CyY8Ojng/simple_background_ruby_daemons.html" />
    <id>tag:smuby.org,2008-06-15:1213557952</id>
    <updated>2008-06-15T20:25:52+01:00</updated>
<content type="html">
&lt;div class="span-14"&gt;
&lt;p&gt;&lt;img src="http://smuby.org/images/devil.jpg" title="Picture of a paper devil" alt="Picture of a paper devil" /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="photo_credit span-14"&gt;&lt;a href="http://www.sxc.hu/profile/spekulator"&gt;PHOTO CREDIT: courtesy of spekulator at sxc.hu&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;If you&amp;#8217;re looking for a super simple way to daemonize a Ruby script then have a sneaky peek at &lt;a href="http://daemons.rubyforge.org/"&gt;Daemons&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This description from the site sums up what the deal is with Daemons -&lt;/p&gt;
&lt;blockquote cite="http://daemons.rubyforge.org/"&gt;Daemons provides an easy way to wrap existing ruby scripts (for example a self-written server) to be run as a daemon and to be controlled by simple &lt;strong&gt;start/stop/restart&lt;/strong&gt; commands.&lt;/blockquote&gt;
&lt;p&gt;All you need do if you want a Ruby script to run in the background as a daemon, say my_app.rb, is to wrap a call to my_app.rb like this -&lt;/p&gt;
&lt;p class="code_title"&gt;my_app_control.rb&lt;/p&gt;
&lt;div class="CodeRay"&gt;&lt;pre&gt;&lt;span class="no"&gt; 1&lt;/span&gt; &lt;span class="c"&gt;#!/usr/bin/env ruby&lt;/span&gt;
&lt;span class="no"&gt; 2&lt;/span&gt; 
&lt;span class="no"&gt; 3&lt;/span&gt; &lt;span class="c"&gt;# This is my_app_control.rb. It allows you to daemonize my_app.rb&lt;/span&gt;
&lt;span class="no"&gt; 4&lt;/span&gt; &lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="no"&gt; 5&lt;/span&gt; &lt;span class="c"&gt;# Usage: ruby my_app_control.rb [start|stop|restart]&lt;/span&gt;
&lt;span class="no"&gt; 6&lt;/span&gt; &lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="no"&gt; 7&lt;/span&gt; 
&lt;span class="no"&gt; 8&lt;/span&gt; require &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;rubygems&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class="no"&gt; 9&lt;/span&gt; require &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;daemons&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class="no"&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;/span&gt; 
&lt;span class="no"&gt;11&lt;/span&gt; &lt;span class="co"&gt;Daemons&lt;/span&gt;.run(&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;my_app.rb&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;)
&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If you enter this at the console -&lt;/p&gt;
&lt;pre class="console"&gt;
ruby my_app_control.rb start
&lt;/pre&gt;
&lt;p&gt;The script __my_app.rb__ will start in the background, and a pid file will be created containing the process id of your newly spawned task. Unfortunately, because of the way that Daemons works, it is not easy to get feedback by way of console messages with a &lt;i&gt;puts&lt;/i&gt; or &lt;i&gt;print&lt;/i&gt; call, but you do have the option to log output to a file.&lt;/p&gt;
&lt;p&gt;There are some other ways in which Daemons can be utilised that are well documented on the site. Nice, neat, try it.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://smuby.org/articles/2008/06/simple_background_ruby_daemons.html"&gt;Permalink&lt;/a&gt; | &lt;a href="http://smuby.org/articles/2008/06/simple_background_ruby_daemons.html#disqus_thread"&gt;comments(View)&lt;/a&gt;&lt;/p&gt;
&lt;script type="text/javascript" src="http://disqus.com/forums/smuby/embed.js"&gt;&lt;/script&gt;&lt;noscript&gt;&lt;a href="http://smuby.disqus.com/?url=ref"&gt;View the forum thread.&lt;/a&gt;&lt;/noscript&gt;&lt;p&gt;&lt;a href="http://disqus.com" class="dsq-brlink"&gt;blog comments powered by &lt;span class="logo-disqus"&gt;Disqus&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/smuby?a=Bx1CyY8Ojng:uotkxwwJtgM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/smuby?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/smuby?a=Bx1CyY8Ojng:uotkxwwJtgM:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/smuby?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/smuby?a=Bx1CyY8Ojng:uotkxwwJtgM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/smuby?i=Bx1CyY8Ojng:uotkxwwJtgM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/smuby/~4/Bx1CyY8Ojng" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://smuby.org/articles/2008/06/simple_background_ruby_daemons.html</feedburner:origLink></entry>
  
  <entry>
    <title>Ruby Web Application Plumbing: Rack</title>
    <link href="http://feedproxy.google.com/~r/smuby/~3/oa9-7e417g8/web_application_plumbing_rack.html" />
    <id>tag:smuby.org,2008-06-09:1213040392</id>
    <updated>2008-06-09T20:39:52+01:00</updated>
<content type="html">
&lt;div class="span-14"&gt;
&lt;p&gt;&lt;img src="http://smuby.org/images/rack-logo.png" title="Rack logo" alt="Rack logo" /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;There has been a proliferation of Ruby web application frameworks in recent times and this is mainly due to one thing; &lt;a href="http://rack.rubyforge.org"&gt;Rack&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Rack is a &amp;#8220;Ruby webserver interface&amp;#8221; that provides the plumbing for a Ruby web application framework to communicate with a webserver via an adapter. HTTP requests and responses are routed to the appropriate destinations with various niceties, like Apache-style logging, taken care of by Rack.&lt;/p&gt;
&lt;p&gt;If your needs are simple, and a framework would be overkill, just use Rack on its own and code any little extras yourself. Visit the &lt;a href="http://rack.rubyforge.org"&gt;site&lt;/a&gt; for a list of frameworks that use Rack as well as a list of supported web servers.&lt;/p&gt;
&lt;p&gt;I cannot stress this enough &amp;#8211; if you are considering building YARWF (Yet Another Ruby Web Framework, pronounced &amp;#8216;Yar-woof&amp;#8217;) &lt;em&gt;you need to be looking at Rack&lt;/em&gt;. It contains a lot of the basic infrastructure to get you started and is rapidly becoming a de facto standard in this space, even though it is only at release 0.3 at the time of writing.&lt;/p&gt;
&lt;p&gt;To give you an idea of why people are excited about what Rack brings to the party, install Rack -&lt;/p&gt;
&lt;pre class="console"&gt;
sudo gem install rack
&lt;/pre&gt;
&lt;p&gt;Next, put the following in a file with a .rb suffix and run it -&lt;/p&gt;
&lt;p class="code_title"&gt;taken from &lt;a href="http://yeahnah.org/files/rack-presentation-oct-07.pdf"&gt;yeahnah.org&lt;/a&gt;&lt;/p&gt;
&lt;div class="CodeRay"&gt;&lt;pre&gt;&lt;span class="no"&gt;1&lt;/span&gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;%w(&lt;/span&gt;&lt;span class="k"&gt;rubygems rack&lt;/span&gt;&lt;span class="dl"&gt;)&lt;/span&gt;&lt;/span&gt;.each { |dep| require dep } 
&lt;span class="no"&gt;2&lt;/span&gt; app = lambda { |env| [&lt;span class="i"&gt;200&lt;/span&gt;, {}, &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;Hello World!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;] } 
&lt;span class="no"&gt;3&lt;/span&gt; &lt;span class="co"&gt;Rack&lt;/span&gt;::&lt;span class="co"&gt;Handler&lt;/span&gt;::&lt;span class="co"&gt;Mongrel&lt;/span&gt;.run(app, &lt;span class="sy"&gt;:Port&lt;/span&gt; =&amp;gt; &lt;span class="i"&gt;3000&lt;/span&gt;)
&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Yes that&amp;#8217;s right, a working web app in 3 &amp;#8211; count them &amp;#8211; 3 lines of code.&lt;/p&gt;
&lt;p&gt;There is a whole new Internet town growing up, filled with web houses that Rack built.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://smuby.org/articles/2008/06/web_application_plumbing_rack.html"&gt;Permalink&lt;/a&gt; | &lt;a href="http://smuby.org/articles/2008/06/web_application_plumbing_rack.html#disqus_thread"&gt;comments(View)&lt;/a&gt;&lt;/p&gt;
&lt;script type="text/javascript" src="http://disqus.com/forums/smuby/embed.js"&gt;&lt;/script&gt;&lt;noscript&gt;&lt;a href="http://smuby.disqus.com/?url=ref"&gt;View the forum thread.&lt;/a&gt;&lt;/noscript&gt;&lt;p&gt;&lt;a href="http://disqus.com" class="dsq-brlink"&gt;blog comments powered by &lt;span class="logo-disqus"&gt;Disqus&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/smuby?a=oa9-7e417g8:Jdu7pKMu6TE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/smuby?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/smuby?a=oa9-7e417g8:Jdu7pKMu6TE:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/smuby?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/smuby?a=oa9-7e417g8:Jdu7pKMu6TE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/smuby?i=oa9-7e417g8:Jdu7pKMu6TE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/smuby/~4/oa9-7e417g8" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://smuby.org/articles/2008/06/web_application_plumbing_rack.html</feedburner:origLink></entry>
  
</feed>
