<?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" xml:lang="en"><title type="text">::blowmage::</title><link rel="alternate" type="text/html" href="http://blowmage.com/" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/blowmage" /><author><name>Mike Moore</name><email>mike@blowmage.com</email></author><updated>2011-11-14T17:34:18+00:00</updated><feedburner:info uri="blowmage" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><id>http://blowmage.com/</id><geo:lat>40.38584</geo:lat><geo:long>-111.733334</geo:long><feedburner:browserFriendly>This is an XML content feed. It is intended to be viewed in a newsreader or syndicated to another site, subject to copyright and fair use.</feedburner:browserFriendly><entry><title type="text">Rubiverse Podcast Lives!</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blowmage/~3/2safSKSygPg/rubiverse-lives" /><updated>2011-05-16T00:00:00-07:00</updated><id>http://blowmage.com/2011/05/16/rubiverse-lives</id><content type="html">&lt;p&gt;Okay, so its been a couple years. So what? Big deal. What is a short 768 day hiatus between friends? The good news is that my &lt;a href="http://rubiverse.com/"&gt;Ruby podcast&lt;/a&gt; is back. And not just one episode back. I&amp;#8217;ve published three episodes recently with with Brian Ford, Nathan Esquenazi, and Wayne Seguin. I&amp;#8217;m really happy with them and excited for a future with many more interesting conversations.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://rubiverse.com/podcasts/11-wayne-seguin-on-rvm-and-bdsm"&gt;I spoke with Wayne Seguin&lt;/a&gt; about his über popular &lt;a href="http://rvm.beginrescueend.com/"&gt;&lt;span class="caps"&gt;RVM&lt;/span&gt;&lt;/a&gt; and his plans to rewrite it using his up and coming &lt;a href="http://bdsm.beginrescueend.com/"&gt;&lt;span class="caps"&gt;BDSM&lt;/span&gt; framework&lt;/a&gt;. &lt;span class="caps"&gt;BDSM&lt;/span&gt; is interesting because it provides a bit more structure to the default shell environment and in my mind holds the promise that more can contribute to &lt;span class="caps"&gt;RVM&lt;/span&gt;. I expect great things from this in the future.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://rubiverse.com/podcasts/10-nathan-esquenazi-on-padrino"&gt;I spoke with Nathan Esquenazi&lt;/a&gt; about the &lt;a href="http://www.padrinorb.com/"&gt;Padrino&lt;/a&gt; web micro-framework and its take on creating modular web applications. I&amp;#8217;m excited for more modularity in our web apps, and think Padrino is on the right track.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://rubiverse.com/podcasts/9-brian-ford-on-rubinius"&gt;I also spoke with Brian Ford&lt;/a&gt; about the history and future of &lt;a href="http://rubini.us/"&gt;Rubinius&lt;/a&gt;. Rubinius seems to be on the verge of tipping over and being a viable Ruby implementation for mainstream applications. I&amp;#8217;m very excited for this and hope that the release of 2.0 pushed it over the edge.&lt;/p&gt;
&lt;p&gt;This is just the start. I&amp;#8217;m committed to more conversations with interesting Rubyists. Who would you like to hear from? Let me know and I&amp;#8217;ll make it happen.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blowmage/~4/2safSKSygPg" height="1" width="1"/&gt;</content><feedburner:origLink>http://blowmage.com/2011/05/16/rubiverse-lives</feedburner:origLink></entry><entry><title type="text">Binary Lottery 2008</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blowmage/~3/MKy15-ebKu8/binary-lottery-2008" /><updated>2008-03-30T00:00:00-07:00</updated><id>http://blowmage.com/2008/03/30/binary-lottery-2008</id><content type="html">&lt;p&gt;This year at &lt;a href="http://mtnwestrubyconf.org/"&gt;MountainWest RubyConf 2008&lt;/a&gt; we had a slew of books and t-shirts to give away to attendees. Like last year we printed each attendee's unique number on their badge in base 2 (binary). We would then randomly select a winner from the attendee list. But we would use their binary number in the reveal, showing only one number at a time. It might be cheesy, but we really enjoy it so deal. :)&lt;/p&gt;
&lt;p&gt;This is what the badges looked like:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/binary-lottery-2008/badge.jpg" width="500" height="375" alt="My MWRC Badge. I'm number 11111111 because I made the badges. Its my right as an organizer! :)"/&gt;&lt;/p&gt;
&lt;p&gt;Last year I wrote a command line app that used &lt;a href="http://www.figlet.org/"&gt;figlet&lt;/a&gt; to display the winner. You can see the &lt;a href="http://mtnwestrubyconf2007.confreaks.com/session07.html"&gt;video of last year's Lightning Talk&lt;/a&gt; where I show the code if you are interested. This year I wanted to mix it up a bit, and I decided about 10 hours before the conference to try my hand at using &lt;a href="http://whytheluckystiff.net/"&gt;_why&lt;/a&gt;'s &lt;a href="http://code.whytheluckystiff.net/shoes/"&gt;Shoes&lt;/a&gt; to build a GUI version. So here it is:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="lineno"&gt; 1&lt;/span&gt; &lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;yaml&amp;#39;&lt;/span&gt;
&lt;span class="lineno"&gt; 2&lt;/span&gt; 
&lt;span class="lineno"&gt; 3&lt;/span&gt; &lt;span class="c1"&gt;# The source of much evil...&lt;/span&gt;
&lt;span class="lineno"&gt; 4&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;update_digit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cnt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;wnr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="lineno"&gt; 5&lt;/span&gt;   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;cnt&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;dig&lt;/span&gt;
&lt;span class="lineno"&gt; 6&lt;/span&gt;     &lt;span class="nb"&gt;p&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;replace&lt;/span&gt; &lt;span class="nb"&gt;rand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="lineno"&gt; 7&lt;/span&gt;   &lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="lineno"&gt; 8&lt;/span&gt;     &lt;span class="nb"&gt;p&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;replace&lt;/span&gt; &lt;span class="n"&gt;wnr&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;dig&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;chr&lt;/span&gt;
&lt;span class="lineno"&gt; 9&lt;/span&gt;     &lt;span class="nb"&gt;p&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;style&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:stroke&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;red&lt;/span&gt;
&lt;span class="lineno"&gt;10&lt;/span&gt;   &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="lineno"&gt;11&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="lineno"&gt;12&lt;/span&gt; 
&lt;span class="lineno"&gt;13&lt;/span&gt; &lt;span class="c1"&gt;# Use the full path because either Shoes is easily confused, or I am&lt;/span&gt;
&lt;span class="lineno"&gt;14&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;YAML&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;/Users/blowmage/Lottery/users.yaml&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="lineno"&gt;15&lt;/span&gt; &lt;span class="n"&gt;winner&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;rand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="k"&gt;until&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;winner&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;winner&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:eligible&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="lineno"&gt;16&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="lineno"&gt;17&lt;/span&gt; 
&lt;span class="lineno"&gt;18&lt;/span&gt; &lt;span class="no"&gt;Shoes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="ss"&gt;:width&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;900&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:height&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;700&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="lineno"&gt;19&lt;/span&gt;   &lt;span class="n"&gt;keypress&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="lineno"&gt;20&lt;/span&gt;     &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="lineno"&gt;21&lt;/span&gt;   &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="lineno"&gt;22&lt;/span&gt;   &lt;span class="n"&gt;stack&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="lineno"&gt;23&lt;/span&gt;     &lt;span class="n"&gt;para&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;MountainWest RubyConf 2008 Binary Lottery&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="lineno"&gt;24&lt;/span&gt;       &lt;span class="s2"&gt;&amp;quot;And your winner is...&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:font&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Helvetica 48px&amp;#39;&lt;/span&gt;
&lt;span class="lineno"&gt;25&lt;/span&gt;     &lt;span class="n"&gt;lbl_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;para&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:font&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Helvetica 128px&amp;#39;&lt;/span&gt;
&lt;span class="lineno"&gt;26&lt;/span&gt;     &lt;span class="n"&gt;flow&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="lineno"&gt;27&lt;/span&gt;       &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;para&lt;/span&gt; &lt;span class="nb"&gt;rand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="ss"&gt;:font&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Helvetica 192px&amp;#39;&lt;/span&gt;
&lt;span class="lineno"&gt;28&lt;/span&gt;       &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;para&lt;/span&gt; &lt;span class="nb"&gt;rand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="ss"&gt;:font&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Helvetica 192px&amp;#39;&lt;/span&gt;
&lt;span class="lineno"&gt;29&lt;/span&gt;       &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;para&lt;/span&gt; &lt;span class="nb"&gt;rand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="ss"&gt;:font&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Helvetica 192px&amp;#39;&lt;/span&gt;
&lt;span class="lineno"&gt;30&lt;/span&gt;       &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;para&lt;/span&gt; &lt;span class="nb"&gt;rand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="ss"&gt;:font&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Helvetica 192px&amp;#39;&lt;/span&gt;
&lt;span class="lineno"&gt;31&lt;/span&gt;       &lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;para&lt;/span&gt; &lt;span class="nb"&gt;rand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="ss"&gt;:font&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Helvetica 192px&amp;#39;&lt;/span&gt;
&lt;span class="lineno"&gt;32&lt;/span&gt;       &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;para&lt;/span&gt; &lt;span class="nb"&gt;rand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="ss"&gt;:font&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Helvetica 192px&amp;#39;&lt;/span&gt;
&lt;span class="lineno"&gt;33&lt;/span&gt;       &lt;span class="n"&gt;g&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;para&lt;/span&gt; &lt;span class="nb"&gt;rand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="ss"&gt;:font&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Helvetica 192px&amp;#39;&lt;/span&gt;
&lt;span class="lineno"&gt;34&lt;/span&gt;       &lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;para&lt;/span&gt; &lt;span class="nb"&gt;rand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="ss"&gt;:font&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Helvetica 192px&amp;#39;&lt;/span&gt;
&lt;span class="lineno"&gt;35&lt;/span&gt; 
&lt;span class="lineno"&gt;36&lt;/span&gt;       &lt;span class="n"&gt;animate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="lineno"&gt;37&lt;/span&gt;         &lt;span class="n"&gt;update_digit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;winner&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:number&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="lineno"&gt;38&lt;/span&gt;         &lt;span class="n"&gt;update_digit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;winner&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:number&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="lineno"&gt;39&lt;/span&gt;         &lt;span class="n"&gt;update_digit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;winner&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:number&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="lineno"&gt;40&lt;/span&gt;         &lt;span class="n"&gt;update_digit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;winner&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:number&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="lineno"&gt;41&lt;/span&gt;         &lt;span class="n"&gt;update_digit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;winner&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:number&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="lineno"&gt;42&lt;/span&gt;         &lt;span class="n"&gt;update_digit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;winner&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:number&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="lineno"&gt;43&lt;/span&gt;         &lt;span class="n"&gt;update_digit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;winner&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:number&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="lineno"&gt;44&lt;/span&gt;         &lt;span class="n"&gt;update_digit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;winner&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:number&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="lineno"&gt;45&lt;/span&gt; 
&lt;span class="lineno"&gt;46&lt;/span&gt;         &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;
&lt;span class="lineno"&gt;47&lt;/span&gt;           &lt;span class="n"&gt;lbl_name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;replace&lt;/span&gt; &lt;span class="n"&gt;winner&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="lineno"&gt;48&lt;/span&gt;         &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="lineno"&gt;49&lt;/span&gt;         &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;
&lt;span class="lineno"&gt;50&lt;/span&gt;           &lt;span class="c1"&gt;# Click one more time to flag the user so they won&amp;#39;t win again.&lt;/span&gt;
&lt;span class="lineno"&gt;51&lt;/span&gt;           &lt;span class="n"&gt;lbl_name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;style&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:stroke&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;red&lt;/span&gt;
&lt;span class="lineno"&gt;52&lt;/span&gt;           &lt;span class="n"&gt;winner&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:eligible&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
&lt;span class="lineno"&gt;53&lt;/span&gt;           &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;/Users/blowmage/Lottery/users.yaml&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;w&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="lineno"&gt;54&lt;/span&gt;             &lt;span class="no"&gt;YAML&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dump&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;out&lt;/span&gt;
&lt;span class="lineno"&gt;55&lt;/span&gt;           &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="lineno"&gt;56&lt;/span&gt;         &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="lineno"&gt;57&lt;/span&gt;       &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="lineno"&gt;58&lt;/span&gt;     &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="lineno"&gt;59&lt;/span&gt;   &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="lineno"&gt;60&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Here is a sample of what the &lt;code&gt;users.yaml&lt;/code&gt; file looked like:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="yaml"&gt;&lt;span class="lineno"&gt; 1&lt;/span&gt; &lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="lineno"&gt; 2&lt;/span&gt; &lt;span class="p-Indicator"&gt;-&lt;/span&gt; &lt;span class="l-Scalar-Plain"&gt;:number&lt;/span&gt;&lt;span class="p-Indicator"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;00000000&amp;quot;&lt;/span&gt;
&lt;span class="lineno"&gt; 3&lt;/span&gt;   &lt;span class="l-Scalar-Plain"&gt;:name&lt;/span&gt;&lt;span class="p-Indicator"&gt;:&lt;/span&gt; &lt;span class="l-Scalar-Plain"&gt;Jonathan Younger&lt;/span&gt;
&lt;span class="lineno"&gt; 4&lt;/span&gt;   &lt;span class="l-Scalar-Plain"&gt;:eligible&lt;/span&gt;&lt;span class="p-Indicator"&gt;:&lt;/span&gt; &lt;span class="l-Scalar-Plain"&gt;true&lt;/span&gt;
&lt;span class="lineno"&gt; 5&lt;/span&gt; &lt;span class="p-Indicator"&gt;-&lt;/span&gt; &lt;span class="l-Scalar-Plain"&gt;:number&lt;/span&gt;&lt;span class="p-Indicator"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;00000001&amp;quot;&lt;/span&gt;
&lt;span class="lineno"&gt; 6&lt;/span&gt;   &lt;span class="l-Scalar-Plain"&gt;:name&lt;/span&gt;&lt;span class="p-Indicator"&gt;:&lt;/span&gt; &lt;span class="l-Scalar-Plain"&gt;Brian Cooke&lt;/span&gt;
&lt;span class="lineno"&gt; 7&lt;/span&gt;   &lt;span class="l-Scalar-Plain"&gt;:eligible&lt;/span&gt;&lt;span class="p-Indicator"&gt;:&lt;/span&gt; &lt;span class="l-Scalar-Plain"&gt;false&lt;/span&gt;
&lt;span class="lineno"&gt; 8&lt;/span&gt; &lt;span class="p-Indicator"&gt;-&lt;/span&gt; &lt;span class="l-Scalar-Plain"&gt;:number&lt;/span&gt;&lt;span class="p-Indicator"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;00000010&amp;quot;&lt;/span&gt;
&lt;span class="lineno"&gt; 9&lt;/span&gt;   &lt;span class="l-Scalar-Plain"&gt;:name&lt;/span&gt;&lt;span class="p-Indicator"&gt;:&lt;/span&gt; &lt;span class="l-Scalar-Plain"&gt;Justin Kay&lt;/span&gt;
&lt;span class="lineno"&gt;10&lt;/span&gt;   &lt;span class="l-Scalar-Plain"&gt;:eligible&lt;/span&gt;&lt;span class="p-Indicator"&gt;:&lt;/span&gt; &lt;span class="l-Scalar-Plain"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Here is what the app looked like while running:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/binary-lottery-2008/shoes.gif" width="500" height="254" alt="Binary Lottery written in Shoes"/&gt;&lt;/p&gt;
&lt;p&gt;Logan Barnett also wrote a GUI using &lt;a href="http://jruby.codehaus.org/"&gt;JRuby&lt;/a&gt; and &lt;a href="http://monkeybars.rubyforge.org/"&gt;MonkeyBars&lt;/a&gt;. I really hope he releases his version as well. Here is what the app looked like on the third draw, sort of an easter egg I discovered during the conference:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/binary-lottery-2008/monkeybars.jpg" width="500" height="374" alt="Binary Lottery written in JRuby with MonkeyBars"/&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blowmage/~4/MKy15-ebKu8" height="1" width="1"/&gt;</content><feedburner:origLink>http://blowmage.com/2008/03/30/binary-lottery-2008</feedburner:origLink></entry><entry><title type="text">Ruby Folk Are Nice</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blowmage/~3/jGu5H7oX-d8/ruby-folk-are-nice" /><updated>2008-03-29T00:00:00-07:00</updated><id>http://blowmage.com/2008/03/29/ruby-folk-are-nice</id><content type="html">&lt;p&gt;We&amp;#8217;re in the midst of &lt;a href="http://mtnwestrubyconf.org/"&gt;MountainWest RubyConf 2008&lt;/a&gt;, and I have lots I want to blog about it. But before I get there, and before I take a 36 hour nap, I just want to let you know how nice Ruby folk are. This may be a fairly simple example, but I want to share it anyway.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;m one of the organizers of the conference, and that has meant that I miss about half the conference sessions because I&amp;#8217;m running around trying to fix the power or fix the wifi or organize the distribution of food. On Friday we had a really delicious lunch from &lt;a href="http://www.rumbi.com/"&gt;Rumbi&amp;#8217;s&lt;/a&gt;, but it left the conference room we ate in rather messy. We paid a cleaning deposit, but the trash needed to be collected and the room straightened. I was informed of this just as we were breaking for dinner and I told them we would fix it before the evening session. I ended up stressing over this for the entire dinner break because I hate the idea of inconveniencing the great people at the &lt;a href="http://www.slcpl.lib.ut.us/locations.jsp?parent_id=8&amp;#38;page_id=20"&gt;Salt Lake City library&lt;/a&gt; who have been so accommodating towards the 200 geeks who descended upon them destroying their power circuits and their wifi.&lt;/p&gt;
&lt;p&gt;I got back from dinner just 20 minutes before the evening session, and called out to the ~30 folks milling around in the foyer asking for help cleaning the room up.  We had ~8 people in the room and had the whole thing straightened up in under 5 minutes. That&amp;#8217;s awesome.&lt;/p&gt;
&lt;p&gt;And to add to this, as we left at the end of the day I asked if everyone could pick up their empty water bottles. After chatting with some folks I walked out and the entire auditorium was cleaned out. Not a water bottle in site. Now this may seem like two very small things, but this means the world to me. It shows respect for the venue and I appreciate it very much. Thanks guys!&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ve had so much fun at the conference this year. I&amp;#8217;ve fully enjoyed meeting new people and talking with everyone I&amp;#8217;ve been able talk with. We have a wide variety of folks attending this year; from the mind-bendingly smart gurus to the total noobs. But everyone is getting along and helping each other become better. Not just better technically in regards to Ruby, but I honestly believe that we are helping each other become better people as well. There is a great vibe here, I wish everyone could experience it.&lt;/p&gt;
&lt;p&gt;I know we set the bar pretty high last year, but I think we on our way to being even better this year.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blowmage/~4/jGu5H7oX-d8" height="1" width="1"/&gt;</content><feedburner:origLink>http://blowmage.com/2008/03/29/ruby-folk-are-nice</feedburner:origLink></entry><entry><title type="text">IronRuby + C# = Awesomeness</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blowmage/~3/Qtcr2JSFty4/ironruby-csharp-awesomeness" /><updated>2008-03-10T00:00:00-07:00</updated><id>http://blowmage.com/2008/03/10/ironruby-csharp-awesomeness</id><content type="html">&lt;p&gt;Saturday I gave a session at the third &lt;a href="http://www.boisecodecamp.org/"&gt;Boise Code Camp&lt;/a&gt;. &lt;a href="http://www.cityofboise.org/"&gt;Boise&lt;/a&gt; is my home town, so I am always happy to get back and enjoy the nostalgia.  The Boise Code Camp this year was huge! As of Saturday morning there were 495 folks registered to attend, and 370 that were actually there. Crazy. Much props to the folks running it this year.  Having helped organize the first Boise Code Camp and organized both MountainWest RubyConfs I know how hard they worked to pull this off. Great work guys!&lt;/p&gt;
&lt;p&gt;Here are some of my notes for my session. I use a modified &lt;a href="http://presentationzen.blogs.com/presentationzen/2005/09/living_large_ta.html"&gt;Takahashi Method&lt;/a&gt; of presentation, so my slide deck doesn&amp;#8217;t make much sense by itself. Also, I only gave three demos, and the code was really simple because I can&amp;#8217;t type and talk at the same time. Another reason for limited demo code is that alot of these concepts are new to folks so I wanted to go slow and make sure I brought everyone along. Disclaimer finished, here is the &lt;a href="http://blowmage.com/assets/2008/3/10/ironruby-csharp-awesomeness.pdf"&gt;slide deck&lt;/a&gt; and the &lt;a href="http://blowmage.com/assets/2008/3/10/ironruby-csharp-awesomeness.zip"&gt;code&lt;/a&gt;. (Watch for the random Spider-Man appearance.)&lt;/p&gt;
&lt;h3&gt;Can a Computer Language be Beautiful?&lt;/h3&gt;
&lt;p&gt;I believe that software developers tend to create an exclusive culture around their technical knowledge. Most think that you need to &amp;#8220;earn&amp;#8221; your knowledge, and will respond to naive questions with answers such as &amp;#8220;RTFM&amp;#8221; or &amp;#8220;Just Google it&amp;#8221;. While this is understandable I think this attitude hurts more than it helps in the long run.&lt;/p&gt;
&lt;p&gt;Seeing as the majority of sessions are Microsoft-centric, I kept my observations to Microsoft technologies. I&amp;#8217;ve got my own path through Microsoft technologies and really came to my own on &amp;#8220;classic&amp;#8221; &lt;span class="caps"&gt;ASP&lt;/span&gt;. ASP and &lt;span class="caps"&gt;COM&lt;/span&gt; were a great leap forward for web programming compared to what we were using before, but it was typical to end up with spaghetti code. The introduction of .NET was seen as a solution to &lt;span class="caps"&gt;ASP&lt;/span&gt;&amp;#8217;s &amp;#8220;loose&amp;#8221; code, but it came at a cost of restricting how expressive our code could be, making beautiful code more difficult&lt;/p&gt;
&lt;p&gt;It shouldn&amp;#8217;t come as a surprise that Ruby folks refer to Ruby code as &amp;#8220;beautiful&amp;#8221;. This is one of the things that I really love about the Ruby community. Ruby&amp;#8217;s notion of Object Orientation is fundamentally different that C++/Java/C#. And Ruby&amp;#8217;s meta-programming enables you to place responsibility where it belongs, and write expressive code by avoiding the accidental complexity typical of static language. This is why I like to think of Ruby as beautiful.&lt;/p&gt;
&lt;p&gt;I gave the example of trying to enable sorting of domain objects in a DataGridView control, because that just happened to come up yesterday. The .NET solution is to inherit from BindingList&lt;T&gt; and implement 4 properties and 2 methods. The Ruby solution is to simply call the array&amp;#8217;s &lt;code&gt;sort_by&lt;/code&gt; passing a block of how you want the item&amp;#8217;s sort value to be calculated. My point being that Ruby code tends to rely on on the trust of the developer, while there is no way to quantify that trust in statically-compiled C#.&lt;/p&gt;
&lt;h3&gt;What is Polyglot Programming?&lt;/h3&gt;
&lt;p&gt;Another term for &amp;#8220;Polyglot Programming&amp;#8221; can be &amp;#8220;Language Oriented Programming&amp;#8221;, or using the right tool for the right job. I asked the folks attending if their language is right for their task, and a few responded that they thought C# was indeed the right language. I countered by putting forth my opinion that unless it is a domain specific language it probably isn&amp;#8217;t the right language. DSLs can express the domain instructions without all the cruft or implementation instructions. I&amp;#8217;m not sure how well this was received, as most seemed skeptical.&lt;/p&gt;
&lt;p&gt;I also soap-boxed a bit about some developers defending C# to their dying breath, and the irony that the &lt;span class="caps"&gt;CLR&lt;/span&gt; was intended for multiple languages. Then I went into my belief that static languages are not the future, and in 5 years we will be using a dynamic language for the majority of work we are using static languages for today. You can read more about my thoughts on this &lt;a href="http://blowmage.com/2006/2/17/ruby-thinking"&gt;here&lt;/a&gt; and &lt;a href="http://blowmage.com/2007/12/18/the-rubification-of-csharp"&gt;here&lt;/a&gt; and &lt;a href="http://blowmage.com/2007/12/19/static-languages-are-fail"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;But I don&amp;#8217;t believe that C# will or should go away. C# will still be the best language for system-level coding, because it is so aligned to the &lt;span class="caps"&gt;CLR&lt;/span&gt;. What I do believe is that we will stack dynamic languages on top of the static languages, and DSLs on top of the dynamic languages. You can hear more about this in my &lt;a href="http://rubiverse.com/podcasts/5-ola-bini-on-polyglot-programming"&gt;Rubiverse Podcast with Ola Bini&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;What can IronRuby do now?&lt;/h3&gt;
&lt;p&gt;IronRuby is not complete and therefore not 100% compatible with &lt;span class="caps"&gt;MRI&lt;/span&gt;. But, there are some great things that we can do with IronRuby today. I gave four examples of how we can use IronRuby now. I didn&amp;#8217;t have a demo for the testing though, I ran out of time.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Calling and using .NET objects from IronRuby&lt;/li&gt;
  &lt;li&gt;Replacing tests written in C# with tests written in IronRuby&lt;/li&gt;
  &lt;li&gt;Replacing application code written in C# with code in IronRuby&lt;/li&gt;
  &lt;li&gt;Provide Scripting in Application&lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://feeds.feedburner.com/~r/blowmage/~4/Qtcr2JSFty4" height="1" width="1"/&gt;</content><feedburner:origLink>http://blowmage.com/2008/03/10/ironruby-csharp-awesomeness</feedburner:origLink></entry><entry><title type="text">The Blizzard of 2008</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blowmage/~3/CHXOk52tUtk/blizzard" /><updated>2008-02-14T00:00:00-08:00</updated><id>http://blowmage.com/2008/02/14/blizzard</id><content type="html">&lt;p&gt;Please excuse this non-geeky post, but today was harrowing and quite the tale. We came home from my grandmother&amp;#8217;s funeral yesterday. We drove from Boise, ID to Cedar Hills, UT. The trip usually takes five hours, but yesterday it took nine due to major road work at Ogden, and a complete freeway closure north of Salt Lake City. My wife was scheduled to work the evening shift at the hospital that night, but the delays were too much and she didn&amp;#8217;t make it in. Also, you can imagine how unhappy our two young girls were from sitting in the car for so long.&lt;/p&gt;
&lt;p&gt;Today, we got the &lt;a href="http://www.ksl.com/?nid=148&amp;#38;sid=2659200"&gt;worst winter storm&lt;/a&gt; I have ever seen. On the way home from appointments in Salt Lake City, my wife and two girls got stuck in huge traffic jam due to the snow storm on the road home. This was just a couple miles from my work, where I was not allowed to leave because of the storm. I became increasingly worried, even more when my wife tried to turn around and got the car stuck in a snow drift. For two hours my little family was stuck and the girls became increasingly stir crazy while strapped in their car seats. Fortunately someone was kind enough to gently nudge our car out of the drift and my family was able to find shelter at a nearby hotel.&lt;/p&gt;
&lt;p&gt;My wife called work to tell them she couldn&amp;#8217;t make it to work again. I was not able to get to them to watch our daughters in time for her to leave. And her scrubs were at home where she could not get them. And the freeway was so backed up it would take hours to get there, if at all. What are the odds of being unable to make it to work on consecutive nights for entirely different reasons?&lt;/p&gt;
&lt;p&gt;Two hours later we were told that we could leave the plant heading away from the hotel where my wife and daughters was staying. I decided to take the chance and leave in hopes of reuniting with my family. The doors of the plant were iced over to the point you could not see through them.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.flickr.com/photos/blowmage/2264703038/" title="IMG_0100 by blowmage, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2179/2264703038_b5c94e1cbd_z.jpg" width="640" height="480" alt="IMG_0100" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Here is the view of the sidewalk out of the plant. The sidewalk is covered with little rolling waves of ice from one to two inches thick. Although it was slick there was enough traction to walk on it.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.flickr.com/photos/blowmage/2264703042/" title="IMG_0101 by blowmage, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2086/2264703042_b852ccbffb_z.jpg" width="640" height="480" alt="IMG_0101" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As I was walking to my truck I was battered with wind gusts upwards of 50 mph. It was hard to keep my feet under me as I crossed the parking lot. As I got to my truck, I scrapped an inch of ice off my side-view mirrors. I have never seen anything like it. Sitting in my truck, the wind battered it back and forth as if an angry mob was trying to get me to leave.&lt;/p&gt;
&lt;p&gt;Visibility was low as plumes of snow and ice blew across the roads. The images captured by my iPhone do not capture the blowing snow and ice as well as I&amp;#8217;d hoped.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.flickr.com/photos/blowmage/2264703048/" title="IMG_0102 by blowmage, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2187/2264703048_322a03cd2d_z.jpg" width="640" height="480" alt="IMG_0102" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I was eventually able to leave the plant traveling at ~5 mph. Even at that speed, I almost slid off the road twice and slid into the truck in front of my once.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.flickr.com/photos/blowmage/2263917683/" title="IMG_0106 by blowmage, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2373/2263917683_39a09bc0c0_z.jpg" width="640" height="480" alt="IMG_0106" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Eventually I was able to escape the worst of the storm, and then traveled across the valley, where I picked up some food, and then headed back towards the hotel. As I passed under the freeway I could see lines of cars and trucks just sitting there, like a very narrow parking lot. I was on the road three hours to get to the hotel. I was in bumper to bumper traffic most of the way. Eventually, I was able to break off to some back roads and arrived at the hotel.&lt;/p&gt;
&lt;p&gt;The hotel is filled with people trying to get rooms. The lobby is filled with folks tired of waiting on the freeway and deciding to cut their losses. We overheard discussions of folks spending two, three, and four hours stranded on the freeway.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.flickr.com/photos/blowmage/2263917687/" title="IMG_0107 by blowmage, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2386/2263917687_aaba983664_z.jpg" width="640" height="480" alt="IMG_0107" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Since the girls were now asleep in the hotel room, and the lobby was so full, my wife and I decided to eat our dinner in the only other logical place: the bathroom.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.flickr.com/photos/blowmage/2263917689/" title="IMG_0108 by blowmage, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2296/2263917689_46c481e7ac_z.jpg" width="640" height="480" alt="IMG_0108" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The Winter Storm Advisory was supposed to end at 10:00 PM tonight, but has been extended to 5:00 AM tomorrow. Right now I&amp;#8217;m not sure if I will be able to get back to work or even get home in the morning. But I&amp;#8217;m very happy to be with my family and thankful we are all safe.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; We made it home this morning and I made it in to work. I saw many abandoned cars and trucks off to the side of the road buried in snow. The road my family was stuck on was still closed this morning. I&amp;#8217;ve heard &lt;a href="http://www.ksl.com/?nid=148&amp;#38;sid=2661908"&gt;news reports&lt;/a&gt; that there were also elementary school buses stuck for hours on that road, and the children were eventually brought back to the school where they stayed the night.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blowmage/~4/CHXOk52tUtk" height="1" width="1"/&gt;</content><feedburner:origLink>http://blowmage.com/2008/02/14/blizzard</feedburner:origLink></entry><entry><title type="text">What I Do</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blowmage/~3/YD92JDf3IEU/what-i-do" /><updated>2008-01-06T00:00:00-08:00</updated><id>http://blowmage.com/2008/01/06/what-i-do</id><content type="html">&lt;p&gt;I don&amp;#8217;t like talking about myself much, I&amp;#8217;d rather talk about how to do stuff or what I think the best way to do said stuff is. But &lt;a href="http://www.chadmyers.com/"&gt;Chad Myers&lt;/a&gt; &amp;#8220;tagged&amp;#8221; me in his &lt;a href="http://www.lostechies.com/blogs/chad_myers/archive/2008/01/05/what-i-do-with-spoilers.aspx" title="with spoilers"&gt;What I do&lt;/a&gt; post. Its been so long since someone used the word &amp;#8220;tag&amp;#8221; outside of &lt;a href="http://en.wikipedia.org/wiki/Tag_%28metadata%29"&gt;metadata&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Folksonomy"&gt;folksonomies&lt;/a&gt; that it took me a while to realize he meant it like the schoolyard game tag.&lt;/p&gt;&lt;h3&gt;My Day Job&lt;/h3&gt;
&lt;p&gt;During the day I spend my time at &lt;a href="http://www.imftech.com/"&gt;IM Flash&lt;/a&gt; where we make the &lt;span class="caps"&gt;NAND&lt;/span&gt; that makes your cell phones and mp3 players go. My title is &amp;#8220;Software Engineer&amp;#8221; and I work in the group that supports the engineers. We support a metric ton of systems that help the engineers keep track of the manufacturing process. Most of these systems involve schlepping data from one system to the other. We collect data from the tools, process the data, report on the data, move the data to centralized systems, report on that data again, etc&amp;#8230; Some of our systems are 3rd party, but most are homegrown. I end up doing my fair share of Perl on Linux and Solaris, as well as WinForms and &lt;span class="caps"&gt;ASP&lt;/span&gt;.NET apps in C#. We also have a nice backlog of VB apps as well, but we aren&amp;#8217;t much of a Java shop.&lt;/p&gt;
&lt;p&gt;When I&amp;#8217;m not helping to keep the ship running, I actually get to do a bit of development. I am also the site&amp;#8217;s IT architecture oversight representative, although it probably isn&amp;#8217;t as fancy as you&amp;#8217;d think. I participate in a variety of groups, both on site and around the company. I run a fun little group called TechShare, where we meet weekly and watch interesting videos and screencasts to help us improve as developers. I am also the self-proclaimed Agile and Ruby evangelist, and I&amp;#8217;m sure everyone is tired of hearing it from me. When I&amp;#8217;m not providing support or new development, I generally try to help improve things as much as I can.&lt;/p&gt;&lt;h3&gt;My &amp;#8220;Contribution&amp;#8221;&lt;/h3&gt;
&lt;p&gt;I don&amp;#8217;t consider my time at &lt;a href="htp://mtnwestruby.org/"&gt;MountainWest Ruby, &lt;span class="caps"&gt;LLC&lt;/span&gt;&lt;/a&gt; a job, per se. I suppose I should as it is a real company, but I don&amp;#8217;t take a salary and everything we do is to promote the Ruby language. MountainWest Ruby is the organization that hosts the &lt;a href="http://mtnwestrubyconf.org/"&gt;MountainWest RubyConf&lt;/a&gt;, which is coming up March 28-29. MountainWest Ruby is a fun thing to be a part of, as I get to meet and interact with alot of really interesting and smart people that I probably wouldn&amp;#8217;t have the opportunity otherwise.&lt;/p&gt;
&lt;p&gt;While we have a handful of folks involved with MountainWest Ruby, I think it would be fair to say I do the majority of the behing-the-scenes work. &lt;a href="http://on-ruby.blogspot.com/"&gt;Pat Eyler&lt;/a&gt; is the public face of the conference, and he and I work very closely to make sure we act responsibly toward the community. I like to think that the community has entrusted us with their money, so I am very conscious where we spend it. Some might say I&amp;#8217;m too frugal, but we operate on a shoestring budget so I feel I need to be.&lt;/p&gt;
&lt;p&gt;One thing I can say is that I love the Ruby community. It is by far the nicest and most giving online community I&amp;#8217;ve ever been a part of, and I&amp;#8217;m humbled that I get to be a part of that in some small way.&lt;/p&gt;
&lt;h3&gt;My Night Job&lt;/h3&gt;
&lt;p&gt;Forgive me for the shameless self-promotion, but I have been known to moonlight on Ruby, Rails, or .NET projects. My little one-man company is &lt;a href="http://humanecode.com/"&gt;HumaneCode&lt;/a&gt;. I&amp;#8217;m not actively seeking work at the moment so the website is embarrassingly bare. I&amp;#8217;m sure you&amp;#8217;ll understand.&lt;/p&gt;
&lt;h3&gt;Other Stuff&lt;/h3&gt;
&lt;p&gt;I&amp;#8217;ve got more going on as well. I do a podcast about Ruby called &lt;a href="http://rubiverse.com/"&gt;Rubiverse&lt;/a&gt; that is alot of fun. I try to be active in the &lt;a href="http://altdotnet.org/"&gt;&lt;span class="caps"&gt;ALT&lt;/span&gt;.NET&lt;/a&gt; community as well, and hope to grow a local &lt;a href="http://groups.google.com/group/utahaltnet"&gt;group&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;My Family&lt;/h3&gt;
&lt;p&gt;My family is supremely important; I have a a wonderful wife and two beautiful little girls (with one in the oven). Without getting too personal, the past year has been hard for us. What I will say is the our trials have brought us even closer.&lt;/p&gt;
&lt;p&gt;I know this list seems like alot of stuff, but it all pales in comparison to the importance of my family. My wife has been very gracious to allow me to follow my interests and take chances. Without her and the girls it would be meaningless.&lt;/p&gt;
&lt;h3&gt;Who Next?&lt;/h3&gt;
&lt;p&gt;It seems implicit in this &lt;a href="http://en.wikipedia.org/wiki/Meme"&gt;meme&lt;/a&gt; is to pass the pain along. Fortunately, there isn&amp;#8217;t isn&amp;#8217;t a set number I have to inflict, so I&amp;#8217;ll just choose the two following.&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;&lt;a href="http://www.lukemelia.com/"&gt;Luke Melia&lt;/a&gt; &amp;#8211; Because I&amp;#8217;m curious about what he does next.&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://objo.com/"&gt;Joe O&amp;#8217;Brien&lt;/a&gt; &amp;#8211; Because I find his business fascinating and I want to know more.&lt;/li&gt;
&lt;/ol&gt;&lt;img src="http://feeds.feedburner.com/~r/blowmage/~4/YD92JDf3IEU" height="1" width="1"/&gt;</content><feedburner:origLink>http://blowmage.com/2008/01/06/what-i-do</feedburner:origLink></entry><entry><title type="text">A brief history of Ruby on .NET</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blowmage/~3/RnlEf_fqxs4/ruby-on-dotnet-history" /><updated>2008-01-03T00:00:00-08:00</updated><id>http://blowmage.com/2008/01/03/ruby-on-dotnet-history</id><content type="html">&lt;p&gt;&lt;a href="http://www.iunknown.com/"&gt;John Lam&lt;/a&gt; recently
&lt;a href="http://www.iunknown.com/2008/01/ironruby-vs-rub.html"&gt;responded&lt;/a&gt; to
a post by &lt;a href="http://mdavid.name/"&gt;M. David Peterson&lt;/a&gt; about the
&lt;a href="http://www.oreillynet.com/windows/blog/2008/01/rubynet_vs_ironruby_whats_the.html"&gt;
differences between Ruby.NET and IronRuby&lt;/a&gt;. A few months ago
&lt;a href="http://drnicwilliams.com/"&gt;Dr. Nic&lt;/a&gt; (inadvertently)
&lt;a href="http://drnicwilliams.com/2007/10/13/rubynet-goes-open-source/"&gt;made it
seem&lt;/a&gt; like the two projects are at odds. Afterwards the
&lt;a href="http://softiesonrails.com/"&gt;Softies on Rails&lt;/a&gt; guys seemed to
&lt;a href="http://softiesonrails.com/2007/10/17/ruby-net-and-ironruby-are-open-sourced"&gt;
question Microsoft&amp;#39;s interest in Ruby&lt;/a&gt; and were disappointed with Microsoft&amp;#39;s
&amp;quot;lack of support&amp;quot; for Ruby.NET. There seems to be some confusion about the relationship
between IronRuby and Ruby.NET. Implicit in some online conversations about IronRuby
and Ruby.NET is a distrust of Microsoft doing the right thing in regards to Ruby.
I&amp;#39;ve read many statements that imply Microsoft is trying to kill Ruby.NET. I&amp;#39;ve
also read that Microsoft is trying to kill Ruby! So for all those that haven&amp;#39;t been
following Ruby&amp;#39;s adventures on Microsoft&amp;#39;s .NET framework, here is a (very) brief
history as I remember it. Corrections are welcome.&lt;/p&gt;

&lt;h3&gt;NETRuby&lt;/h3&gt;

&lt;p&gt;Actually, Ruby.NET wasn&amp;#39;t the first Ruby implementation on .NET. Sure, there
were Ruby to .NET bridges like &lt;a href="http://www.iunknown.com/"&gt;John Lam&lt;/a&gt;&amp;#39;s
&lt;a href="http://www.rubyclr.com/"&gt;RubyCLR&lt;/a&gt; and
&lt;a href="http://www.saltypickle.com/"&gt;SaltyPickle&lt;/a&gt;&amp;#39;s
&lt;a href="http://www.saltypickle.com/rubydotnet"&gt;Ruby/.NET Bridge&lt;/a&gt; before, but
there was also an actual port of Ruby 1.6 to .NET by
&lt;a href="http://arton.hp.infoseek.co.jp/"&gt;arton&lt;/a&gt;. This project was called named
&lt;a href="http://www.geocities.co.jp/SiliconValley-PaloAlto/9251/ruby/nrb.html"&gt;NETRuby&lt;/a&gt;
and it was a straight port of the Ruby C code to C# in 2001. I think I got it working
on some small things, and I found the code pretty interesting. But the effort eventually
died from lack of attention and/or need, as it was started and abandoned long before
Rails was born and brought so much attention to the Ruby language.&lt;/p&gt;

&lt;h3&gt;The First IronRuby&lt;/h3&gt;

&lt;p&gt;Another early Ruby on .NET project was &lt;a href="http://www.wilcob.com/"&gt;Wilco
Bauwer&lt;/a&gt;&amp;#39;s &lt;a href="http://www.wilcob.com/Wilco/IronRuby.aspx"&gt;IronRuby project&lt;/a&gt;.
Wilco based his implementation on the IronPython implementation. Although the current
&lt;a href="http://www.ironruby.net/"&gt;IronRuby&lt;/a&gt; project shares the name, the two
projects don&amp;#39;t share any code. I don&amp;#39;t believe Wilco ever publicly released the
source code for his implementation. I do remember playing with the compiled version
he released, but it was far from complete.&lt;/p&gt;

&lt;h3&gt;Ruby.NET&lt;/h3&gt;

&lt;p&gt;Around the time that Wilco was talking about his IronRuby implementation, the
&lt;a href="http://plas.fit.qut.edu.au/"&gt;Queensland University of Technology&lt;/a&gt; folks
announced that they had received funding from Microsoft Research to implement
&lt;a href="http://plas.fit.qut.edu.au/Ruby.NET/"&gt;Ruby on the .NET Framework&lt;/a&gt;. I
remember that Microsoft was just starting to show more interest in dynamic languages,
due to the success of IronPython and the sudden and overwhelming emergence of Ruby
(largely because of Rails).

&lt;a href="http://rubydotnet.googlegroups.com/web/Home.htm"&gt;Ruby.NET&lt;/a&gt;&amp;#39;s runtime
involves creating wrapper objects for the .NET objects to implement all the Ruby-ish
features. This is a very common approach for implementing dynamic languages on a
static language runtime. The early work from the Queensland guys resulted in code
drops every six months or so. As the project has matured the releases became more
frequent until the code was eventually put into a
&lt;a href="http://code.google.com/p/rubydotnetcompiler/"&gt;public subversion repository&lt;/a&gt;
on Google&amp;#39;s service.&lt;/p&gt;

&lt;h3&gt;The Current IronRuby&lt;/h3&gt;

&lt;p&gt;Microsoft&amp;#39;s investment in Ruby.NET was rewarded when
&lt;a href="http://www.iunknown.com/"&gt;John Lam&lt;/a&gt; joined Microsoft to implement Ruby
on the yet to be announced Dynamic Language Runtime (DLR). The DLR sits on top of
the CLR and allows IronRuby to add Ruby-ish features to the .NET objects without
creating proxies. The DLR also allows different dynamic languages to interoperate
in the same way that languages such as C# and VB.NET can interoperate on the CLR.

For legal reasons John&amp;#39;s team can&amp;#39;t look at the original C implementation of
Ruby (you can listen to my &lt;a href="http://rubiverse.com/"&gt;Rubiverse&lt;/a&gt; podcast
interview &lt;a href="http://rubiverse.com/podcasts/1-john-lam-on-ironruby"&gt;with John&lt;/a&gt;
for the details to why this is), but was able to license and look at the Queensland
implementation of Ruby.NET. John&amp;#39;s team was also able to use parts of Ruby.NET to
more quickly stand up IronRuby. Although it seems that the parts of Ruby.NET in
IronRuby are scheduled to be replaced in order to provide better future integration
with the Visual Studio IDE.

So that&amp;#39;s is. The efforts are dramatically different in their implementation,
and address different needs. I see them both as complementary, and having a similar
relationship as the one between &lt;a href="http://jruby.codehaus.org/"&gt;JRuby&lt;/a&gt; and
&lt;a href="http://xruby.com/"&gt;XRuby&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blowmage/~4/RnlEf_fqxs4" height="1" width="1"/&gt;</content><feedburner:origLink>http://blowmage.com/2008/01/03/ruby-on-dotnet-history</feedburner:origLink></entry><entry><title type="text">The Failure of Static Languages</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blowmage/~3/5EWGiPWXATc/static-languages-are-fail" /><updated>2007-12-19T00:00:00-08:00</updated><id>http://blowmage.com/2007/12/19/static-languages-are-fail</id><content type="html">&lt;p&gt;So, &lt;a href="http://weblogs.asp.net/bleroy/"&gt;Bertrand Le Roy&lt;/a&gt; left a comment on my &lt;a href="http://blowmage.com/2007/12/18/the-rubification-of-csharp"&gt;previous post&lt;/a&gt; calling me out for saying, "static languages have failed". I think I need more space than the comment field to make a full reply, so I'll do it here with a sensational title to gain the maximum attention. ;)&lt;/p&gt;&lt;blockquote&gt;
&lt;p&gt;I usually enjoy reading your blog but wow. "Static languages have failed"? Just wow. Don't you think that viewpoint might be just a little myopic?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Like I said in my comment, I hope this view isn't myopic. The last 20+ years have been dominated by static languages like C++, Java, and C#. I believe we are in the midst of a dynamic language revolution and I expect the landscape to look dramatically different in 3 to 5 years. I'm talking about the entire IT landscape, not just the .NET or J2EE landscape (although they will look different as well).&lt;/p&gt;
&lt;p&gt;My point isn't that static languages aren't useful and won't continue to be used. But they aren't where I believe the majority of development will be done in the future. Just as you would build a departmental client app using VB instead of C++ 10 years ago, you will be using a dynamic language instead of a static language in 3-5 years.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Because they don't work for you or for the microcosm you're hanging out in doesn't mean it doesn't work for the rest of the world.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;My point is that static languages don't work &lt;em&gt;for you&lt;/em&gt;! Creating an interface just to run a unit test is a sign (to me) of a weak language. The existence of so many design patterns and anti-patterns are also a sign (to me) of a weak language. There are and will be better languages that allow you to get your work done faster while being more maintainable.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Static languages have been and continue to be very successful. Maybe it would be a little more productive to recognize the merits of each side before making definitive judgements like this one.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I don't mean to take any thing away from static languages like C# and Java. Hell, I program in C# every single day. Well, every work day. And I certainly don't hate C#, but I don't love it like I love Ruby. I think I've been a good soldier in the static camp long enough to make up my own mind and voice my opinion. I don't do so out of ignorance.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;It might also help the dynamic language world to recognize major advances in language design (which imo Linq is) so that they can incorporate similar concepts in their own favorite technology.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I know many folks have been excited by the prospect of using LINQ from IronRuby. But honestly I don't know how to take advantage of LINQ from IronRuby. If you have your local objects, you can already iterate and .map() or .collect() on them. And there are already ORM and data access libraries that will use a DSL or take a closure and query your data store. &lt;a href="http://onestepback.org/"&gt;Jim Weirich&lt;/a&gt; recently discussed building such a library at &lt;a href="http://rubyconf2007.confreaks.com/d1t1p2_advanced_ruby_class_design.html"&gt;RubyConf&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;LINQ looks to be very useful and a huge win while working in C# and VB.NET. But I don't need that in a dynamic language like Ruby because I already have those facilities. So I don't see LINQ as a major advance in language design.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;One thing that can be said from the C# team (which from our own microcosm looks very very far from "desperate") is that *they* know how to keep an eye on the other side and incorporate what looks interesting, while not compromising the integrity of the language.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I didn't mean to imply that the C# team is desperate, just that the language is trying hard to stay relevant amidst the dynamic language onslaught. There are alot of reasons why I'll do my best to stay on the .NET platform, but I can't say the same for C#. From the beginning the CLR was designed to support multiple languages, so I've always found the staunch defense of C# confusing. Particularly amongst the &lt;a href="http://altdotnet.org/"&gt;Alt.NET&lt;/a&gt; crowd, but that's a topic for a different post. :)&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In that respect, anonymous types capture an essential aspect of dynamic languages while remaining strongly-typed (and thus keeping IntelliSense working).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I think there is the perception that you can't get IntelliSense&amp;copy;&amp;trade; or performance with dynamic languages. You certainly can. We might not be there 100% just yet, but we will get there. &lt;a href="http://www.netbeans.org/"&gt;NetBeans&lt;/a&gt; and &lt;a href="http://www.activestate.com/Products/komodo_ide/"&gt;Komodo&lt;/a&gt; and &lt;a href="http://www.sapphiresteel.com/"&gt;Ruby in Steel&lt;/a&gt; are good examples of Ruby IDEs with autocomplete.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You might also want to consult the documentation for anonymous methods, which do capture surrounding local variables (since 2.0), which in my book is pretty much what a closure is.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Great point! Anonymous methods are definitely closer to closures than anonymous delegates. But the point I tried to make about anonymous delegates wasn't about local variables as parameters; it was about accessing private class variables. Once you replace the delegate you lose the ability to access private class variables.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Don't want to look aggressive or anything, sorry if I did, not my intention. Keep up the good work and the provocative thinking.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;No way man, I appreciate you wanting to engage in a discussion about this! There are a couple more points I want to make to clarify what I'm trying to say but didn't fit well in response to you comment.&lt;/p&gt;
&lt;p&gt;I say static languages have failed because the features we are looking for in future languages are at odds with static typing. For example, static languages achieve polymorphism through inheritance (or implementation of an interface) instead of duck-typing/composition/parametric polymorphism. So you have an explosion of interfaces when you want to test your code. But those interfaces aren't for reuse as much as they are for testing. They don't really help the reason your code exists, just your test cases. You end up with all that code cruft adding little value because static languages achieve polymorphism through tightly coupling implementations. Meanwhile Ruby promotes object composition over class inheritance.&lt;/p&gt;
&lt;p&gt;My problem with the Rubification of C# is that C# has incorporated some of the aspects of Ruby, but not the real power of Ruby. Its all sugar and no meat. OO in Ruby or Smalltalk is very different than OO in C# or Java. I've had many discussions where other developers have said they are a better C++ or Java or C# programmer because of the time they've spent with Ruby. That isn't because of Ruby's syntax, that is because of Ruby's fundamentally different understanding of objects.&lt;/p&gt;
&lt;p&gt;Am I right or am I wrong? Please let me know. You can either leave me a comment or send me &lt;a href="mailto:mike@blowmage.com?subject=You Suck! Static Languages ARE the Future!"&gt;hate&lt;/a&gt; (or &lt;a href="mailto:mike@blowmage.com?subject=You Rock! Static Languages are SO 2007!"&gt;fan&lt;/a&gt;) mail.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blowmage/~4/5EWGiPWXATc" height="1" width="1"/&gt;</content><feedburner:origLink>http://blowmage.com/2007/12/19/static-languages-are-fail</feedburner:origLink></entry><entry><title type="text">The Rubification of C#</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blowmage/~3/1dPS6kvoow0/the-rubification-of-csharp" /><updated>2007-12-18T00:00:00-08:00</updated><id>http://blowmage.com/2007/12/18/the-rubification-of-csharp</id><content type="html">&lt;p&gt;&lt;a href="http://chadmyers.com/Blog/"&gt;Chad Myers&lt;/a&gt; gave me a nice little surprise by using my surname in his blog post &lt;a href="http://chadmyers.com/Blog/archive/2007/12/15/moore-on-the-anonymous-delegate-approach.aspx"&gt;"Moore on the Anonymous Delegate Approach"&lt;/a&gt; about an approach to make his statically-typed C# code more easily testable. I struggled with how best to respond because the subject of his code experiments really demonstrates some of the things I've been thinking about C#'s evolution for a while now. So while this isn't a direct response to his post, its something I've been wanting to say for a while now.&lt;/p&gt;
&lt;p&gt;Chad started out by showing how you can use anonymous delegates to encapsulate your logic, and then swap out the delegates in his test cases so he can verify the dependent objects work properly. So he is essentially swapping the implementation of the code his object has a reference to. The fly in the ointment is that only the original anonymous delegate can access all the internal data in his object, so once you swap out the object's original anonymous delegate, the object becomes ineffective. (Unless your logic is dead simple, like the kind you use when you are writing code demos.)&lt;/p&gt;
&lt;p&gt;The thing I really like about Chad's code is that he's getting really close to using anonymous delegates as closures, and I really love closures. I believe if Microsoft would (or could) add closures to the C# language (and idioms) that C# would be better for it. But closures aren't embraced by C#. I understand that he is finding new ways to solve the testability problem with static languages, and while I enjoy his ingenuity, I'm starting to think that C# is moving too far from what it is. My concern is that as C# tries to be all things to all people, it simply stops being as useful.&lt;/p&gt;
&lt;p&gt;Coincidentally, Tim Bray posted his thoughts on &lt;a href="http://www.tbray.org/ongoing/When/200x/2007/12/16/On-Closures"&gt;adding closures to Java&lt;/a&gt; yesterday, and he said many of the things I've been thinking about in regards to C# and Ruby. The only caveat I'd make on applying Tim's thoughts to C# and .NET is that Java Generics != .NET Generics. Essentially, C# is an 80% language, and I'm totally okay with it. Ruby is also an 80% language, although a much different 80%. Making C#'s 80% overlap overlap Ruby's 80% as much as possible seems kinda wrong.&lt;/p&gt;
&lt;p&gt;Tim's favored approach to improving Java is to work on a multi-language VM, not the core language itself. .NET is already ahead because it has facilities for interoperating multiple languages. Therefore I don't think we should focus on improving C#, but we should start focusing on using the right tool for the right job; meaning the right language. Don't get me wrong, I appreciate the fact that C# is taking on many Rubyisms in an effort to improve. But C# will never be Ruby, and really it never should. My hopes are that the DLR enables C# and IronRuby to not just co-exist but integrate well.&lt;/p&gt;
&lt;p&gt;In &lt;a href="http://channel9.msdn.com/ShowPost.aspx?PostID=350187"&gt;this Channel9 video&lt;/a&gt; &lt;a href="http://channel9.msdn.com/ShowPost.aspx?PostID=350187"&gt;Robert Martin&lt;/a&gt; and &lt;a href="http://chadfowler.com/"&gt;Chad Fowler&lt;/a&gt; discuss dynamic vs. static languages at JAOO 2007. You should &lt;a href="http://channel9.msdn.com/ShowPost.aspx?PostID=350187"&gt;watch this video now&lt;/a&gt;. In it, Uncle Bob was asked if he was excited about the new functional programming features of C#; specifically LINQ. His response? "I'm about as excited about that as I am about Fortran 95." His point was that by the time the new Fortran was released he had already moved on and it was no longer relevant to him. That is certainly how I feel about C#; the more features they add, the more desperate it looks, and the less I feel like investing myself in it.&lt;/p&gt;
&lt;p&gt;Static languages have failed. They aren't dead, but they aren't the future. You can only fight a language so long before its time to move on.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blowmage/~4/1dPS6kvoow0" height="1" width="1"/&gt;</content><feedburner:origLink>http://blowmage.com/2007/12/18/the-rubification-of-csharp</feedburner:origLink></entry><entry><title type="text">Why the kids don't like the RSS</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blowmage/~3/erxWJd2mHDU/social-networks-suck" /><updated>2007-10-20T00:00:00-07:00</updated><id>http://blowmage.com/2007/10/20/social-networks-suck</id><content type="html">&lt;p&gt;A couple days ago Coté asked &lt;a href="http://twitter.com/cote/statuses/346353002"&gt;"Is Web 2.0 the middle-agers web?"&lt;/a&gt; and today he asks if &lt;a href="http://www.redmonk.com/cote/2007/10/20/do-the-kids-like-the-rss/"&gt;the kids like the RSS&lt;/a&gt;. The answer is obviously no; kids think blogs and RSS aren't a big deal. Not to say that blogs and RSS aren't useful or of value; just that their technical details aren't important to the kids and their damn rock and roll music. I think that blogs, RSS, and to an extent even twitter succeed because they are geek tools.&lt;/p&gt;
&lt;p&gt;Facebook and MySpace have found success by making the process of creating and consuming blogs and RSS content approachable by the vast sea of non-geek users on the Interweb. They, and other social networks of their ilk, have taken our awesome geek ideas and packaged them up in a seamless... package. Well, maybe not seamless, but they hide most if not all of the complexity and apparently by doing so have created &lt;em&gt;billions&lt;/em&gt; of dollars of value.&lt;/p&gt;
&lt;p&gt;Apparently value is added because those punk kids on MySpace don't want the complexity of setting up NetNewsWire or Google Reader with their favorite feeds. Or, they have no idea what I just said and are incapable of doing so. They just want to go to a site, any site, and see what their friends are doing. And make the Internet a little bit uglier. Yeah, it doesn't make much sense to me either but apparently the unwashed masses love it.&lt;/p&gt;
&lt;p&gt;I like the prospects of using Facebook's platform to build apps and make money, but I don't personally like the idea of using &lt;a href="http://www.facebook.com/people/Mike_Moore/582561201"&gt;Facebook&lt;/a&gt;. And I can't stand &lt;a href="http://www.myspace.com/blowmage"&gt;MySpace&lt;/a&gt;. I'm more lenient about &lt;a href="http://www.linkedin.com/in/mikemoore"&gt;LinkedIn&lt;/a&gt;, but I think that is because I have delusions of actually getting work from it... some day... eventually. The reason I don't like them is because they feel restrictive, and don't work they way I want them to work. But I'm a geek and like all self-respecting geeks I have a strong opinion of how the world &lt;em&gt;should&lt;/em&gt; work. And so far the social network apps just haven't done it for me.&lt;/p&gt;
&lt;p&gt;I like &lt;a href="http://twitter.com/blowmage"&gt;twitter&lt;/a&gt; and I like &lt;a href="http://del.icio.us/blowmage"&gt;del.icio.us&lt;/a&gt; and I like &lt;a href="http://www.flickr.com/photos/blowmage/"&gt;Flickr&lt;/a&gt;. I like the fact that &lt;a href="http://blowmage.com/"&gt;blowmage.com&lt;/a&gt; is the central hub for my online presence. I like keeping track with people through their blogs, and having public discussions on mailing lists. Maybe if I were 20 years younger I'd think differently, but what the hell do those whippersnapper know?&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blowmage/~4/erxWJd2mHDU" height="1" width="1"/&gt;</content><feedburner:origLink>http://blowmage.com/2007/10/20/social-networks-suck</feedburner:origLink></entry><entry><title type="text">Getting RubyGems to play nice at work</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blowmage/~3/4UAAYVPS3tE/rubygems-at-work" /><updated>2007-10-18T00:00:00-07:00</updated><id>http://blowmage.com/2007/10/18/rubygems-at-work</id><content type="html">&lt;p&gt;At work I'm on Windows and behind a proxy server. I recently wiped my workstation and started over. After I installed Ruby I found the gems command not working, again. The reason is that my proxy server requires a username and password, and open-uri doesn't pass them. (Supposedly because keeping your username and password in an environment variable isn't secure, but at work I don't care as much about apps snooping my environment variables.)&lt;/p&gt;
&lt;p&gt;To get things working I had to hack up open-uri a bit.  So I found the following code in &lt;code&gt;C:\ruby\lib\ruby\1.8\open-uri.rb&lt;/code&gt;&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;net/http&amp;#39;&lt;/span&gt;
  &lt;span class="n"&gt;klass&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Net&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;HTTP&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="no"&gt;URI&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;HTTP&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;
    &lt;span class="c1"&gt;# HTTP or HTTPS&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;proxy&lt;/span&gt;
      &lt;span class="n"&gt;klass&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Net&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Proxy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;proxy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;proxy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;And I make the following change:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;net/http&amp;#39;&lt;/span&gt;
&lt;span class="n"&gt;klass&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Net&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;HTTP&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="no"&gt;URI&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;HTTP&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;
  &lt;span class="c1"&gt;# HTTP or HTTPS&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;proxy&lt;/span&gt;
    &lt;span class="c1"&gt;# Add proxy user and password to work with the proxy server.&lt;/span&gt;
    &lt;span class="n"&gt;klass&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Net&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Proxy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;proxy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;proxy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;proxy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;proxy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Then I create the &lt;code&gt;http_proxy&lt;/code&gt; environment variable with the value of &lt;code&gt;http://blowmage:s3cr3t@proxy:8080&lt;/code&gt; and I'm good to go. Well, I have to log off and log back in for Windows to find and RubyGems to use the new environment variable. Oh, and be sure to create it as a user variable and not a system variable. :)&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blowmage/~4/4UAAYVPS3tE" height="1" width="1"/&gt;</content><feedburner:origLink>http://blowmage.com/2007/10/18/rubygems-at-work</feedburner:origLink></entry><entry><title type="text">Ruby Blue Visual Studio Theme</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blowmage/~3/hS_o3yeUTRU/ruby-blue-visual-studio-theme" /><updated>2007-10-10T00:00:00-07:00</updated><id>http://blowmage.com/2007/10/10/ruby-blue-visual-studio-theme</id><content type="html">&lt;p&gt;Now that I'm blogging again, and I've had a resurgence of .NET related posts, I thought I'd add to a meme I saw going around earlier this summer. First John Lam posted his &lt;a href="http://www.iunknown.com/2007/06/vibrant_ink_vis.html"&gt;Vibrant Ink&lt;/a&gt; theme for Visual Studio, then I saw Tomas Restrepo post his &lt;a href="http://www.winterdom.com/weblog/2007/09/11/NightingaleAVS2005ColorScheme.aspx"&gt;Nightingale&lt;/a&gt; theme.&lt;/p&gt;
&lt;p&gt;I've always been a fan of John Long's &lt;a href="http://wiseheartdesign.com/2006/3/11/ruby-blue-textmate-theme/"&gt;Ruby Blue TextMate&lt;/a&gt; theme. So I created my own Visual Studio theme (including the Monaco font) a long time ago and thought I should &lt;a href="http://github.com/downloads/blowmage/rubyblue/RubyBlueVS2005.zip"&gt;share it here&lt;/a&gt;. Feel free to fork &lt;a href="http://github.com/blowmage/rubyblue"&gt;my repo&lt;/a&gt;, improve it, and send me a pull request. Enjoy.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blowmage/~4/hS_o3yeUTRU" height="1" width="1"/&gt;</content><feedburner:origLink>http://blowmage.com/2007/10/10/ruby-blue-visual-studio-theme</feedburner:origLink></entry><entry><title type="text">Will we ever get IronRuby on Rails?</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blowmage/~3/75NM0wPN1lQ/ironruby-on-rails" /><updated>2007-10-10T00:00:00-07:00</updated><id>http://blowmage.com/2007/10/10/ironruby-on-rails</id><content type="html">&lt;p&gt;Last weekend the ALT.NET Conf I had a couple opportunities to plead my case for Microsoft to embrace the Ruby on Rails framework and better enable it on IIS. I believe IronRuby will eventually run Rails, and I believe when it does the community will implement whatever hooks are required to run Rails using the DLR on IIS. But I want more. I want Microsoft to stand behind Rails and encourage its use. I want an "official" deployment story for Rails using IronRuby and IIS like the one Sun has with JRuby. I was able to discuss this with Scott Guthrie himself at the end of Scott Hanselman's DLR/MVC session, but I don't think I changed his mind at all. Sorry guys.&lt;/p&gt;
&lt;p&gt;Half of the resistance seemed to be that Rails was too much of a fad and a moving target. I heard ScottGu say on a couple of occasions that prototype.js was really hot last year, but this year everyone is using jQuery. I also heard him say that last year everyone was all excited about RJS, but this year nobody is actually using it. The implication seemed to be that the Rails community couldn't make up its mind. But the reality is that the Rails community is having a conversation about how to build web apps better and it seems like Microsoft is either ignoring the conversation or blissfully ignorant of it. Neither is the case, obviously; but Microsoft has yet to join the conversation. In talking with ScottGu it became apparent to me exactly how well tuned in he is. He has obviously talked to enough Rails guys to have satisfied himself that Microsoft is making informed decisions.&lt;/p&gt;
&lt;p&gt;The other half of the resistance to official support for "IronRails" is the giant mutex lock hanging around Rails' neck. The implication with this one was that as soon as the Rails team fixes the threading model, then Microsoft can have something to work with to get a performant Rails on IIS. I wish I had a good answer to this. The JRuby guys appear to be working hard on improving performance of Rails on JRuby, and having success. Can something similar be done for IronRuby on IIS?&lt;/p&gt;
&lt;p&gt;The third half of the resistance to Rails was that the Rails community is simply not interested in running on Windows in any meaningful way. Its been historically hard to get support from the community for the SQL Server adapter in Rails, and there has been very little activity on getting Rails running on the new FastCGI ISAPI filter on IIS. I don't have a good answer for these things either. Personally, I don't have permissions to the web servers at my work; so I can't get FastCGI on the server because it isn't on the roadmap. But this is exactly why I want support via the DLR; so I don't have to have admin access to the server to deploy a Rails app because its all just .NET.&lt;/p&gt;
&lt;p&gt;I disagree with ScottGu's view was that the Rails community isn't committed to running on Windows. I don't think that is it exactly; I think the Rails community isn't committed to running on IIS. Deploying Rails on IIS is more than just FastCGI; you also need a mod_rewrite replacement and there doesn't appear to be any free solution for that. Simply put, its too painful to deploy on IIS and its much easier to deploy on Apache. Rails devs are usually pragmatic folks, and will go with a working solution.&lt;/p&gt;
&lt;p&gt;But personally, I really want to build Rails apps. And I'd hate to have to not be able to do that on Windows and .NET. I have very high hopes for the new ASP.NET MVC framework, but I'd also like a commitment from Microsoft to the Rails community similar to the commitment made to the Ruby community. And honestly, I think it would be in their best interest long term.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blowmage/~4/75NM0wPN1lQ" height="1" width="1"/&gt;</content><feedburner:origLink>http://blowmage.com/2007/10/10/ironruby-on-rails</feedburner:origLink></entry><entry><title type="text">ALT.NET Conf: Day 3</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blowmage/~3/CTVQceqaXv4/altnetconf-day-3" /><updated>2007-10-08T00:00:00-07:00</updated><id>http://blowmage.com/2007/10/08/altnetconf-day-3</id><content type="html">&lt;p&gt;Today was abbreviated with only two sessions this morning and then a combined closing session. I had a late start (again) this morning, and missed the opening comments (again). I know this makes me seem like the kinda guy who always sleeps in (and the guys I work with would definitely agree with that characterization) but I want to point out that a) I was &lt;em&gt;very&lt;/em&gt; sleep deprived going into this weekend, and b) conferences like this are physically draining. There is so much mental engagement that it really does fatigue you physically. Really.&lt;/p&gt;
&lt;p&gt;The first session I attended was about Mono. I haven't looked at Mono in years, and I was impressed with what I saw. The &lt;a href="http://mono-project.com/MoMA"&gt;Mono Migration Analyzer&lt;/a&gt; app (MoMA) was really cool. It essentially inspects your .NET *.exe and *.dll files and identifies what calls used are not available on Mono. This is a great idea, and apparently Mono's compatibility was improved by the real world metrics collected through the tool.&lt;/p&gt;
&lt;p&gt;I cut the session a bit short to catch up with my family, and when I returned the session had migrated next door to a discussion on why the MSDN magazine sucks and how to market the ALT.NET message. I don't read the MSDN magazine (but I will if someone sends me a free subscription), so I don't know if it sucks or not and didn't have much to add. However, I think its a bit premature to focus so much on online community building and marketing. I kinda like ALT.NET being undefinable and using guerilla marketing efforts to build awareness of its ambiguity. It just seems more authentic to me that way. Also, I don't see a message well defined enough to actively market. After all the current message is basically, "do what works and don't be afraid to look to other communities to see what works there".&lt;/p&gt;
&lt;p&gt;The mid morning session was the assigned slot for my proposed "Dynamic Languages on the CLR" session. Last night Scott Bellware suggested that what folks would really benefit from was a real life Ruby on Rails demo using test first with RSpec, so I changed the focus of the session to "Ruby on Rails Demonstration". Unfortunately Scott Bellware bailed on me (he had a scheduling conflict) and I recruited &lt;a href="http://lukemelia.com/"&gt;Luke Melia&lt;/a&gt; to pair with me for the session. Scott Hanselman attended and he started a really good discussion before we started writing code. There seemed to be alot of folks who either tried Rails, or knew someone who tried Rails, and were let down by the experience. There was this perception that Rails is *so* cool that you don't have to understand what is going on under the hood. This is true for very simple, golden path apps; but very untrue for most real-world apps. Like anything in life, you get out of Rails what you put into it.&lt;/p&gt;
&lt;p&gt;The Rails session seemed to go well and I had a couple folks thank me for showing them the approach Rails guys take to solve errors when coding. I really like live coding demonstrations where you don't go in with a scripted plan. For instance, The video of the &lt;a href="http://mtnwestrubyconf2007.confreaks.com/session10.html"&gt;Jamis Buck and Marcel Molina, Jr. session&lt;/a&gt; at the &lt;a href="http://mtnwestruby.org/"&gt;MountainWest RubyConf&lt;/a&gt; is by far the most downloaded session of the conference. I hope I continue to see more and more of those types of sessions at future conferences.&lt;/p&gt;
&lt;p&gt;After that all conference attendees poured into one room and one by one we all made comments about what we got from the experience. This was incredibly positive and was a great way to close the conference. This conference wasn't so much about technology as it was focused on the individual. I was happy to be a part of it and I look forward to more gatherings and communications about the ALT.NET ideals, even if it is a big ball of mud at the moment. :)&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blowmage/~4/CTVQceqaXv4" height="1" width="1"/&gt;</content><feedburner:origLink>http://blowmage.com/2007/10/08/altnetconf-day-3</feedburner:origLink></entry><entry><title type="text">ALT.NET Conf: Day 2</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blowmage/~3/bsAVN_gcLNI/altnetconf-day-2" /><updated>2007-10-07T00:00:00-07:00</updated><id>http://blowmage.com/2007/10/07/altnetconf-day-2</id><content type="html">&lt;p&gt;The next day of the &lt;a href="http://altnetconf.com/"&gt;ALT.NET Conference&lt;/a&gt; started with me sleeping in and missing the opening announcements. So as far as I know there was an edict to not talk about Ruby. An edict that I bravely disobeyed.&lt;/p&gt;
&lt;p&gt;The first session I attended was "Ruby for &lt;strike&gt;Dummies&lt;/strike&gt; .NET Developers" and I volunteered to show my intro to Ruby slide desk. I originally built the desk for a ~90 minute presentation, so zipping through the desk in 20 minutes may have resulted in making the message come across a bit strong. But we had a really good discussion about what Ruby is and why Rubyists love it. I really emphasized the human oriented view that Rubyists have and that the Ruby language enables. Folks seemed to go back to the open classes feature over and over. I was really happy (and honestly surprised) when Roy Osherove later announced that he now gets why folks love Ruby and is excited about it.&lt;/p&gt;
&lt;p&gt;The next session was BDD. It was held in the big room and there were alot of folks in that session. There was alot of showing BDD-style code, arguing, and pointing to the screen. It seems that everyone had a different view of BDD and nobody could express exactly what the benefits were to using it. I got kinda frustrated in this session because both philosophically and in practice BDD is great, but nobody could express that during the session. I wish we had a more formal presentation to frame the discussion around.&lt;/p&gt;
&lt;p&gt;After lunch Scott Guthrie showed the new ASP.NET MVC framework. His main points for the framework were:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Separation of Concerns, Testing, Red/Green TDD, Maintainable By Default&lt;/li&gt;
  &lt;li&gt;Extensible and Pluggable&lt;/li&gt;
  &lt;li&gt;Enable clean URLs and HTML&lt;/li&gt;
  &lt;li&gt;Integrate nicely with ASP.NET + .NET; Support Static + Dynamic Languages&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I was really surprised to see how well thought out the framework is, and how extensible and testable the code you can write in it can be. Throughout the demo he highlighted features that were inspired by web frameworks that real developers are using like &lt;a href="http://castleproject.org/monorail/index.html"&gt;MonoRail&lt;/a&gt; or &lt;a href="http://rubyonrails.org/"&gt;Rails&lt;/a&gt; or &lt;a href="http://djangoproject.com/"&gt;Django&lt;/a&gt;. He also showed how it was designed to be testable using any of the current unit testing frameworks. Even more surprising that is uses the current ASP.NET stack, Provider model, Request and Response objects, *.aspx/*.master files, etc. The framework seemed to me to be a brilliant combination of idiomatic .NET features and the agile development practices espoused by open source web frameworks. You can see the video Scott Hanselman took of the demo soon.&lt;/p&gt;
&lt;p&gt;As seamless as ScottGu's demo was, Scott Hanselman's follow up presentation on making the MVC framework use dynamic languages (via the DLR) showed the real pain that lies in front us to integrate dynamic languages into existing static code. For example, configuring and using IronPython in ASP.NET or the new MVC framework seems way more painful than it should. Scott showed the several changes to an older version of the MVC framework to use IronPython as both controllers and views. And Phil Haack (who wasn't here) also did alot of work to use Ruby ERB files for the view using IronRuby. I'm excited that this work is being done, and I hope that the process will lead to a detailed white-paper on how best to integrate static and dynamic code.&lt;/p&gt;
&lt;p&gt;I really liked what I saw with the MVC framework. I can easily see me easing on the fight to get my full-time employer to give Rails a try because the ASP.NET MVC framework will give me all I need and most I want to get my "real" work done. I'll certainly not leave Ruby, but I will definitely be more active in the .NET world because of the ASP.NET MCV framework. So if convincing me to give .NET another shot was the Scott(s) goal; then mission accomplished.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; I ended the day with a &lt;a href="http://www.flickr.com/photos/blowmage/1501544424/"&gt;pile of brisket&lt;/a&gt; at Rudy's and some great conversation with some .NET dignitaries. I tried to get folks to show up for a coordinated hacking session where we will try to make the world better... but the bar seemed to be a bigger attraction for most. (The Ruby community would have combined those two activities...)&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blowmage/~4/bsAVN_gcLNI" height="1" width="1"/&gt;</content><feedburner:origLink>http://blowmage.com/2007/10/07/altnetconf-day-2</feedburner:origLink></entry><entry><title type="text">ALT.NET Conf: Day 1</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blowmage/~3/bGBMccuWFus/altnetconf-day-1" /><updated>2007-10-06T00:00:00-07:00</updated><id>http://blowmage.com/2007/10/06/altnetconf-day-1</id><content type="html">&lt;p&gt;I'm at the &lt;a href="http://altnetconf.com/"&gt;ALT.NET Conference&lt;/a&gt; this weekend to gain a better understanding of where the .NET community is heading and to spread some &lt;a href="http://ruby-lang.org/"&gt;Ruby love&lt;/a&gt;. The conference is using the Open Space format, which seems to be alot like a BarCamp. Although, since I've never been to a BarCamp I'm not so sure what the difference is. This seems to be more focused on interactions and discussions as opposed to presentations, so I suppose that may be the difference. Unfortunately there isn't alot of information online about what "Open Space" is.&lt;/p&gt;
&lt;p&gt;There are some really stellar folks in attendance, you can see the full list &lt;a href="http://altnetconf.com/participants"&gt;here&lt;/a&gt;. &lt;a href="http://iserializable.com/"&gt;Roy Osherove&lt;/a&gt; is here, and he looks way different than I've always imagined in my head. I met &lt;a href="http://blogs.msdn.com/jamesnewkirk/"&gt;Jim Newkirk&lt;/a&gt; of &lt;a href="http://nunit.org/"&gt;NUnit&lt;/a&gt; fame in the hotel lobby. &lt;a href="http://hanselman.com/"&gt;Scott Hanselman&lt;/a&gt; is also here, and seems to be a bit defensive about a perceived (or not) anti-Microsoft bias. There are other folks from Microsoft here as well, including folks from the MSDN team. And &lt;a href="http://agileprogrammer.com/dotnetguy/"&gt;Brad Wilson&lt;/a&gt; (who I just today realized isn't getting &lt;a href="http://twitter.com/blowmage"&gt;my twitter replies&lt;/a&gt; because I'm not being followed by &lt;a href="http://twitter.com/dotnetguy"&gt;him&lt;/a&gt;) is here as well. Oh, and did I mention &lt;a href="http://weblogs.asp.net/scottgu/"&gt;Scott Guthrie&lt;/a&gt;? Yeah, he's here too. I was really surprised and happy to see him here, mostly so I can pester him over and over again that we want &lt;a href="http://www.ironruby.net/"&gt;IronRuby&lt;/a&gt; on Rails support from Microsoft. And of course there is &lt;a href="http://martinfowler.com/"&gt;Martin Fowler&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.dovetailsoftware.com/blogs/slist/"&gt;Doc List&lt;/a&gt; started the conference by setting the expectations and demonstrating the &lt;a href="http://en.wikipedia.org/wiki/Fishbowl_(conversation)"&gt;fishbowl discussion technique&lt;/a&gt; by starting a discussion on what exactly "ALT.NET" means. This discussion is an ongoing topic on the blogs right now, so I wasn't surprised that the discussion continued for a while. It even survived a couple attempts by Doc to kill it. In the end we don't have any cleared definition for ALT.NET; but we did hear alot of opinions. This seems to me to be alot like the Web 2.0 discussions of a couple years ago. ALT.NET, like art, is hard to define but you know it when you see it.&lt;/p&gt;
&lt;p&gt;Then we were given time to think up the topics we would like to discuss for the next couple days. When someone wanted to add a topic, they would write it down on a post-it, move to the center of the room, introduce themselves and the topic, and put the post-it on the board. We quickly had double the post-its than we have rooms and time slots for. There was some consolidation to the list of topics and eventuality we added our initials to the post-its we want to attend or be involved with.&lt;/p&gt;
&lt;p&gt;Scott Guthrie added a note to discuss the often rumored yet unannounced MVC/Model2 ASP.NET framework. And Scott Hanselman added a note to discuss making said MVC framework work with dynamic languages via the DLR. The topic that got the most submissions seemed to be TDD, BDD, and DDD. I added a note to discuss dynamic languages on the CLR; specifically what folks are looking for from them and why some developers fear them. I also volunteered to present on the topic "Ruby for &lt;strike&gt;Dummies&lt;/strike&gt; .NET Developers". There was alot of topics and talk about Ruby and Rails, so I expect some good discussion. I look forward to tomorrow.&lt;/p&gt;
&lt;p&gt;Afterwards, I took the opportunity to introduce myself to Scott Guthrie and promptly cornered him on what his thoughts were on the topics put forward. He said that it wasn't all that surprising and that he was excited to present his new MVC framework. He said he thought it was a good blend of extendibility and "opinionated conventions". It was a really fun discussion and we got a bit of a crowd at the end. I'll hopefully record an interview with him tomorrow.&lt;/p&gt;
&lt;p&gt;Scott Hanselman also floated around the room taking notes on what folks &lt;em&gt;specifically&lt;/em&gt; thought was wrong with the current Microsoft toolset. There were some honest gripes, but it mostly seemed to be folks complaining about features that are most likely already in Visual Studio but are either buried in the UI or not as extensible as folks want. But I started thinking those discussions were missing the point of what I think the meaning of ALT.NET is. To me, ALT.NET is at heart the embrace of Agile by the .NET community and the recognition that the .NET community determines its own fate; not the toolset vendor (Microsoft). But the tools aren't the answer; people are! The &lt;a href="http://agilemanifesto.org/"&gt;Agile Manifesto&lt;/a&gt; holds the following value: "Individuals and interactions over processes and tools". My wish is that Microsoft would focus more on improving individuals and facilitating better interactions, but the heart of the matter is that the .NET community needs to do this regardless of what Microsoft does with its tools.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blowmage/~4/bGBMccuWFus" height="1" width="1"/&gt;</content><feedburner:origLink>http://blowmage.com/2007/10/06/altnetconf-day-1</feedburner:origLink></entry><entry><title type="text">RailsConf 2006: Day 1</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blowmage/~3/8fEtD7rB6ns/railsconf-2006-day-1" /><updated>2006-06-25T00:00:00-07:00</updated><id>http://blowmage.com/2006/06/25/railsconf-2006-day-1</id><content type="html">&lt;p&gt;Here are my notes from Day 1. The word of the day was "deployment". One of the reasons I'm attending RailsConf is to be considered hip and influential by those around me, but the *other* reason is to learn how to better deploy Rails apps. It looks like I'm not alone, as many of the sessions seem to touch on deployment in some way.&lt;/p&gt;
&lt;p&gt;Dave Thomas's opening keynote kicked the conference off with a terrific look at three areas that the Rails community should address to help Rails continue to gain market and mind share: improve ActiveRecord to make better use of database features, improve scaffolding to make it usable and pretty for more complex models (kinda like TurboGears?), and improving deployment so that the various responsibilities in deployment can be delivered by more than one person. Not all developers have full access to their production machines, which is one of the areas Capistrano breaks down. Dave's vision and common sense was on full display, and his message was simple: Rails needs to see wider adoption because *all* developers deserve to be happy.&lt;/p&gt;
&lt;p&gt;Mike Clark's Capistrano overview was excellent as well. And his session was packed. He presented the basics of Capistrano and showed real affection for it. Its too bad Jamis isn't here to take the deserved applause for creating such a wonderful tool. I'm looking forward to attending more sessions about deployment.&lt;/p&gt;
&lt;p&gt;As Bob Silva &lt;a href="http://railtie.net/articles/2006/06/24/railsconf-update"&gt;said&lt;/a&gt;, if you were stuck in the next session you know who you are.&lt;/p&gt;
&lt;p&gt;I attended the Identity/OpenID session next. I didn't realize it was a Verisign product. The first half was very much like Dick Hardt's Identity 2.0 presentation, while the second half was a quick demo showing how easy it was to start using OpenID plugins in Rails. I'm very interested in offloading the user creation experience to a third party, but there seem to be many holes in OpenID that I'm not sure its worth it yet. But I did get a t-shirt out of it. :) Cote has an excellent &lt;a href="http://www.redmonk.com/cote/archives/2006/04/identity_20_tru.html"&gt;review&lt;/a&gt; of the advantages and disadvantages of the various identity standards.&lt;/p&gt;
&lt;p&gt;Geoffrey Grosenbach of the Ruby on Rails Podcast gave a great session on deploying to shared hosts. He covered some of the design choices you can make to fit better into the shared hosting model. He said what we were all thinking, that Typo wasn't designed and for the most part isn't a good fit on a shared host. (I've really got to get around to writing my way out of Typo.) He also covered some common configuration settings for Capistrano's recipe files. Although he didn't cover it, he did mention that some folks are using Mongrel in leu of FastCGI when running on Apache. He said that it wasn't quite ready for prime time yet, but I'll have to check that out.&lt;/p&gt;
&lt;p&gt;Martin Fowler gave the first of two closing Keynotes. He just stood up there and talked. No slides. Martin is one of my heros, and one of the reasons I love being here is because I get to meet and chat with folks like him and Dave Thomas and Chad Fowler and ... He spoke on what it is about Rails that interested him, seeing as he hasn't ever actually used it. I see him as the surrogate grand father of Rails because of the influence his Enterprise Patterns and Practices book had on DHH when he was creating Rails. The name Active Record came from that book. I have lots of notes from his keynote that I will post separately.&lt;/p&gt;
&lt;p&gt;Paul Graham also delivered his keynote without slides. He read a very good essay about how great ideas and innovation often come from the marginalized. In many ways it is an advantage to be an outsider rather than an insider. Here are a couple good quotes:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You're on the right track when people complain you're unqualified or what you're doing is "inappropriate".&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Why and his band took the stage next and delivered a great show. This is the first time I've gotten to see the Thirsty Cups and it was everything I expected. Although I think there are a number of folks here who love Rails but don't really understand Ruby and were lost during Why's show. But maybe that was the point? Either way there was way too much in the show to give it proper coverage here, so I won't even try. I can say that I look forward to see them perform again.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blowmage/~4/8fEtD7rB6ns" height="1" width="1"/&gt;</content><feedburner:origLink>http://blowmage.com/2006/06/25/railsconf-2006-day-1</feedburner:origLink></entry><entry><title type="text">Ruby.NET Beta Announced</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blowmage/~3/GdUu_a1Wl9s/ruby-net-beta-announced" /><updated>2006-06-22T00:00:00-07:00</updated><id>http://blowmage.com/2006/06/22/ruby-net-beta-announced</id><content type="html">&lt;p&gt;They guys at &lt;a href="http://www.fit.qut.edu.au/"&gt;Queensland University of Technology&lt;/a&gt; announced the public beta of their &lt;a href="http://plas.fit.qut.edu.au/Ruby.NET/"&gt;Gardens Point .NET Ruby compiler&lt;/a&gt; yesterday. Not only will it interpret and run Ruby files, but it will compile to .NET executables and assemblies as well. I got it to run on .NET 2.0 on WinXP SP2 and Mono 2.0 on Ubuntu (both running in Parallels on my MacBook Pro). I didn't get it to run on OS X, but that is more to with the lack of an Intel version of Mono for OS X. (Meaning I didn't try too hard to get it working on OS X.)&lt;/p&gt;
&lt;p&gt;I skimmed through the Ruby.NET source code last night and I have to say I'm impressed. I’m particularly excited about Ruby.NET because I trotted down the path of building a .NET version of Ruby and have a good idea how challenging it was to get this far. I looked at &lt;a href="http://www.geocities.co.jp/SiliconValley-PaloAlto/9251/ruby/main.html"&gt;arton&lt;/a&gt;'s older &lt;a href="http://www.geocities.co.jp/SiliconValley-PaloAlto/9251/ruby/nrb.html"&gt;NetRuby&lt;/a&gt; effort code that was essentially a straight port of Ruby 1.6's C code to C#. I looked at what &lt;a href="http://www.codeplex.com/Wiki/View.aspx?ProjectName=IronPython"&gt;IronPython&lt;/a&gt; does to take advantage of the 2.0 CLR. I was at &lt;a href="http://headius.blogspot.com/"&gt;Charles Nutter&lt;/a&gt;’s RubyConf 2005 &lt;a href="http://brainspl.at/articles/2005/12/01/rubyconf-files-resurrected"&gt;presentation&lt;/a&gt; and familiarized myself with what his team has done with &lt;a href="http://jruby.sourceforge.net/"&gt;JRuby&lt;/a&gt;. After starting development on my own C#/.NET version of Ruby I found that I didn't have the time to devote to such an effort. I’m very glad there is a viable solution now. I hope the .NET and Ruby communities rally around this effort.&lt;/p&gt;
&lt;p&gt;I can't wait to see if we can get Ruby to play nice Avalon/WPF like &lt;a href="http://www.simplegeek.com/"&gt;Chris Anderson&lt;/a&gt; has done with IronPython in &lt;a href="http://www.simplegeek.com/permalink.aspx/e0b2f9bc-5a8f-4d5f-b378-16ca634e0646"&gt;AvPad&lt;/a&gt;. Perhaps we can someday (sooner rather than later) get a Ruby on Rails project fully compiled to an ASP.NET assembly and running on IIS? But what I'm probably most excited for is to be able to create DSLs using Ruby and use them in the .NET applications I write at work.&lt;/p&gt;
&lt;p&gt;Now all we need is for an effort like &lt;a href="http://www.sapphiresteel.com/"&gt;Steel&lt;/a&gt; or &lt;a href="http://www.wilcob.com/"&gt;Wilco&lt;/a&gt;’s &lt;a href="http://www.wilcob.com/wilco/News/IronRuby-integration-with-VisualStudio.aspx"&gt;IronRuby Visual Studio integration&lt;/a&gt; to properly use Ruby.NET within Visual Studio 2005. Then we've got our first class IDE support and all those naysayers who complain that Ruby will never see wide-spread corporate adoption can respectfully stick it.:)&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blowmage/~4/GdUu_a1Wl9s" height="1" width="1"/&gt;</content><feedburner:origLink>http://blowmage.com/2006/06/22/ruby-net-beta-announced</feedburner:origLink></entry><entry><title type="text">Polymorphic Podcast on Object Thinking</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blowmage/~3/6qxKOEbDagI/object-thinking-podcast" /><updated>2006-06-16T00:00:00-07:00</updated><id>http://blowmage.com/2006/06/16/object-thinking-podcast</id><content type="html">&lt;p&gt;&lt;a href="http://www.dotnetjunkies.com/weblog/craigshoemaker/"&gt;Craig Shoemaker&lt;/a&gt; of the &lt;a href="http://polymorphicpodcast.com/"&gt;Polymorphic Podcast&lt;/a&gt; has just posted &lt;a href="http://polymorphicpodcast.com/shows/objectthinking/"&gt;part one&lt;/a&gt; of his interview with author Dr. David West about his book Object Thinking.  Craig contacted me a few months ago about &lt;a href="http://blowmage.com/2005/09/20/object-thinking"&gt;my review of Object Thinking&lt;/a&gt; and asked if I had any questions for Dr. West.  Boy do I.&lt;/p&gt;
&lt;p&gt;Here is the list of questions I sent Craig:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What is formalist thinking and why is it bad? It seems like such a good fit when dealing with computers.&lt;/li&gt;
&lt;li&gt;Why is OOP/object thinking so hard to get right? Besides making everyone read your book, how can help change a formalist culture to object thinking? Not just an individual's understanding, but the culture as a whole - like a corporate IT culture.&lt;/li&gt;
&lt;li&gt;Where are the future object thinkers coming from today? Methodology? (Agile? XP?) Languages? (Ruby? Python?)&lt;/li&gt;
&lt;li&gt;Are programming languages important? Where are we in regards to object-oriented languages? What is missing? Where do future languages need to go? Is formalist thinking reflected in language design? (I believe so.) What are the best examples of hermeneutic languages?&lt;/li&gt;
&lt;li&gt;How did you end up with Microsoft Press as a publisher? The book was Microsoft-agnostic, and it seemed like a strange fit to me.&lt;/li&gt;
&lt;li&gt;(Unsure about this question) Was the book successful? How was it received?&lt;/li&gt;
&lt;li&gt;What is Dr. West doing now? Teaching? Research? Slinging code?&lt;/li&gt;
&lt;li&gt;Does he have a blog? If not, why not?!? Seriously, he needs a blog! He is depriving the work of much needed object thinking by not having a blog.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Get the podcast &lt;a href="http://polymorphicpodcast.com/shows/objectthinking/"&gt;here&lt;/a&gt;!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blowmage/~4/6qxKOEbDagI" height="1" width="1"/&gt;</content><feedburner:origLink>http://blowmage.com/2006/06/16/object-thinking-podcast</feedburner:origLink></entry><entry><title type="text">Agile Databases</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blowmage/~3/t8DrBBYwVdM/agile-databases" /><updated>2006-04-28T00:00:00-07:00</updated><id>http://blowmage.com/2006/04/28/agile-databases</id><content type="html">&lt;p&gt;I am not an expert on this subject, although I play one on the Internet.
&lt;a href="http://www.jasonmauer.com/"&gt;Jason&lt;/a&gt; posted
&lt;a href="http://www.jasonmauer.com/EntryView.aspx?id=5ECDF2A0-68D4-45B9-B69F-48A84616420A"&gt;
some thoughts&lt;/a&gt; about the relatively light use of the data tier in a recent TDD
presentation he attended. Instead of writing the longest comment in the history
of his blog I thought I'd post my response here. The following is a brain dump only,
and subject to change as folks smarter than me correct me.&lt;/p&gt;
&lt;p&gt;Martin Fowler has an
&lt;a href="http://martinfowler.com/bliki/DatabaseStyles.html"&gt;article where he distinguishes&lt;/a&gt;
between "application" databases and "integration" databases. To me this is the main
difference between traditional "enterprise" thinking and the Agile approach. Most
Agilistas (and the &lt;a href="http://rubyonrails.org/"&gt;Ruby on Rails&lt;/a&gt; framework) like the "application" view, and
every DBA I've ever known assumes the "integration" view. Here is what Martin Fowler
has to say about the latter:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Integration databases end up with interfaces that have a large surface area and
limited abilities to separate interface from implementation. The resulting links
between applications and databases end up being brittle and thus difficult to change.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That perfectly describes my life.&lt;/p&gt;
&lt;p&gt;I can't point to too many examples where I've actually reused stored procedures.
Database functions yes, stored procedures no. I either end up writing new stored
procedures for my new application, because the new application needs to access the
data differently, or I hack up the stored procedures to do things they weren't originally
designed for and effectively tightly couple my data and application tiers. In fact,
my opinion is that the current irrational exuberance over SOA is mostly an acknowledgement
of the fact that stored procedures make a shitty abstraction layer. But that's just
my opinion, and unlike
&lt;a href="http://www.comicbookresources.com/columns/archive.cgi?column=ofo"&gt;Erik
Larsen&lt;/a&gt; I'm not that willing to concede I might be wrong. :)&lt;/p&gt;
&lt;p&gt;Rails takes the view that you should have your
&lt;a href="http://www.loudthinking.com/arc/000516.html"&gt;complexity in one place&lt;/a&gt;,
and code is a much nicer place than the database. That is one of the reasons Rails
is called "opinionated software", because this world-view permeates the framework.
Can you use Rails with an "integration" database? Sure, but it will be harder. And
even though I have no idea exactly what SOA really, truly is, I'd investigate using
SOA before strapping Rails on top of a legacy database where stored procedures are
the only way to get or set data. So the "application" database approach is
different, but its different for a reason.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blowmage/~4/t8DrBBYwVdM" height="1" width="1"/&gt;</content><feedburner:origLink>http://blowmage.com/2006/04/28/agile-databases</feedburner:origLink></entry><entry><title type="text">Ruby and Thought Leadership</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blowmage/~3/ssmF9RIns6M/ruby-thought-leadership" /><updated>2006-04-27T00:00:00-07:00</updated><id>http://blowmage.com/2006/04/27/ruby-thought-leadership</id><content type="html">&lt;p&gt;&lt;a href="http://pluralsight.com/blogs/dbox"&gt;Don Box&lt;/a&gt; may be a &lt;a href="http://www.loudthinking.com/arc/000569.html"&gt;few&lt;/a&gt; &lt;a href="http://www.loudthinking.com/arc/000571.html"&gt;weeks&lt;/a&gt; late to &lt;a href="http://blogs.sun.com/roller/page/jag"&gt;James Gosling&lt;/a&gt;'s &lt;a href="http://java.sys-con.com/read/193146.htm"&gt;comments&lt;/a&gt; about Ruby, but he does pay Ruby a nice compliment. &lt;a href="http://pluralsight.com/blogs/dbox/archive/2006/04/27/22819.aspx"&gt;He says&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;"Ruby has the language thought leadership position..."&lt;/blockquote&gt;
&lt;p&gt;In the comments Don implies that Ruby will overtake Java once Ruby gets a first class IDE. I think the Java community can rest easy, I don't see that happening for a long time, if ever.&lt;/p&gt;
&lt;p&gt;Oh, and one more thing, I agree with Don that .NET is slightly less vulnerable to Ruby than Java, but by only a fraction of a percent. Why? Because Ruby does have thought leadership. I gave a presentation on Ruby and Rails to some developer evangelists at Microsoft a few weeks ago and I tried to make that point crystal clear. Perhaps that first class IDE support should come from Visual Studio 2007?&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blowmage/~4/ssmF9RIns6M" height="1" width="1"/&gt;</content><feedburner:origLink>http://blowmage.com/2006/04/27/ruby-thought-leadership</feedburner:origLink></entry><entry><title type="text">Boise Code Camp Wrap-up</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blowmage/~3/rnMjV8na-cI/boise-code-camp-wrapup" /><updated>2006-03-21T00:00:00-08:00</updated><id>http://blowmage.com/2006/03/21/boise-code-camp-wrapup</id><content type="html">&lt;p&gt;The first &lt;a href="http://www.boisecodecamp.org/"&gt;Boise Code Camp&lt;/a&gt; was this past weekend. It was very well received and turnout was higher than we were expecting. Congratulations go out to &lt;a href="http://www.bsdg.org/"&gt;Jim&lt;/a&gt; and &lt;a href="http://blog.coryisakson.com/"&gt;Cory&lt;/a&gt; who were the main local leads for the camp. And special thanks to &lt;a href="http://www.jasonmauer.com/"&gt;Jason&lt;/a&gt; for presenting the idea to us and putting Microsoft's considerable weight behind the event.&lt;/p&gt;
&lt;p&gt;I presented sessions about &lt;a href="http://www.ruby-lang.org/"&gt;Ruby&lt;/a&gt; and &lt;a href="http://www.rubyonrails.org/"&gt;Rails&lt;/a&gt;. The Rails session went very well, mostly because I stole half of the session from &lt;a href="http://onestepback.org/"&gt;Jim Weirich&lt;/a&gt;’s &lt;a href="http://onestepback.org/index.cgi/News/IntroToRailsMovieAvailable.red"&gt;A Quick Introduction to Rails&lt;/a&gt; talk. :)&lt;/p&gt;
&lt;p&gt;The earlier Ruby session didn't go quite as smooth though. I've been struggling for the past two months on how to present about Ruby in 60 minutes. So much of what I love about Ruby are the subtle little things that Ruby does. I felt that you can't really show those subtle things until you explain where Ruby came from, the structure of the language, and how Ruby scripts are executed. Oh, and I was up almost the entire night before trying to solve a technical issue in my demo that I actually didn't ever get to. So I was very tired on top of a dry presentation. But the good news is that I learned from my mistake and the next time I present on Ruby I will be better prepared and more coherent. I promise.&lt;/p&gt;
&lt;p&gt;I've taken the last couple days to recover and I'll post the slides and code samples later this week. Thanks to all that attended, it was a great time and I felt that the event was a tremendous success! We hope to make the camp a regular event in Boise. I hope that some who attended my sessions will consider joining the &lt;a href="http://boiserb.com/"&gt;local Ruby user group&lt;/a&gt; as well.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blowmage/~4/rnMjV8na-cI" height="1" width="1"/&gt;</content><feedburner:origLink>http://blowmage.com/2006/03/21/boise-code-camp-wrapup</feedburner:origLink></entry><entry><title type="text">Ruby Thinking</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blowmage/~3/cxV6P7FVxfs/ruby-thinking" /><updated>2006-02-17T00:00:00-08:00</updated><id>http://blowmage.com/2006/02/17/ruby-thinking</id><content type="html">&lt;p&gt;I attended the &lt;a href="http://www.netdug.com/"&gt;local .NET user group&lt;/a&gt; last night and had a few people approach me about &lt;a href="http://boiserb.com/"&gt;Boise Ruby Brigade&lt;/a&gt; (The first meeting is next week! Sign up for the &lt;a href="http://groups.google.com/group/boiserb"&gt;mailing list&lt;/a&gt; today!).  In answering their questions about Ruby, I shared the fact that Ruby is a 'type-less' language.  You can take a variable and make it hold an integer, and then make it hold an array of strings.  Not that you ever would, but the point is that you could.  I said this to get them thinking about the implications.  Not surprisingly the discussion engendered some fairly strong "but I like my static typing!" reactions.  With this contrast between Ruby and the languages developers are currently using, I started to explain why this isn't such a bad thing and pointed out some of the benefits of such a language.  I made a claim I've made several times before, but not here yet: "In five years half of all new code we produce will be written using a dynamic language".  I said this at a .NET user group, as a professional .NET developer.&lt;/p&gt;
&lt;p&gt;I readily admit this is a bold statement, especially for those for whom dynamic languages such as Perl, Python, and Ruby aren't even on the radar.  But I stand by my prediction.  It is an obvious one to me, considering that both the .NET runtime and the JVM are adding more and more dynamic capabilities.  The discussion eventually degraded as one individual took issue with me and got a little upset about the merits of dynamic languages vs. static languages.  He would not concede that dynamic languages can be a better solution for certain applications, much less become convinced that it was a better way of programming.  It was then that I realized  I wasn't dealing with a static-typing bigot.  I was dealing with a formalist thinker.&lt;/p&gt;
&lt;p&gt;In my &lt;a href="/2005/09/20/object-thinking"&gt;review&lt;/a&gt; of "&lt;a href="http://www.amazon.com/exec/obidos/redirect?link_code=ur2&amp;amp;camp=1789&amp;amp;tag=blowmage-20&amp;amp;creative=9325&amp;amp;path=tg/detail/-/0735619654"&gt;Object Thinking&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=blowmage-20&amp;amp;l=ur2&amp;amp;o=1" alt="" style="border: medium none ! important; margin: 0px ! important;" border="0" height="1" width="1"&gt;" I outline Dr. West's definition of formalist and hermeneutic thinking, and how it compared to computer thinking vs. object thinking. Dr. West obviously advocates that we embrace object thinking and shun computer thinking, and outlines the benefits of such a world-view. It is an eye-opening book and I recommend it highly.&lt;/p&gt;
&lt;p&gt;The conclusion I've come to is that the C-based languages like C# and Java typically bias our thinking about programming. You need to understand how a computer runs code, but you also need to develop the discipline to divorce yourself from thinking that way when designing software. But this is hard to do because the environment reinforces the computer way of thinking with their structures and base libraries. To borrow from &lt;a href="http://www.martinfowler.com/"&gt;Martin Fowler&lt;/a&gt;'s article on &lt;a href="http://www.martinfowler.com/bliki/HumaneInterface.html"&gt;Humane Interfaces&lt;/a&gt;, take this example for getting the last element of an array:&lt;/p&gt;
&lt;p&gt;C#:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="csharp"&gt;&lt;span class="n"&gt;anArray&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;anArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Ruby:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="n"&gt;anArray&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;last&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;In C# and Java you have the C heritage of accessing variables by shifting your pointer to the correct memory location. In Ruby you simply call the appropriate method. In other words, the C#/Java approach is Implementation-specific, while the Ruby approach is Intention-specific. The difference between the C#/Java and Ruby approach is permeated throughout the base libraries for their respective environments. It is more difficult to write a Ruby-like library in C#/Java because it wouldn't behave like the other C#/Java libraries. And while you can write a C#/Java-like library in Ruby, the longer you use Ruby the more you start thinking the Ruby way. Ruby does this by making it so easy to stop thinking like a computer and start thinking like a human being.&lt;/p&gt;
&lt;p&gt;I suppose that what made this individual upset was that he worried that Ruby's simplicity and power would make him obsolete. As if by suggesting that Ruby code was more readable and understandable that the programmer was not needed and that the source code could be put in the hands of end users. Ruby is not a toy; Ruby is a tool to make programmers more productive. It makes programming easier. And I believe you can be happier when using Ruby because it gets out of your way. Ruby makes my life easier because I can focus on getting the job done and not talking to the computer or compiler. That's why I like Ruby.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blowmage/~4/cxV6P7FVxfs" height="1" width="1"/&gt;</content><feedburner:origLink>http://blowmage.com/2006/02/17/ruby-thinking</feedburner:origLink></entry><entry><title type="text">Boise Ruby Brigade</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blowmage/~3/V_w4Piaae3w/boiserb" /><updated>2006-01-27T00:00:00-08:00</updated><id>http://blowmage.com/2006/01/27/boiserb</id><content type="html">&lt;p&gt;Well, I finally did it. I started a user group for Ruby. I'm very excited about it, and I hope those who attend will be half as enthused about it as I am.&lt;/p&gt;
&lt;p&gt;I expect that the Boise Ruby Brigade (boise.rb for short) group will be two parts &lt;a href="http://ruby-lang.org/"&gt;Ruby&lt;/a&gt;, two parts &lt;a href="http://rubyonrails.org/"&gt;Rails&lt;/a&gt;, and one part &lt;a href="http://agilemanifesto.org/"&gt;Agile&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Check out the site here: &lt;a href="http://boiserb.com/"&gt;http://boiserb.com/&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blowmage/~4/V_w4Piaae3w" height="1" width="1"/&gt;</content><feedburner:origLink>http://blowmage.com/2006/01/27/boiserb</feedburner:origLink></entry><entry><title type="text">Who killed Web 2.0?</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blowmage/~3/PrkgKDzzvbk/who-killed-web-2-0" /><updated>2005-10-08T00:00:00-07:00</updated><id>http://blowmage.com/2005/10/08/who-killed-web-2-0</id><content type="html">This has been a difficult week for me. I don’t know how it happened, but somehow this week at the "Web 2.0 Conference":http://www.web2con.com/ (of all places) Web 2.0 died.&lt;/p&gt;
&lt;p&gt;Before this week I advocated for the notion of “Web 2.0” to those around me. Even with all the &lt;a href="http://www.oreillynet.com/pub/a/oreilly/tim/news/2005/09/30/what-is-web-20.html"&gt;confusion&lt;/a&gt; over what exactly the title meant, I liked the title because it conveyed the new promise for the Web. (And it was certainly better than the title “Semantic Web”.) After the dot-com bust and the painful years that followed, the importance of the Web was diminished. The Web lost attention and respect. And this was our own fault; we got caught up in our own self-importance and greed. Web 2.0 was a turning point; it was our chance to do it over, to do it right. It wasn’t about technology as much as it is about fulfilling the original promise of what the Web should be.&lt;/p&gt;
&lt;p&gt;We had a pretty good start too. Web services showed that Internet technologies were still innovative and that XML was useful for something other than configuration files. Google reminded us that the Web enables people and not technologies. Google also taught us that you can succeed by doing one thing and doing it well. Syndication feeds changed how users receive and view your content. AJAX showed you can be creative while building upon mature technologies. All this was happening because of people who believed in the promise of the Web post dot-com crash.&lt;/p&gt;
&lt;p&gt;But then suddenly we lost our minds. We changed the notion of Web 2.0 to be something that it can’t be. We started using Web 2.0 as another item on our feature list. We started promoting Web 2.0 as a project management methodology. We started promoting Web 2.0 as a business plan. And although I didn’t attend O’Reilly’s “Web 2.0 Conference”, most of what I’ve gathered from the blogosphere is that the conference was little more than a bazaar for newly-minted start-ups to hype themselves as if we were in the throes of the dot-com bubble. We corrupted ourselves again and tarnished our ideal, and for what? A shot at some new VC cash? A handful of links from the regular bloggers?&lt;/p&gt;
&lt;p&gt;Starting this week I hate the term Web 2.0. Now I have to go back to my job and just code. There is no greater good, there is no larger vision. Its just technology. You’ve killed my idealism. Again. Perhaps this was all my own fault for wanting to believe again. The more I think about it, the more Nicholas Carr is correct in his essay "The amorality of Web 2.0":http://www.roughtype.com/archives/2005/10/the_amorality_o.php where he states that those who view the Web in religious terms can "no longer see it objectively".&lt;/p&gt;
&lt;p&gt;Coincidentally or not, this week I’ve been viewing the presentations and listening to the podcasts from last week’s "Web Essentials 2005":http://we05.com/podcast/ conference in Sidney, Australia. I was originally looking for broadcasts of the Web 2.0 Conference sessions, but apparently the principle of "transparency" only applies to Web 2.0, and not it's conferences. I can’t shake the thought that the Web Essentials conference is what the Web 2.0 Conference could and should have been. I encourage everyone to give them a listen. If anything, it washed the bad taste out in my mouth left by the Web 2.0 Conference.&lt;/p&gt;
&lt;p&gt;Web 2.0 is dead, long live Web 2.0.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blowmage/~4/PrkgKDzzvbk" height="1" width="1"/&gt;</content><feedburner:origLink>http://blowmage.com/2005/10/08/who-killed-web-2-0</feedburner:origLink></entry><entry><title type="text">Book Review: Agile Web Development with Rails</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blowmage/~3/mb0h1Kus7BI/rails-book" /><updated>2005-09-30T00:00:00-07:00</updated><id>http://blowmage.com/2005/09/30/rails-book</id><content type="html">&lt;blockquote&gt;
  &lt;p&gt;Ruby on Rails is a framework that makes it easier to develop, deploy, and maintain web applications.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="amazon-product-link" style="float: right;"&gt;
 &lt;iframe src="http://rcm.amazon.com/e/cm?t=blowmage-20&amp;amp;o=1&amp;amp;p=8&amp;amp;l=as1&amp;amp;asins=097669400X&amp;amp;fc1=000000&amp;amp;=1&amp;amp;lc1=0000ff&amp;amp;bc1=000000&amp;amp;lt1=_blank&amp;amp;IS2=1&amp;amp;bg1=ffffff&amp;amp;f=ifr" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="http://blogs.pragprog.com/cgi-bin/pragdave.cgi"&gt;Dave Thomas&lt;/a&gt; and &lt;a href="http://www.loudthinking.com/"&gt;David Heinemeier Hansson&lt;/a&gt; wrote a killer book in "&lt;a href="http://www.amazon.com/exec/obidos/redirect?link_code=ur2&amp;amp;camp=1789&amp;amp;tag=blowmage-20&amp;amp;creative=9325&amp;amp;path=tg/detail/-/097669400X"&gt;Agile Web Development with Rails&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=blowmage-20&amp;amp;l=ur2&amp;amp;o=1" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /&gt;". I wish more technical books would be as reader-friendly and enjoyable as this book. While the book isn't a reference book, it isn't a brain-dead newbie overview either. It covers all of the important technical aspects of the Ruby on Rails framework from design to development and from installation to deployment. It also does a great job of explaining the philosophy behind Rails, and why Rails makes the assumptions it does. (Don't worry, it also shows you how to configure Rails to use your assumptions if they are different.) Overall, the book is a first-class introduction to the body and soul of the Rails framework.&lt;/p&gt;
&lt;p&gt;The reason I read the book was to really understand the &lt;a href="http://www.rubyonrails.org/"&gt;Ruby on Rails&lt;/a&gt; framework. I have dabbled with Rails for the last nine months or so, ever since I first read about &lt;a href="http://blog.curthibbs.us/"&gt;Curt Hibbs&lt;/a&gt;'s &lt;a href="http://www.onlamp.com/pub/a/onlamp/2005/01/20/rails.html"&gt;claim&lt;/a&gt; "that that you could develop a web application at least ten times faster with Rails than you could with a typical Java framework". Rails seems simple enough when you first approach it, but there is surprising depth once you scratch the surface. So like most things I don't fully understand right away, I decided to find some books on the subject. This book was so good I'm not sure if I'll need any others.&lt;/p&gt;
&lt;p&gt;Rails is a new framework for building web applications using the Model-View-Controller pattern, similar to most Java-based web apps. Unlike Java web apps which are usually heavy on configuration, Rails follows the philosophy of "don't repeat yourself" and "convention over configuration". This means that Rails is built to improve the time of development. But the promise of Rails to me is beyond making me more productive, once you become familiar with Rails and accept the conventions you will get more done while having more fun in the process.&lt;/p&gt;
&lt;p&gt;I think Rails has the potential to be a disruptive technology for web development. As more users become familiar with and expect Web 2.0 functionality web sites will be forced to change in order to deliver the new standard for usability. Web designers and developers will look to new frameworks such as Rails to help them achieve this functionality. Does this mean that Rails will lead the way to a new utopian world where proprietary frameworks like .NET and J2EE are abandoned, PHP is dethroned, and Rails becomes the de-facto standard for modern web development? Probably not, but I do think that Rails does show just how much everyone else will have to evolve or face extinction. To an extent, I think we are already seeing this with Microsoft's embrace of &lt;a href="http://atlas.asp.net/"&gt;AJAX&lt;/a&gt; for the next version of the ASP.NET framework. But for now Rails is here and arguably more fun to use.&lt;/p&gt;
&lt;p&gt;The meat of the book is divided into two main sections; an implementation of a simple e-commerce web site and an in-depth look at the various components of Rails. The book has a great layout. The book’s format, links, tips, index, appendixes, etc are all handy when skimming the book, although I found most of the book so compelling I read it cover to cover. (And I actually finished it, unlike most technical books I read.) Based on your experience you could skip one section or the other, but I would suggest not skipping around too much, the authors build on content presented earlier to deliver an engaging narrative that adds perspective and savor to the content. But if you do skip around the page number of the previous content is always listed.&lt;/p&gt;
&lt;p&gt;The introductory section does what you would expect; introduces Rails and shows you how to use it. In this section I think the readers are presented with more of the soul of Rails; explaining why things are they way they are and now that helps you. While you don't need to be familiar with the Ruby language, you do need to be familiar with web programming in general. While the authors claim that Rails is inherently Agile, I didn't find the tutorial particularly Agile. I was disappointed that the chapter on testing was separate from the rest of the tutorial. But I found this acceptable because the section was about getting to know Rails, and not about reinforcing the Agile methodology.&lt;/p&gt;
&lt;p&gt;The advanced section goes into detail of the body of Rails; explaining each component of Rails and how they work. I found these chapters particularly well written and was thankful for the narrative presentation. It would have been very easy for these chapters to be dry and boring to read. Near the end of this section there are chapters on additional topics such as Web 2.0, scalability, and deployment. I think there are more advanced books that could be written on certain subjects, specifically ActiveRecord, deployment, and scalability. (I only mention scalability because it has been a common &lt;a href="http://discuss.joelonsoftware.com/default.asp?joel.3.159134"&gt;criticism&lt;/a&gt; against Rails. I think the book did a fair job of explaining the framework's scalability.) Perhaps the Pragmatic Programmer folks could write some &lt;a href="http://pragmaticprogrammer.com/fridays.html"&gt;Friday&lt;/a&gt; books about these subjects?&lt;/p&gt;
&lt;p&gt;The success of the book is conveying the spirit of Rails. I think the future looks bright for the Rails framework because the contributors are committed to keeping Rails simple, lightweight, and not overly-complex like most J2EE solutions. I'll be using the lessons learned from the book such as "convention over configuration", "don't repeat yourself", integrated unit testing, and the Rails deployment model while designing a new .NET-based web framework at my work.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blowmage/~4/mb0h1Kus7BI" height="1" width="1"/&gt;</content><feedburner:origLink>http://blowmage.com/2005/09/30/rails-book</feedburner:origLink></entry><entry><title type="text">Book Review: Object Thinking</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blowmage/~3/euohsZ6o_Bo/object-thinking" /><updated>2005-09-20T00:00:00-07:00</updated><id>http://blowmage.com/2005/09/20/object-thinking</id><content type="html">&lt;blockquote&gt;
  &lt;p&gt;Despite any appearances to the contrary, objects are not something you do; objects are a way that you think.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="amazon-product-link" style="float: right"&gt;
  &lt;iframe src="http://rcm.amazon.com/e/cm?t=blowmage-20&amp;amp;o=1&amp;amp;p=8&amp;amp;l=as1&amp;amp;asins=0735619654&amp;amp;fc1=000000&amp;amp;=1&amp;amp;lc1=0000ff&amp;amp;bc1=000000&amp;amp;lt1=_blank&amp;amp;IS2=1&amp;amp;bg1=ffffff&amp;amp;f=ifr" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;David West's book "&lt;a href="http://www.amazon.com/exec/obidos/redirect?link_code=ur2&amp;amp;camp=1789&amp;amp;tag=blowmage-20&amp;amp;creative=9325&amp;amp;path=tg/detail/-/0735619654"&gt;Object Thinking&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=blowmage-20&amp;amp;l=ur2&amp;amp;o=1" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /&gt;" leads you down the garden path that you can create something new, inventive, and more than the sum of the parts. Your program can be something more than just data with algorithms. And the way to do that is by simply changing your thinking about the problem. Quite a promise, fortunately for me (and hopefully you) it delivers on the promise.&lt;/p&gt;
&lt;p&gt;This book is very different from every other
&lt;a href="http://en.wikipedia.org/wiki/Object-oriented_programming"&gt;OOP&lt;/a&gt; or &lt;a href="http://en.wikipedia.org/wiki/Design_patterns"&gt;design pattern&lt;/a&gt; book I've ever come across. The first half of the book is an intriguing philosophical exploration into both the art and science of programming and how they came about. It is the author's premise that there are fundamentally two schools of thought in Computer Science; formalist thinkers and &lt;a href="http://www.cis.drexel.edu/faculty/gerry/publications/interpretations/hermeneutic.html"&gt;hermeneutic thinkers&lt;/a&gt;. The majority of programmers (and western culture) are formalists, who share notions of control, centralization, mathematical, hierarchy, predictability, and provability. While a small minority &amp;lt;sarcasm&amp;gt;of mostly &lt;a href="http://en.wikipedia.org/wiki/Smalltalk"&gt;Smalltalkers&lt;/a&gt;&amp;lt;/sarcasm&amp;gt; follow a more humanistic approach to the design of software. I have to say I found the author's portrayal quite compelling. The concept of designing code using a humanistic approach blew me away.&lt;/p&gt;
&lt;p&gt;According to West's definitions, I am (or was) a formalist, and have been for as long as I can remember. Most every computer science or programming book I've ever read has been from the formalist position. I have worked hard and struggled many times to &lt;a href="http://en.wikipedia.org/wiki/Grok"&gt;grok&lt;/a&gt; OOP and design patterns in efforts to improve my project's design. Every time I thought I had a handle on it I found a new way to break the complex model I built. I hope I'm not alone in admitting that I have struggled at times trying to find the "perfect" design solution for a given project.&lt;/p&gt;
&lt;p&gt;The author then extends this discussion to define and differentiate computer thinking and object thinking. Computer thinking is limiting your design of the software to how you think the computer is going to perform. I found this way of thinking analogous to premature optimization, and we all know what &lt;a href="http://en.wikiquote.org/wiki/Donald_Knuth"&gt;Donald Knuth&lt;/a&gt; has says about that; "Premature optimization is the root of all evil (or at least most of it) in programming."&lt;/p&gt;
&lt;p&gt;Object thinkers strive to understand and model the domain fully, and letting their designs reflect the real world without respect to implementation. This may seem similar to use-cases, but I think there are important differences. Use-cases are a way to capture requirements, while object thinkers attempt to capture the behavior and responsibilities. Here is what the author has to say about thinking about object design:&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;You cannot begin to understand what must be until you understand what is. This assertion has two corollaries:&lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;Almost all of the objects you will ever need are already defined, and already have behavioral expectations associated with them, in the domain.&lt;/li&gt;
    &lt;li&gt;Almost all of the requirements of new development arise from a misalignment of behaviors and objects. Misalignment results when the wrong object (or group of objects) is providing a particular service, a service is more appropriately provided by a silicon-based object simulation instead of a carbon-based biological object, or, occasionally, no existing object is capable of providing the needed service.&lt;/li&gt;
  &lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;West gives some great guidelines for composing objects throughout the book. Here are some of the ideas that rang true to me:&lt;/p&gt;
&lt;div&gt;
  &lt;ul&gt;
    &lt;li&gt;Objects are lazy.&lt;/li&gt;
    &lt;li&gt;The four presuppositions for Object Thinking:&lt;ol&gt;
      &lt;li&gt;Everything is an object.&lt;/li&gt;
      &lt;li&gt;Simulation of a problem domain drives object discovery and definition.&lt;/li&gt;
      &lt;li&gt;Objects must be composable.&lt;/li&gt;
      &lt;li&gt;Distributed cooperation and communication must replace hierarchical centralized control as an organizational paradigm.&lt;/li&gt;
    &lt;/ol&gt;
    &lt;/li&gt;
    &lt;li&gt;Eliminating centralized control is one of the hardest lessons to be learned by object developers.&lt;/li&gt;
  &lt;/ul&gt;
&lt;/div&gt;
&lt;p&gt;Part of designing objects is delegating the right responsibilities to them. One way of determining the appropriateness of a design is to treat objects as if they were people. I found this analogy very effective when describing the book to others.&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;Many readers will be uncomfortable with the object-as-person metaphor. A major source of discomfort arises from consideration of characteristics that humans have that we obviously cannot replicate (and probably do not want to replicate) in software. Emotions, true intelligence, and will are major examples. The problem is made worse when descriptions of objects and their behaviors seem to allude to precisely this kind of nonreplicable characteristic—for example, "Objects are lazy."&lt;/p&gt;
  &lt;p&gt;Effective use of metaphor requires constant awareness that a metaphor is not a specification. It is often helpful to replace the metaphor—an object is a person—with a supposition: what if an object were a person? You can then ask questions about your design in this form: if an object were a person, would I write my code this way? Here are two examples:&lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;If an object were a person, would I directly access part of its memory without its knowledge instead of sending it a message asking for the information I need? If a developer is obsessed with performance, direct access is tempting. But reminding yourself that, as a person, you would not like someone directly probing your brain without your knowledge reminds you that this is a bad design choice. (It leads to undesirable coupling.)&lt;/li&gt;
    &lt;li&gt;Technology exists that would allow me to make hardware connections to your brain. I could then build a control box that would allow me to raise your hand whenever I pressed a button. Eventually this same technology might allow me to make you perform a complicated dance. Again, as a person, you might not like this, and neither would an object if it were a person.&lt;/li&gt;
  &lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;Once you have properly designed the objects to fit the problem domain, you should find that the application using the objects is less of a controller and more of a collaborator. The metaphor West uses is that of a theater and the application as a director putting the right actors/objects in the right place and the right time. This is in sharp contrast to the majority of projects I've worked on, which mostly maintain a death-grip on the application behavior. As I look back at the projects that I've been a part of, I've found that the more elegantly designed solutions have been the ones that have relied less on rigid control and more on the proper behavior of the actors/objects.&lt;/p&gt;
&lt;p&gt;The book is not without its failings however. I found the latter chapters that focused on a process for discovering object responsibilities using &lt;a href="http://en.wikipedia.org/wiki/Class-Responsibility-Collaboration_card"&gt;CRC cards&lt;/a&gt; less captivating. The author stated that this approach was presented to support and aid in the discovery of object's responsibilities, but that the approach was not mandatory to do so. To me the real value of the book was its challenge to how I thought, not what tools or practices I used.&lt;/p&gt;
&lt;p&gt;In the end, this was the book I have been looking for. I was tired of reading about the implementations of OOP, and wanted a book to just help me "get it" on a deeper level. I hope to find more books like this in the future. Highly recommended.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blowmage/~4/euohsZ6o_Bo" height="1" width="1"/&gt;</content><feedburner:origLink>http://blowmage.com/2005/09/20/object-thinking</feedburner:origLink></entry><entry><title type="text">Installing Typo on Shared Hosting</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blowmage/~3/qd5Z7ho9SbQ/installing-typo" /><updated>2005-08-31T00:00:00-07:00</updated><id>http://blowmage.com/2005/08/31/installing-typo</id><content type="html">&lt;p&gt;Okay, I've succumbed to the peer pressure, I've installed &lt;a href="http://www.rubyonrails.org/"&gt;Ruby on Rails&lt;/a&gt; and I'll even use it for this site. As I said earlier, my hosting provider is &lt;a href="http://www.hostingplex.com/redir.php?aff=blowmage"&gt;HostingPlex&lt;/a&gt;, and is not yet well suited to host Rails applications because &lt;a href="http://modruby.net/"&gt;mod_ruby&lt;/a&gt; and &lt;a href="http://fastcgi.com/"&gt;FastCGI&lt;/a&gt; are not installed with a shared-hosting account. I've been begging for first class Ruby support, but so far nothing has come of it. Of course, folks could always &lt;a href="mailto:sales@hostingplex.com?subject=Ruby and Rails Support?"&gt;contact HostingPlex&lt;/a&gt; and ask that they support Ruby and Rails in the future.&lt;/p&gt;
&lt;p&gt;I've used and said nice things about &lt;a href="http://rubyforge.org/projects/rublog/"&gt;Rublog&lt;/a&gt; in the past, but the reason I've decided to move from Rublog is the exact reason I chose it in the first place. Rublog works off the files on the file system, and not a database. I've found that if I need to make a change to an older article, the file's timestamp and subsequently the article's URL is changed. I've discovered that I like to correct spelling and grammar mistakes, and that ended up changing the chronological order of my site.&lt;/p&gt;
&lt;p&gt;I could have extended Rublog to change this behavior (similar to the extensions used in &lt;a href="http://www.blosxom.com/"&gt;blosxom&lt;/a&gt;), but I decided to switch to &lt;a href="http://typo.leetsoft.com/"&gt;Typo&lt;/a&gt; which uses Ruby on Rails. Typo recently released a new version that caches the generated pages on the file system, so the blog serves static HTML files the majority of the time. Compared to the performance to the older versions of Typo, the performance seems good enough (for now), even without mod_ruby and FastCGI.&lt;/p&gt;
&lt;p&gt;The first step is to download the latest version:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~
&lt;span class="nv"&gt;$ &lt;/span&gt;wget http://rubyforge.org/frs/download.php/5602/typo-2.5.5.tgz
&lt;span class="nv"&gt;$ &lt;/span&gt;tar zxvf typo-2.5.5.tgz
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Typo uses a database to store articles and comments, so the next step is going to be to create a new MySQL database. It seems HostingPlex doesn't allow you to create a new database using shell commands, so we'll use the tools available on CPanel. First, go to the CPanel and choose &lt;q&gt;MySQL Databases&lt;/q&gt; and create a new DB named &lt;code&gt;typo&lt;/code&gt;. This will actually create a new database named &lt;code&gt;&lt;em&gt;hostname&lt;/em&gt;_typo&lt;/code&gt;, because your account name is always added to the beginning. The same is true for user accounts. On the MySQL page create a new user named &lt;code&gt;typo&lt;/code&gt;. This will create the user &lt;code&gt;&lt;em&gt;hostname&lt;/em&gt;_typo&lt;/code&gt;. Use the same MySQL page to add the &lt;code&gt;&lt;em&gt;hostname&lt;/em&gt;_typo&lt;/code&gt; user to the &lt;code&gt;&lt;em&gt;hostname&lt;/em&gt;_typo&lt;/code&gt; database with &lt;q&gt;All&lt;/q&gt; privileges.&lt;/p&gt;
&lt;p&gt;Next you click the &lt;q&gt;phpMyAdmin&lt;/q&gt; link at the bottom of the page. This tool will allow you to create and maintain tables in your databases. Instead of creating each table manually, we will run the script that comes with Typo. Using a new instance of CPanel, go into the &lt;q&gt;File Manager&lt;/q&gt;, navigate to the &lt;code&gt;typo-2.5.5/db&lt;/code&gt; directory and view the &lt;code&gt;schema.mysql.sql&lt;/code&gt; file. Copy the contents of the file and paste them into the &lt;q&gt;SQL&lt;/q&gt; tab in &lt;q&gt;phpMyAdmin&lt;/q&gt;. You should add 15 new tables to your schema.&lt;/p&gt;
&lt;p&gt;Now that you have the tables created, you need to tell Typo what database to use. To do this, edit the &lt;code&gt;typo-2.5.5/config/database.yml&lt;/code&gt; file and add your database credentials.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="yaml"&gt;&lt;span class="l-Scalar-Plain"&gt;production&lt;/span&gt;&lt;span class="p-Indicator"&gt;:&lt;/span&gt;
  &lt;span class="l-Scalar-Plain"&gt;adapter&lt;/span&gt;&lt;span class="p-Indicator"&gt;:&lt;/span&gt; &lt;span class="l-Scalar-Plain"&gt;mysql&lt;/span&gt;
  &lt;span class="l-Scalar-Plain"&gt;database&lt;/span&gt;&lt;span class="p-Indicator"&gt;:&lt;/span&gt; &lt;span class="l-Scalar-Plain"&gt;blowmage_typo&lt;/span&gt;
  &lt;span class="l-Scalar-Plain"&gt;host&lt;/span&gt;&lt;span class="p-Indicator"&gt;:&lt;/span&gt; &lt;span class="l-Scalar-Plain"&gt;localhost&lt;/span&gt;
  &lt;span class="l-Scalar-Plain"&gt;username&lt;/span&gt;&lt;span class="p-Indicator"&gt;:&lt;/span&gt; &lt;span class="l-Scalar-Plain"&gt;blowmage_typo&lt;/span&gt;
  &lt;span class="l-Scalar-Plain"&gt;password&lt;/span&gt;&lt;span class="p-Indicator"&gt;:&lt;/span&gt; &lt;span class="l-Scalar-Plain"&gt;super_secret_password&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;We need to tell Typo where to find Ruby and where to find the Typo scripts. We do this in the &lt;code&gt;typo-2.5.5/public/dispatch.cgi&lt;/code&gt; script. (Because HostingPlex doesn't have Ruby installed, we installed a local version &lt;a href="/2005/05/27/installing-ruby"&gt;earlier&lt;/a&gt;.) We also need to tell Typo that we should be running in the production environment by setting the RAILS_ENV environment value. This will tell Typo to use caching for improved performance. Change the first few lines to this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="c1"&gt;#!/home/blowmage/local/bin/ruby&lt;/span&gt;
&lt;span class="no"&gt;ENV&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;RAILS_ENV&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;production&amp;quot;&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;/home/blowmage/typo-2.5.5/config/environment&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;We also need to tell Apache to use the &lt;code&gt;dispatch.cgi&lt;/code&gt; script instead of the default &lt;code&gt;dispatch.fgci&lt;/code&gt;. In the &lt;code&gt;typo-2.5.5/public/.htaccess&lt;/code&gt; file, change the last RewriteRule line to the following:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="text"&gt;RewriteRule ^(.*)$ dispatch.cgi [QSA,L]
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Like all Rails apps, the "typo-2.5.5/public" directory is what the web server is supposed to serve files from. However, with our shared accounts we don't have permissions to change where Apache to serves the site. Instead, we will copy the files from the public directory to the directory that Apache uses. We also need to tell Typo where to write the cached files so that Typo and Rails don't load into memory with every request – killing performance. The configuration isn't difficult, but it needs to be set in two different files. First, the &lt;code&gt;typo-2.5.5/config/environments/production.rb&lt;/code&gt; file needs the following lines added to it.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="no"&gt;ActionController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;page_cache_directory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;/home/blowmage/public_html&amp;quot;&lt;/span&gt;
&lt;span class="no"&gt;ActionController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;page_cache_extension&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;.html&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Second, we need to tell Typo's &lt;code&gt;PageCache&lt;/code&gt; class where to remove the cached entries from. (I believe this is a flaw in the current design, and I have opened a &lt;a href="http://typo.leetsoft.com/trac/ticket/328"&gt;case&lt;/a&gt;. As of this writing, the case has not yet been assigned.) So change the &lt;code&gt;typo-2.5.5/app/models/page_cache.rb&lt;/code&gt; file to the following:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PageCache&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;

  &lt;span class="n"&gt;cattr_accessor&lt;/span&gt; &lt;span class="ss"&gt;:public_path&lt;/span&gt;
&lt;span class="c1"&gt;#  @@public_path = RAILS_ROOT + &amp;quot;/public&amp;quot;&lt;/span&gt;
  &lt;span class="vc"&gt;@@public_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;/home/blowmage/public_html&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Alright, we're almost there! We just need to copy the public files to our site.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~
&lt;span class="nv"&gt;$ &lt;/span&gt;cp –r typo-2.5.5/public/* public_html
&lt;span class="nv"&gt;$ &lt;/span&gt;cp –r typo-2.5.5/public/.htaccess public_html/.htaccess
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Now when you browse to your site you will be prompted for your login information. Enter your info and you will be redirected to the admin section. You can now create new articles and categories. Enjoy.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blowmage/~4/qd5Z7ho9SbQ" height="1" width="1"/&gt;</content><feedburner:origLink>http://blowmage.com/2005/08/31/installing-typo</feedburner:origLink></entry><entry><title type="text">Installing Rails on Shared Hosting</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blowmage/~3/vSdfBAwK2sI/installing-rails" /><updated>2005-08-20T00:00:00-07:00</updated><id>http://blowmage.com/2005/08/20/installing-rails</id><content type="html">&lt;p&gt;I stated in an earlier entry on installing the excellent &lt;a href="http://www.pragprog.com/pragdave"&gt;Rublog&lt;/a&gt; that I may be simply delaying the inevitable move to &lt;a href="http://rubyonrails.com/"&gt;Ruby on Rails&lt;/a&gt;, and I was right. The siren call of the new and shiny has won me over, and I decided to extend this site's Ruby support to include Rails. (The fact that the &lt;a href="http://typo.leetsoft.com/"&gt;Typo&lt;/a&gt; blog engine now renders static HTML files dramatically improving performance also helped, but more on that next time.)&lt;/p&gt;
&lt;p&gt;It is possible to install and use Rails on &lt;a href="http://www.hostingplex.com/redir.php?aff=blowmage"&gt;HostingPlex&lt;/a&gt;, but the performance will suffer. Rails is a large framework, and not having &lt;a href="http://modruby.net/"&gt;mod_ruby&lt;/a&gt; and &lt;a href="http://fastcgi.com/"&gt;FastCGI&lt;/a&gt; installed hurts performance tremendously. Until they are properly supported by HostingPlex, you should use at your own risk. But since you're reading this, I'll assume that you want to continue with installing Rails. ;)&lt;/p&gt;
&lt;p&gt;The first step to installing Rails is to install &lt;a href="http://docs.rubygems.org/"&gt;RubyGems&lt;/a&gt;. Truth be known, you probably want to install gems whether you install Rails or not. Installing gems is as easy as our previous installations:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~
&lt;span class="nv"&gt;$ &lt;/span&gt;wget http://rubyforge.org/frs/download.php/3463/rubygems-0.8.8.tgz
&lt;span class="nv"&gt;$ &lt;/span&gt;tar zxvf rubygems-0.8.8.tgz
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;rubygems-0.8.8
&lt;span class="nv"&gt;$ &lt;/span&gt;ruby setup.rb
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Once gems is installed, installing Rails or any other gem is the easiest thing in the world:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;gem install rails
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Be sure to answer &lt;code&gt;y&lt;/code&gt; when prompted by the Rails installation. While you are at it, you can also install a couple supporting libraries common to Rails apps.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;gem update mysql
&lt;span class="nv"&gt;$ &lt;/span&gt;gem install redcloth
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;By default, Rails connects to a MySQL database using a library written in Ruby. This library isn't as fast as using a compiled library. &lt;a href="http://blog.x180.net/"&gt;James Duncan Davidson&lt;/a&gt; has a great &lt;a href="http://blog.x180.net/2005/07/rails_and_mysql.html"&gt;article&lt;/a&gt; on improving the performance or Rails apps by using the native library. To install the native library you should use these commands:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~
&lt;span class="nv"&gt;$ &lt;/span&gt;wget http://tmtm.org/downloads/mysql/ruby/mysql-ruby-2.6.3.tar.gz
&lt;span class="nv"&gt;$ &lt;/span&gt;tar zxvf mysql-ruby-2.6.3.tar.gz
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;mysql-ruby-2.6.3
&lt;span class="nv"&gt;$ &lt;/span&gt;ruby extconf.rb --with-mysql-dir&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;/local/mysql &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; make &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; make install
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Is it me, or are these tasks getting easier?&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blowmage/~4/vSdfBAwK2sI" height="1" width="1"/&gt;</content><feedburner:origLink>http://blowmage.com/2005/08/20/installing-rails</feedburner:origLink></entry><entry><title type="text">Extending Rublog with ERb</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blowmage/~3/Eikku340Jo8/extending-rublog" /><updated>2005-07-08T00:00:00-07:00</updated><id>http://blowmage.com/2005/07/08/extending-rublog</id><content type="html">&lt;p&gt;&lt;a href="http://rubyforge.org/projects/rublog/"&gt;Rublog&lt;/a&gt; is a great web site system and has many interesting features. The script works off the files on the file system and supports different file types including RDoc, HTML, and plain text. I wanted to extend Rublog to also support embedded Ruby in &lt;code&gt;.rhtml&lt;/code&gt; files, and here is how I did it.&lt;/p&gt;
&lt;p&gt;I decided to use &lt;a href="http://www.ruby-doc.org/stdlib/libdoc/erb/rdoc/"&gt;ERb&lt;/a&gt; instead of &lt;a href="http://www.modruby.net/"&gt;eRuby&lt;/a&gt;. eRuby is a native library, while ERb is written in Ruby, which makes it slower. I would have chosen to use eRuby, but I couldn't find any documentation on how to use it from a Ruby script, so I decided to follow the examples I could find online that were using ERb. I assume there are better ways to implement this, but this is good enough for me (for now).&lt;/p&gt;
&lt;p&gt;Rublog makes supporting new file types easy. The first step is to create a new converter class. You'll need to inherit from the &lt;code&gt;BaseConverter&lt;/code&gt; class. I followed the example of the &lt;code&gt;HtmlConverter&lt;/code&gt; class that comes with Rublog. You can find the converter classes in the &lt;code&gt;&lt;em&gt;rublog&lt;/em&gt;/convertors/&lt;/code&gt; directory. Here is my &lt;code&gt;RHtmlConvertor.rb&lt;/code&gt; script:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="c1"&gt;# The rhtml convertor reads a file and performs the ERb render.&lt;/span&gt;
&lt;span class="c1"&gt;# Like the html converter, we look for a natural title.&lt;/span&gt;
&lt;span class="c1"&gt;# If we can&amp;#39;t find it, we use the first line (removing it&lt;/span&gt;
&lt;span class="c1"&gt;# if it doesn&amp;#39;t look like valid HTML)&lt;/span&gt;

&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;erb&amp;#39;&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;BaseConvertor&amp;#39;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RHtmlConvertor&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;BaseConvertor&lt;/span&gt;
  &lt;span class="n"&gt;handles&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;rhtml&amp;quot;&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;convert_html&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;all_entries&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;body&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Untitled&amp;quot;&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=~&lt;/span&gt; &lt;span class="sr"&gt;/&amp;lt;title&amp;gt;(..*?)&amp;lt;\/title&amp;gt;/m&lt;/span&gt;
            &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vg"&gt;$1&lt;/span&gt;
    &lt;span class="k"&gt;elsif&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=~&lt;/span&gt; &lt;span class="sr"&gt;/&amp;lt;h1[^&amp;gt;&amp;lt;]*&amp;gt;(.*?)&amp;lt;\/h1&amp;gt;/&lt;/span&gt;
            &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vg"&gt;$1&lt;/span&gt;
    &lt;span class="k"&gt;elsif&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sub!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/\A\s*([^\s&amp;lt;].*)/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vg"&gt;$1&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="n"&gt;erb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="no"&gt;ERB&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;erb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;
    &lt;span class="n"&gt;erb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="no"&gt;ERB&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;erb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;

    &lt;span class="no"&gt;HTMLEntry&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The next step is to add the new converter to your Rublog CGI script. Find where the &lt;code&gt;load_convertors&lt;/code&gt; method is called and add the text &lt;q&gt;RHtml&lt;/q&gt; to the list. You need to add it before the text &lt;q&gt;Html&lt;/q&gt;, or else the &lt;code&gt;HtmlConverter.rd&lt;/code&gt; script will handle your &lt;code&gt;.rhtml&lt;/code&gt; files. You need to be aware of the order the converters are loaded because the converters don't look at the file extension, they simply match the end of the file name.&lt;/p&gt;
&lt;p&gt;Confused? Don't worry about it. Here is what the load_convertors line looks like in my CGI script:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;RubLog::load_convertors(*%w{ RHtml RDoc Text Html })&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That's it, you should be ready to go. Add the following text to a file with the &lt;code&gt;.rhtml&lt;/code&gt; extension to your blog directory and watch the magic.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="rhtml"&gt;&lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Testing ERb and RHTML files in Rublog&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;This is just a test of supporting *.rhtml files in
Rublog. This additional functionality will render the *.rhtml source
with ERb and display the output.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;For example, the following code is executed below:&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;hr&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;&lt;/span&gt;
&lt;span class="ni"&gt;&amp;amp;lt;&lt;/span&gt;p&lt;span class="ni"&gt;&amp;amp;gt;&amp;amp;lt;&lt;/span&gt;% 5.times do %&lt;span class="ni"&gt;&amp;amp;gt;&lt;/span&gt;Hello &lt;span class="ni"&gt;&amp;amp;lt;&lt;/span&gt;% end %&lt;span class="ni"&gt;&amp;amp;gt;&lt;/span&gt;Ruby!&lt;span class="ni"&gt;&amp;amp;lt;&lt;/span&gt;/p&lt;span class="ni"&gt;&amp;amp;gt;&lt;/span&gt;

&lt;span class="ni"&gt;&amp;amp;lt;&lt;/span&gt;ul&lt;span class="ni"&gt;&amp;amp;gt;&lt;/span&gt;

&lt;span class="ni"&gt;&amp;amp;lt;&lt;/span&gt;li&lt;span class="ni"&gt;&amp;amp;gt;&lt;/span&gt;Addition: &lt;span class="ni"&gt;&amp;amp;lt;&lt;/span&gt;%= 1+2 %&lt;span class="ni"&gt;&amp;amp;gt;&amp;amp;lt;&lt;/span&gt;/li&lt;span class="ni"&gt;&amp;amp;gt;&lt;/span&gt;
&lt;span class="ni"&gt;&amp;amp;lt;&lt;/span&gt;li&lt;span class="ni"&gt;&amp;amp;gt;&lt;/span&gt;Concatenation: &lt;span class="ni"&gt;&amp;amp;lt;&lt;/span&gt;%= &amp;quot;cow&amp;quot; + &amp;quot;boy&amp;quot; %&lt;span class="ni"&gt;&amp;amp;gt;&amp;amp;lt;&lt;/span&gt;/li&lt;span class="ni"&gt;&amp;amp;gt;&lt;/span&gt;
&lt;span class="ni"&gt;&amp;amp;lt;&lt;/span&gt;/ul&lt;span class="ni"&gt;&amp;amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;hr&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;%&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;times&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;Hello &lt;span class="cp"&gt;&amp;lt;%&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;Ruby!&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;Addition: &lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;Concatenation: &lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;cow&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;boy&amp;quot;&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;hr&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;This concludes our test...&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;You may be asking yourself why this would be necessary, or even desired. To be honest part of why I wrote this was to see if I could do it, but I do see value in enabling a piece if web content with server-side functionality. It allows me to add new behavior without duplicating the navigation and presentation that Rublog gives you. At least, that's how I justified it. ;)&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blowmage/~4/Eikku340Jo8" height="1" width="1"/&gt;</content><feedburner:origLink>http://blowmage.com/2005/07/08/extending-rublog</feedburner:origLink></entry><entry><title type="text">Installing Rublog on Shared Hosting</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blowmage/~3/0u3gPfCu2ws/installing-rublog" /><updated>2005-06-24T00:00:00-07:00</updated><id>http://blowmage.com/2005/06/24/installing-rublog</id><content type="html">&lt;p&gt;One of my requirements when looking for a blogging engine was to have the engine pull the content from the file system. I just wanted a very simple and lightweight framework. I also wanted to edit my content files manually, and not through some web-based WYSIWYG interface. I'm not distrustful of more complicated blogging engines, I use them on my other sites, but I thought this site needed a different approach. I wanted to be closer to the metal.&lt;/p&gt;
&lt;p&gt;I originally started out using &lt;a href="http://www.blosxom.com/"&gt;blosxom&lt;/a&gt;, and I liked that approach very much. But I've never been much of a &lt;a href="http://www.perl.com/"&gt;Perl&lt;/a&gt; hack, and I was faced with either learning more Perl or finding a different solution. Once I found &lt;a href="http://ruby-lang.org/"&gt;Ruby&lt;/a&gt; I knew I had my language, and I just needed an engine. I thought about porting blosxom to Ruby, but I decided that I would do better with &lt;a href="http://rubyforge.org/projects/rublog/"&gt;Rublog&lt;/a&gt; as my starting point. Rublog isn't 100% what I'd like it to be out of the box, but I find it very easy to change to my liking. I figure one of the tenants of &lt;a href="http://www.artima.com/intv/dry.html"&gt;&lt;q&gt;Don't Repeat Yourself&lt;/q&gt;&lt;/a&gt; is not reinventing the wheel when you don't have to.&lt;/p&gt;
&lt;p&gt;This may seem to fly in the face of the current &lt;a href="http://rubyonrails.com/"&gt;Rails&lt;/a&gt; hype, (and I may indeed only be delaying the inevitable move to Rails) but until my hosting provider has more support for Rails I'm very happy with where I'm at with &lt;a href="http://www.pragprog.com/pragdave"&gt;Rublog&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You start by downloading and uncompressing the Rublog source:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~
&lt;span class="nv"&gt;$ &lt;/span&gt;wget http://rubyforge.org/frs/download.php/1668/rublog-1.0.tgz
&lt;span class="nv"&gt;$ &lt;/span&gt;tar zxtar zxvf rublog-1.0.tgz
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The next step is to copy the CGI script to your &lt;code&gt;public_html&lt;/code&gt; directory. I've renamed it for reasons that I'll explain later. I also created a new directory to store all my blog entries. I find it best to not store these blog entries in the &lt;code&gt;public_html&lt;/code&gt; directory, since you probably don't want folks to bypass the CGI script to get to the content.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;cp rublog-1.0/rublog.cgi public_html/index.cgi
&lt;span class="nv"&gt;$ &lt;/span&gt;mkdir blog
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Before you browse to &lt;code&gt;/index.cgi&lt;/code&gt; and see the content, you need to change the CGI file to point to your local instance of Ruby. Be sure to change &lt;code&gt;/home/&lt;i&gt;blowmage&lt;/i&gt;&lt;/code&gt; to the path to your account's home directory:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="c1"&gt;#!/home/&amp;lt;i&amp;gt;blowmage&amp;lt;/i&amp;gt;/local/bin/ruby&lt;/span&gt;
&lt;span class="no"&gt;RubLogSourceLocation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;/home/blowmage/rublog-1.0&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The CGI will show you the Rublog documentation by default. Once you are comfortable with the way Rublog works, you should update the &lt;code&gt;index.cgi&lt;/code&gt; script to look at the &lt;code&gt;blog&lt;/code&gt; directory for the blog content:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="no"&gt;BLOG_DIR&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;/home/blowmage/blog&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;You can now browse your site through the script: &lt;code&gt;/index.cgi&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;However, I hate seeing a CGI script in the URL. I feel this doesn't &lt;a href="http://www.useit.com/alertbox/990321.html"&gt;promote&lt;/a&gt; &lt;a href="http://www.w3.org/Provider/Style/URI"&gt;good&lt;/a&gt; &lt;a href="http://www.w3.org/DesignIssues/HTTP-URI"&gt;URIs&lt;/a&gt;. If we could hide the CGI script then we are free to replace our site's implementation without breaking search engine results and people's bookmarks. Doing this is much easier than it sounds, and it involves our old friend the &lt;code&gt;.htaccess&lt;/code&gt; file.&lt;/p&gt;
&lt;p&gt;What we need to do is tell the &lt;code&gt;.htaccess&lt;/code&gt; file to route all failed requests through our Rublog CGI script. This means that requests to existing resources such as other CGI scripts or HTML or image files will continue to be served. The requests for files that don't exist are sent to the Rublog CGI where Rublog determines what to serve for that request. This is accomplished by adding the following rewrite rules to the &lt;code&gt;.htaccess&lt;/code&gt; file.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="text"&gt;RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.cgi/$1 [L,QSA]
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Rublog is now installed and will respond to requests even if they are missing the script path. However, Rublog wasn't written with the expectation that we would want to hide the script path, and the script path is embedded throughout the Rublog code. I have made additional changes to Rublog to hide the script path, but those are outside of the scope of this document.&lt;/p&gt;
&lt;p&gt;That's it! Despite the hype machine working overtime promoting Rails, I've found the hardest part was installing Ruby. I hope this article has been of interest to you. If you have any suggestions or corrections &lt;a href="mailto:mike@blowmage.com?subject= Installing Ruby on HostingPlex"&gt;drop me a line&lt;/a&gt;. With Ruby installed, you're on your way to become more productive and have more fun. Good luck!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blowmage/~4/0u3gPfCu2ws" height="1" width="1"/&gt;</content><feedburner:origLink>http://blowmage.com/2005/06/24/installing-rublog</feedburner:origLink></entry><entry><title type="text">Installing eRuby on Shared Hosting</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blowmage/~3/JZKDAUiGO6M/installing-eruby" /><updated>2005-06-10T00:00:00-07:00</updated><id>http://blowmage.com/2005/06/10/installing-eruby</id><content type="html">&lt;p&gt;Now that we've got &lt;a href="/2005/05/27/installing-ruby"&gt;Ruby installed&lt;/a&gt;, we can use it to write CGI scripts. But that is so 1995, isn' t there a better way to use Ruby to create web sites? Of course there is, and the first step is &lt;a href="http://raa.ruby-lang.org/project/eruby"&gt;eRuby&lt;/a&gt;. eRuby interprets Ruby code that is embedded in a text file. Our interest is embedding Ruby code to a HTML file, much like &lt;a href="http://microsoft.com/"&gt;Microsoft's&lt;/a&gt; &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnanchor/html/activeservpages.asp"&gt;Active Server Pages&lt;/a&gt;, &lt;a href="http://sun.com/"&gt;Sun's&lt;/a&gt; &lt;a href="http://java.sun.com/products/jsp/"&gt;Java Server Pages&lt;/a&gt;, and &lt;a href="http://zend.com/"&gt;Zend's&lt;/a&gt; &lt;a href="http://php.net/"&gt;PHP&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Just like installing Ruby, this is surprisingly easy to do, as we simply enter these commands in at the shell:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~
&lt;span class="nv"&gt;$ &lt;/span&gt;wget http://www.modruby.net/archive/eruby-1.0.5.tar.gz
&lt;span class="nv"&gt;$ &lt;/span&gt;tar zxvf eruby-1.0.5.tar.gz
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;eruby-1.0.5
&lt;span class="nv"&gt;$ &lt;/span&gt;./configure.rb --prefix&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;/local &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; make &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; make install
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~
&lt;span class="nv"&gt;$ &lt;/span&gt;cp &lt;span class="nb"&gt;local&lt;/span&gt;/bin/eruby public_html/cgi-bin/eruby
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;We've installed, compiled, and copied the &lt;code&gt;eruby&lt;/code&gt; executable file to our site's &lt;code&gt;cgi-bin&lt;/code&gt; directory. Our site is now ready to use the executable to parse our HTML files for Ruby code and execute it. To do this, we need to associate our files with the CGI executable. Parsing our files for Ruby code does add some overhead, so we probably don't want to parse every single file, so we'll associate the file extension &lt;code&gt;.rhtml&lt;/code&gt; with &lt;code&gt;eruby&lt;/code&gt;. We make this association in the &lt;code&gt;.htaccess&lt;/code&gt; file in the &lt;code&gt;public_html&lt;/code&gt; directory by adding these lines:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="text"&gt;AddType application/x-httpd-eruby .rhtml
Action  application/x-httpd-eruby /cgi-bin/eruby
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;If you don't have an &lt;code&gt;.htaccess&lt;/code&gt; file in your &lt;code&gt;public_html&lt;/code&gt; directory then simply create one. Let's test this! Create a new file in your &lt;code&gt;public_html&lt;/code&gt; directory named &lt;code&gt;hello.rhtml&lt;/code&gt;. The file should include the following lines:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="rhtml"&gt;&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Hello Ruby!&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Hello Ruby!&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;&amp;lt;%&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;times&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;
Hello
&lt;span class="cp"&gt;&amp;lt;%&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;
Ruby!&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;When you browse to the file you will see a message that displays &lt;q&gt;Hello Hello Hello Hello Hello Ruby!&lt;/q&gt; then you have officially installed eRuby, congratulations.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blowmage/~4/JZKDAUiGO6M" height="1" width="1"/&gt;</content><feedburner:origLink>http://blowmage.com/2005/06/10/installing-eruby</feedburner:origLink></entry><entry><title type="text">Installing Ruby on Shared Hosting</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blowmage/~3/EYcSJ-nHXGs/installing-ruby" /><updated>2005-05-28T00:00:00-07:00</updated><id>http://blowmage.com/2005/05/28/installing-ruby</id><content type="html">&lt;p&gt;The hosting provider for this site is &lt;a href="http://www.hostingplex.com/redir.php?aff=blowmage"&gt;HostingPlex&lt;/a&gt;. HostingPlex doesn't support &lt;a href="http://ruby-lang.org/"&gt;Ruby&lt;/a&gt; &lt;q&gt;out-of-the-box&lt;/q&gt;, which is unfortunate because Ruby is gaining momentum and has a lot of mind share with web developers right now. I've made the following modifications to my account in order to run Ruby and I hope you find them useful. Hopefully the steps I tool will translate to other hosting providers and will be useful to others.&lt;/p&gt;
&lt;p&gt;Much of this information is a direct result of an excellent &lt;a href="http://www.viarails.net/articles/2005/04/22/installing-typo-on-a-freeshell-org-account"&gt;article&lt;/a&gt; on &lt;a href="http://www.viarails.net/"&gt;Wesley Moxam&lt;/a&gt;'s blog. I am going to initially focus on installing and using Ruby and Rublog, and not necessarily &lt;a href="http://rubyonrails.com/"&gt;Rails&lt;/a&gt;. Although once Ruby is installed and configured, installing and using Rails shouldn't be too hard to do. However, HostingPlex is not well suited to Rails hosting (yet) because some server-side configurations such as &lt;a href="http://modruby.net/"&gt;mod_ruby&lt;/a&gt; and &lt;a href="http://fastcgi.com/"&gt;FastCGI&lt;/a&gt; are very difficult or impossible to install with a shared-hosting account. Hopefully HostingPlex will change their mind and start supporting Ruby and Rails in the future.&lt;/p&gt;
&lt;p&gt;Ruby is not currently installed on the HostingPlex servers, as I assume is the case for the majority of Linux hosting. To install Ruby, you'll need access to the shell for your account. The Unix shell is similar to the Command Prompt on Windows machines. You can access the shell through your CPanel interface by clicking the &lt;q&gt;SSH/Shell Access&lt;/q&gt; link.&lt;/p&gt;
&lt;p&gt;We'll start with a simple command to ask Ruby to tell us what version it is.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;ruby -v
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;If you don't have Ruby installed you should see a message such as &lt;q&gt;command not found&lt;/q&gt;. If you do have Ruby installed, then you can skip ahead.&lt;/p&gt;
&lt;p&gt;To install Ruby we will download and compile Ruby from the source code. We'll install Ruby into a new directory named &lt;code&gt;local&lt;/code&gt;, because we don't have permissions to install Ruby for all users on the server. We will follow this process for the other programs we'll eventually install.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~
&lt;span class="nv"&gt;$ &lt;/span&gt;wget ftp://ftp.ruby-lang.org/pub/ruby/ruby-1.8.2.tar.gz
&lt;span class="nv"&gt;$ &lt;/span&gt;tar zxvf ruby-1.8.2.tar.gz
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;ruby-1.8.2
&lt;span class="nv"&gt;$ &lt;/span&gt;./configure --prefix&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;/local &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; make &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; make install
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Our next step is to ask Ruby what version is installed.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;ruby -v
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Did that fail again? Don't worry, this is because we installed Ruby in a non-standard location, and the shell doesn't know to look in the new directory. To make the shell look in that directory, run the following command:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;/local/bin:&lt;span class="nv"&gt;$PATH&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Now you should be able to ask Ruby for its version without receiving an error message. Of course, it would be a pain to run the preceding &lt;code&gt;PATH&lt;/code&gt; command every time we connected to the server, so we'll create a new file named &lt;code&gt;.bash_profile&lt;/code&gt;. In this file, you should add the now following line:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="text"&gt;PATH=$HOME/local/bin:$PATH
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Now every time you connect to the server through the shell, your account will look in your &lt;code&gt;local&lt;/code&gt; directory for Ruby.&lt;/p&gt;
&lt;p&gt;Let's test this! Create a new file in your &lt;code&gt;public_html&lt;/code&gt; directory named &lt;code&gt;hello.cgi&lt;/code&gt;. The file should include the following lines:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="c1"&gt;#!/home/blowmage/local/bin/ruby&lt;/span&gt;
&lt;span class="c1"&gt;# hello.cgi&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;content-type: text/html&amp;quot;&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&amp;lt;html&amp;gt;&amp;quot;&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&amp;lt;body&amp;gt;&amp;quot;&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&amp;lt;h1&amp;gt;Hello Ruby!&amp;lt;/h1&amp;gt;&amp;quot;&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&amp;lt;/body&amp;gt;&amp;quot;&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&amp;lt;/html&amp;gt;&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;The home directory for my account on HostingPlex is &lt;code&gt;/home/&lt;i&gt;blowmage&lt;/i&gt;&lt;/code&gt;. You'll want to change the first line of your script from &lt;code&gt;/home/&lt;i&gt;blowmage&lt;/i&gt;&lt;/code&gt; to the path to your account's home directory. If you do not, then the script won't know where to find Ruby and the script will fail. If you see a message that displays &lt;q&gt;Hello Ruby!&lt;/q&gt; then you have officially installed Ruby, congratulations.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blowmage/~4/EYcSJ-nHXGs" height="1" width="1"/&gt;</content><feedburner:origLink>http://blowmage.com/2005/05/28/installing-ruby</feedburner:origLink></entry></feed>

