<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/rss2full.xsl" type="text/xsl" media="screen"?><?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/itemcontent.css" type="text/css" media="screen"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Buci on Rails</title>
	
	<link>http://bucionrails.com</link>
	<description>Ruby, Rails, TDD, programming</description>
	<pubDate>Mon, 17 Nov 2008 20:00:20 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5</generator>
	<language>en</language>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/bucionrails" type="application/rss+xml" /><feedburner:feedFlare href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Ffeeds.feedburner.com%2Fbucionrails" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fbucionrails" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare href="http://feeds.my.aol.com/add.jsp?url=http%3A%2F%2Ffeeds.feedburner.com%2Fbucionrails" src="http://o.aolcdn.com/favorites.my.aol.com/webmaster/ffclient/webroot/locale/en-US/images/myAOLButtonSmall.gif">Subscribe with My AOL</feedburner:feedFlare><feedburner:feedFlare href="http://www.bloglines.com/sub/http://feeds.feedburner.com/bucionrails" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fbucionrails" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fbucionrails" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fbucionrails" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare><item>
		<title>Refuting Rails myths</title>
		<link>http://feeds.feedburner.com/~r/bucionrails/~3/456357916/</link>
		<comments>http://bucionrails.com/2008/11/17/refuting-rails-myths/#comments</comments>
		<pubDate>Mon, 17 Nov 2008 19:59:48 +0000</pubDate>
		<dc:creator>balint</dc:creator>
		
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://bucionrails.com/?p=24</guid>
		<description><![CDATA[David Heinemeier Hansson, the creator of Rails is doing an outstanding series of blog posts on his blog to derail (pun intended) some common myths that claim Rails does not do this or that and that hinders (or rather, slows down) its widespread acceptance.
I am sure David holds his best for last and will refute [...]]]></description>
			<content:encoded><![CDATA[<p>David Heinemeier Hansson, the creator of Rails is doing an <a href="http://loudthinking.com/posts/29-the-rails-myths">outstanding series of blog posts</a> on <a href="http://loudthinking.com/">his blog</a> to derail (pun intended) some common myths that claim Rails does not do this or that and that hinders (or rather, slows down) its widespread acceptance.</p>
<p>I am sure David holds his best for last and will refute the infamous &#8220;Rails does not scale&#8221; in the final episode of the series.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/bucionrails?a=tMm8N"><img src="http://feeds.feedburner.com/~f/bucionrails?i=tMm8N" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/bucionrails?a=w4aDn"><img src="http://feeds.feedburner.com/~f/bucionrails?i=w4aDn" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/bucionrails/~4/456357916" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://bucionrails.com/2008/11/17/refuting-rails-myths/feed/</wfw:commentRss>
		<feedburner:origLink>http://bucionrails.com/2008/11/17/refuting-rails-myths/</feedburner:origLink></item>
		<item>
		<title>ConferenciaRails 2008: enhorabuena!</title>
		<link>http://feeds.feedburner.com/~r/bucionrails/~3/456207337/</link>
		<comments>http://bucionrails.com/2008/11/17/conferenciarails-2008-enhorabuena/#comments</comments>
		<pubDate>Mon, 17 Nov 2008 17:20:51 +0000</pubDate>
		<dc:creator>balint</dc:creator>
		
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://bucionrails.com/?p=23</guid>
		<description><![CDATA[I have just returned from Madrid where the Spanish Rails Conference, Conferencia Rails was held. I liked it quite a lot, there were several interesting talks most of which made me want to learn all of that and very fast (one thing conferences do to me is to boost that healthy feeling of wanting to [...]]]></description>
			<content:encoded><![CDATA[<p>I have just returned from Madrid where the Spanish Rails Conference, <a href="http://www.conferenciarails.org/">Conferencia Rails</a> was held. I liked it quite a lot, there were several interesting talks most of which made me want to learn all of that and very fast (one thing conferences do to me is to boost that healthy feeling of wanting to always learn and discover new things). So I would like to add my e-voice to the web noise: congratulations and thank you to the organizers and presenters!</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/bucionrails?a=PHJbN"><img src="http://feeds.feedburner.com/~f/bucionrails?i=PHJbN" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/bucionrails?a=REWBn"><img src="http://feeds.feedburner.com/~f/bucionrails?i=REWBn" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/bucionrails/~4/456207337" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://bucionrails.com/2008/11/17/conferenciarails-2008-enhorabuena/feed/</wfw:commentRss>
		<feedburner:origLink>http://bucionrails.com/2008/11/17/conferenciarails-2008-enhorabuena/</feedburner:origLink></item>
		<item>
		<title>Blackbird - simple log messages in Javascript</title>
		<link>http://feeds.feedburner.com/~r/bucionrails/~3/434585915/</link>
		<comments>http://bucionrails.com/2008/10/26/blackbird-simple-log-messages-in-javascript/#comments</comments>
		<pubDate>Sun, 26 Oct 2008 15:42:27 +0000</pubDate>
		<dc:creator>balint</dc:creator>
		
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://bucionrails.com/?p=19</guid>
		<description><![CDATA[Using alert() for debugging javascript is a pain. Firebug makes it a lot easier and enables several debug facilities (e.g inserting breakpoints, stepping into methods, adding variable watches) but a painless logging mechanism would still be very useful to supplement Firebug&#8217;s features.
Enter Blackbird, a simple javascript logging tool which has a very clean, nice API [...]]]></description>
			<content:encoded><![CDATA[<p>Using alert() for debugging javascript is a pain. <a href="https://addons.mozilla.org/en-US/firefox/addon/1843" target="_blank">Firebug</a> makes it a lot easier and enables several debug facilities (e.g inserting breakpoints, stepping into methods, adding variable watches) but a painless logging mechanism would still be very useful to supplement Firebug&#8217;s features.</p>
<p>Enter <a title="Blackbird" href="http://bucionrails.com/http://www.gscottolson.com/blackbirdjs/" target="_blank">Blackbird</a>, a simple javascript logging tool which has a very clean, nice API and a cool console. It&#8217;s really worth to check out, you can download the Blackbird files <a href="http://blackbirdjs.googlecode.com/files/blackbirdjs-1.0.zip" target="_self">here</a> and my demo <a href="http://bucionrails.com/wp-content/uploads/2008/10/blackbird_trial.html">here</a> to try out its features. (If you use my demo, you have to save the Blackbird files in a directory named blackbirdjs that is situated in the same directory as the demo page)</p>
<p>Blackbird&#8217;s motto says it all: say &#8220;hello&#8221; to Blackbird and &#8220;goodbye&#8221; to alert().<a href="http://bucionrails.com/wp-content/uploads/2008/10/blackbird_trial.html"><br />
</a></p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/bucionrails?a=t1jEM"><img src="http://feeds.feedburner.com/~f/bucionrails?i=t1jEM" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/bucionrails?a=Tv5Dm"><img src="http://feeds.feedburner.com/~f/bucionrails?i=Tv5Dm" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/bucionrails/~4/434585915" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://bucionrails.com/2008/10/26/blackbird-simple-log-messages-in-javascript/feed/</wfw:commentRss>
		<feedburner:origLink>http://bucionrails.com/2008/10/26/blackbird-simple-log-messages-in-javascript/</feedburner:origLink></item>
		<item>
		<title>PostgreSQL pg_hba.conf authentication</title>
		<link>http://feeds.feedburner.com/~r/bucionrails/~3/428474196/</link>
		<comments>http://bucionrails.com/2008/10/22/postgresql-pg_hbaconf-authentication/#comments</comments>
		<pubDate>Wed, 22 Oct 2008 11:47:49 +0000</pubDate>
		<dc:creator>balint</dc:creator>
		
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://bucionrails.com/?p=13</guid>
		<description><![CDATA[I recently spent some time debugging while I can&#8217;t connect to a local postgreSQL database. I wanted the nice_db database to be accessible to all local users (not real names) without any authentication. The &#8220;trust&#8221; authentication method was what I needed for this scenario, I was sure of this much. So I set up an [...]]]></description>
			<content:encoded><![CDATA[<p>I recently spent some time debugging while I can&#8217;t connect to a local postgreSQL database. I wanted the nice_db database to be accessible to all local users (not real names) without any authentication. The &#8220;trust&#8221; authentication method was what I needed for this scenario, I was sure of this much. So I set up an authentication record in the configuration file below the one that existed by default:</p>

<div class="wp_syntax"><div class="code"><pre class="sql"><span style="color: #808080; font-style: italic;"># TYPE  DATABASE    USER    CIDR-ADDRESS    METHOD</span>
<span style="color: #993333; font-weight: bold;">LOCAL</span>    <span style="color: #993333; font-weight: bold;">ALL</span>          <span style="color: #993333; font-weight: bold;">ALL</span>                   ident sameuser
<span style="color: #993333; font-weight: bold;">LOCAL</span>    nice_db      <span style="color: #993333; font-weight: bold;">ALL</span>                   trust</pre></div></div>

<p>But this gave me the following error and denied access:</p>
<p>psql: FATAL:  Ident authentication failed for user &#8220;balint&#8221;</p>
<p>I tried several things making the second record more allowing each time (in fact, what you see above is the final, most liberal version) to no avail. I then swapped the order of the two records and finally was granted access.</p>
<p>Of course, I should have been wiser and apply the grand old <acronym title="Read The Fucking Manual">RTFM</acronym> principle. The <a title="PostgreSQL documentation" href="http://www.postgresql.org/docs/7.4/static/client-authentication.html" target="_blank">PostgreSQL documentation</a> states in very clear terms how each line in the pg_hba.conf is accessed:</p>
<blockquote><p>The first record with a matching connection type, client address, requested database, and user name is used to perform authentication. There is no <span class="QUOTE">&#8220;fall-through&#8221;</span> or    <span class="QUOTE">&#8220;backup&#8221;</span>: if one record is chosen and the authentication fails, subsequent records are not considered. If no record matches, access is denied.</p></blockquote>
<p>For my particular case, the &#8220;local all all ident sameuser&#8221; record blocked access to all databases but to those whose name matched that of the operating system&#8217;s user (that&#8217;s what the ident sameuser does) since that matches all user and database names.</p>
<p>Beyond the mechanics of PostgreSQL authentication (put the authentication records that match more users/databases below the ones that are more specific), I have learned something which is more precious and that I can put into good use in the future: RTFM!</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/bucionrails?a=1IYyM"><img src="http://feeds.feedburner.com/~f/bucionrails?i=1IYyM" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/bucionrails?a=kyktm"><img src="http://feeds.feedburner.com/~f/bucionrails?i=kyktm" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/bucionrails/~4/428474196" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://bucionrails.com/2008/10/22/postgresql-pg_hbaconf-authentication/feed/</wfw:commentRss>
		<feedburner:origLink>http://bucionrails.com/2008/10/22/postgresql-pg_hbaconf-authentication/</feedburner:origLink></item>
		<item>
		<title>javascript method chain</title>
		<link>http://feeds.feedburner.com/~r/bucionrails/~3/415929735/</link>
		<comments>http://bucionrails.com/2008/10/09/javascript-method-chain/#comments</comments>
		<pubDate>Thu, 09 Oct 2008 16:41:45 +0000</pubDate>
		<dc:creator>balint</dc:creator>
		
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://bucionrails.com/?p=17</guid>
		<description><![CDATA[John Resig has an extraordinary advanced javascript tutorial on his blog that he presented on a web conference. It is definitely worth a walk-through since it expands one&#8217;s javascript horizon unless one has not written a javascript framework himself. 
I played around with several of his slides learning a lot. My favorite was probably the [...]]]></description>
			<content:encoded><![CDATA[<p>John Resig has an extraordinary advanced javascript tutorial on his <a href="http://ejohn.org/apps/learn/" target="_blank">blog</a> that he presented on <a href="http://en.oreilly.com/webexny2008/public/content/home" target="_blank">a web conference</a>. It is definitely worth a walk-through since it expands one&#8217;s javascript horizon unless one has not written a javascript framework himself. </p>
<p>I played around with several of his slides learning a lot. My favorite was probably <a href="http://ejohn.org/apps/learn/#90">the last slide</a> which explains how method overloading works using the fact that <em>methodname</em>.length in javascript gives back the number of expected arguments of that function.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript"><span style="color: #003366; font-weight: bold;">function</span> addMethod<span style="color: #66cc66;">&#40;</span>object, <span style="color: #000066;">name</span>, fn<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span> 
  <span style="color: #009900; font-style: italic;">// Save a reference to the old method </span>
  <span style="color: #003366; font-weight: bold;">var</span> old = object<span style="color: #66cc66;">&#91;</span> <span style="color: #000066;">name</span> <span style="color: #66cc66;">&#93;</span>;
&nbsp;
  <span style="color: #009900; font-style: italic;">// Overwrite the method with our new one </span>
  object<span style="color: #66cc66;">&#91;</span> <span style="color: #000066;">name</span> <span style="color: #66cc66;">&#93;</span> = <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span> 
    <span style="color: #009900; font-style: italic;">// Check the number of incoming arguments, </span>
    <span style="color: #009900; font-style: italic;">// compared to our overloaded function </span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #66cc66;">&#40;</span> fn.<span style="color: #006600;">length</span> == arguments.<span style="color: #006600;">length</span> <span style="color: #66cc66;">&#41;</span> 
      <span style="color: #009900; font-style: italic;">// If there was a match, run the function </span>
      <span style="color: #000066; font-weight: bold;">return</span> fn.<span style="color: #006600;">apply</span><span style="color: #66cc66;">&#40;</span> <span style="color: #000066; font-weight: bold;">this</span>, arguments <span style="color: #66cc66;">&#41;</span>; 
&nbsp;
    <span style="color: #009900; font-style: italic;">// Otherwise, fallback to the old method </span>
    <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #66cc66;">&#40;</span> <span style="color: #000066; font-weight: bold;">typeof</span> old === <span style="color: #3366CC;">&quot;function&quot;</span> <span style="color: #66cc66;">&#41;</span> 
      <span style="color: #000066; font-weight: bold;">return</span> old.<span style="color: #006600;">apply</span><span style="color: #66cc66;">&#40;</span> <span style="color: #000066; font-weight: bold;">this</span>, arguments <span style="color: #66cc66;">&#41;</span>; 
  <span style="color: #66cc66;">&#125;</span>; 
<span style="color: #66cc66;">&#125;</span> 
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> Ninjas<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span> 
  <span style="color: #003366; font-weight: bold;">var</span> ninjas = <span style="color: #66cc66;">&#91;</span> <span style="color: #3366CC;">&quot;Dean Edwards&quot;</span>, <span style="color: #3366CC;">&quot;Sam Stephenson&quot;</span>, <span style="color: #3366CC;">&quot;Alex Russell&quot;</span> <span style="color: #66cc66;">&#93;</span>; 
  addMethod<span style="color: #66cc66;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>, <span style="color: #3366CC;">&quot;find&quot;</span>, <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span> 
    <span style="color: #000066; font-weight: bold;">return</span> ninjas; 
  <span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>; 
  addMethod<span style="color: #66cc66;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>, <span style="color: #3366CC;">&quot;find&quot;</span>, <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #000066;">name</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span> 
    <span style="color: #003366; font-weight: bold;">var</span> ret = <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#93;</span>; 
    <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #66cc66;">&#40;</span> <span style="color: #003366; font-weight: bold;">var</span> i = <span style="color: #CC0000;">0</span>; i <span style="color: #66cc66;">&lt;</span> ninjas.<span style="color: #006600;">length</span>; i++ <span style="color: #66cc66;">&#41;</span> 
      <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #66cc66;">&#40;</span> ninjas<span style="color: #66cc66;">&#91;</span>i<span style="color: #66cc66;">&#93;</span>.<span style="color: #006600;">indexOf</span><span style="color: #66cc66;">&#40;</span><span style="color: #000066;">name</span><span style="color: #66cc66;">&#41;</span> == <span style="color: #CC0000;">0</span> <span style="color: #66cc66;">&#41;</span> 
        ret.<span style="color: #006600;">push</span><span style="color: #66cc66;">&#40;</span> ninjas<span style="color: #66cc66;">&#91;</span>i<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#41;</span>; 
    <span style="color: #000066; font-weight: bold;">return</span> ret; 
  <span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>; 
  addMethod<span style="color: #66cc66;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>, <span style="color: #3366CC;">&quot;find&quot;</span>, <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>first, last<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span> 
    <span style="color: #003366; font-weight: bold;">var</span> ret = <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#93;</span>; 
    <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #66cc66;">&#40;</span> <span style="color: #003366; font-weight: bold;">var</span> i = <span style="color: #CC0000;">0</span>; i <span style="color: #66cc66;">&lt;</span> ninjas.<span style="color: #006600;">length</span>; i++ <span style="color: #66cc66;">&#41;</span> 
      <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #66cc66;">&#40;</span> ninjas<span style="color: #66cc66;">&#91;</span>i<span style="color: #66cc66;">&#93;</span> == <span style="color: #66cc66;">&#40;</span>first + <span style="color: #3366CC;">&quot; &quot;</span> + last<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#41;</span> 
        ret.<span style="color: #006600;">push</span><span style="color: #66cc66;">&#40;</span> ninjas<span style="color: #66cc66;">&#91;</span>i<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#41;</span>; 
    <span style="color: #000066; font-weight: bold;">return</span> ret; 
  <span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>; 
<span style="color: #66cc66;">&#125;</span> 
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> ninjas = <span style="color: #003366; font-weight: bold;">new</span> Ninjas<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>; 
assert<span style="color: #66cc66;">&#40;</span> ninjas.<span style="color: #006600;">find</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">length</span> == <span style="color: #CC0000;">3</span>, <span style="color: #3366CC;">&quot;Finds all ninjas&quot;</span> <span style="color: #66cc66;">&#41;</span>; 
assert<span style="color: #66cc66;">&#40;</span> ninjas.<span style="color: #006600;">find</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">&quot;Sam&quot;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">length</span> == <span style="color: #CC0000;">1</span>, <span style="color: #3366CC;">&quot;Finds ninjas by first name&quot;</span> <span style="color: #66cc66;">&#41;</span>; 
assert<span style="color: #66cc66;">&#40;</span> ninjas.<span style="color: #006600;">find</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">&quot;Dean&quot;</span>, <span style="color: #3366CC;">&quot;Edwards&quot;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">length</span> == <span style="color: #CC0000;">1</span>, <span style="color: #3366CC;">&quot;Finds ninjas by first and last name&quot;</span> <span style="color: #66cc66;">&#41;</span>; 
assert<span style="color: #66cc66;">&#40;</span> ninjas.<span style="color: #006600;">find</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">&quot;Alex&quot;</span>, <span style="color: #3366CC;">&quot;X&quot;</span>, <span style="color: #3366CC;">&quot;Russell&quot;</span><span style="color: #66cc66;">&#41;</span> == <span style="color: #003366; font-weight: bold;">null</span>, <span style="color: #3366CC;">&quot;Does nothing&quot;</span> <span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<p>It took me some time to figure out how exactly the method calls are routed but it was an interesting process nevertheless. I guess the one tricky part to interpret is the following bit:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript"><span style="color: #000066; font-weight: bold;">if</span> <span style="color: #66cc66;">&#40;</span> fn.<span style="color: #006600;">length</span> == arguments.<span style="color: #006600;">length</span> <span style="color: #66cc66;">&#41;</span> 
  <span style="color: #009900; font-style: italic;">// If there was a match, run the function </span>
  <span style="color: #000066; font-weight: bold;">return</span> fn.<span style="color: #006600;">apply</span><span style="color: #66cc66;">&#40;</span> <span style="color: #000066; font-weight: bold;">this</span>, arguments <span style="color: #66cc66;">&#41;</span>; 
&nbsp;
  <span style="color: #009900; font-style: italic;">// Otherwise, fallback to the old method </span>
  <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #66cc66;">&#40;</span> <span style="color: #000066; font-weight: bold;">typeof</span> old === <span style="color: #3366CC;">&quot;function&quot;</span> <span style="color: #66cc66;">&#41;</span> 
    <span style="color: #000066; font-weight: bold;">return</span> old.<span style="color: #006600;">apply</span><span style="color: #66cc66;">&#40;</span> <span style="color: #000066; font-weight: bold;">this</span>, arguments <span style="color: #66cc66;">&#41;</span>; 
  <span style="color: #66cc66;">&#125;</span>;</pre></div></div>

<p>This makes a method chain and allows for method overloading. With the three addMethod calls in the above example a chained method is built up. </p>
<p>After the call to addMethod with no arguments (the first one), the find method of the Ninjas &#8220;class&#8221; will return all ninjas if called with no arguments and do nothing if called with any number of arguments. After the call to addMethod with one single name argument the find method will return the ninjas whose first name matches the passed argument if there is only one argument, return all ninjas if it has been called with no arguments and do nothing otherwise. </p>
<p>I could go on but the pattern is probably clear now. At each call of the find method, the lastly added method is matched for the number of arguments (so in the above example, it will match if the caller passed two arguments) and the method called if the match is successful. Otherwise, it will try to match the number of arguments with the method that was added before the last one, and so on.</p>
<p>I am elaborating this in so much detail because </p>
<ol>
<li>it was such a &#8220;Eureka!&#8221; moment for me when I got it. </li>
<li>it is an incredibly ingenious way to flex the possibilites of javascript and introduce an OOP concept into an originally non-OOP language.</li>
</ol>
<p>I think John Resig made javascript lovable again which is why he deserves my total gratitude.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/bucionrails?a=r71lM"><img src="http://feeds.feedburner.com/~f/bucionrails?i=r71lM" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/bucionrails?a=bu9Rm"><img src="http://feeds.feedburner.com/~f/bucionrails?i=bu9Rm" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/bucionrails/~4/415929735" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://bucionrails.com/2008/10/09/javascript-method-chain/feed/</wfw:commentRss>
		<feedburner:origLink>http://bucionrails.com/2008/10/09/javascript-method-chain/</feedburner:origLink></item>
		<item>
		<title>My first DSL in Ruby</title>
		<link>http://feeds.feedburner.com/~r/bucionrails/~3/398877079/</link>
		<comments>http://bucionrails.com/2008/09/21/my-first-dsl-in-ruby/#comments</comments>
		<pubDate>Sun, 21 Sep 2008 12:00:20 +0000</pubDate>
		<dc:creator>balint</dc:creator>
		
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://bucionrails.com/?p=16</guid>
		<description><![CDATA[I read a few posts about how good fit Ruby is for building DSLs, Domain Specific Languages. Ever the curious I have been waiting for the opportunity to build a very simple one for a particular problem.
Well, I did not have to wait very long (when you have a hammer everything looks like a nail). [...]]]></description>
			<content:encoded><![CDATA[<p>I read a <a href="http://www.artima.com/rubycs/articles/ruby_as_dsl.html">few</a> <a href="http://www.artima.com/rubycs/articles/ruby_as_dsl.html">posts</a> about how good fit Ruby is for building DSLs, Domain Specific Languages. Ever the curious I have been waiting for the opportunity to build a very simple one for a particular problem.</p>
<p>Well, I did not have to wait very long (when you have a hammer everything looks like a nail). I needed a quick method which generates nice html graphs for <a href="http://bucionrails.com/2008/09/17/v8-javascript-engine-benchmarks/">my post about browser javascript engine benchmarking</a>. After spending a few minutes searching for a free tool (I did not want anything fluffy, just something very basic) I hit the nail in the head with my hammer. Only the nail was the generated HTML charts for my post and the hammer, (my desire to build) a DSL in Ruby.</p>
<p>I would like to say it was difficult but in fact it was a piece of cake with Ruby (and armed with the knowledge of previous DSL builders). The solution is composed of the following three parts:</p>
<ol>
<li>The DSL file which defines the charts</li>
<li>The interpreter which understands the definitions in the DSL file</li>
<li>The &#8220;controller&#8221; which just passes the data contained in the DSL file to the interpreter</li>
</ol>
<p>So let&#8217;s see each part separately:</p>
<p><strong>browser_js_benchmarks.dsl (the DSL)</strong></p>

<div class="wp_syntax"><div class="code"><pre class="ruby">chart <span style="color:#996600;">&quot;Score&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>c<span style="color:#006600; font-weight:bold;">|</span>
	c.<span style="color:#9900CC;">add</span> <span style="color:#996600;">&quot;Safari 3.1.2&quot;</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">164</span>
	c.<span style="color:#9900CC;">add</span> <span style="color:#996600;">&quot;Firefox 3.0.1&quot;</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">156</span>
	c.<span style="color:#9900CC;">add</span> <span style="color:#996600;">&quot;Shiretoko&quot;</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">145</span>
	c.<span style="color:#9900CC;">add</span> <span style="color:#996600;">&quot;Google Chrome&quot;</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">1589</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p><strong>chart.rb (the interpreter)</strong></p>

<div class="wp_syntax"><div class="code"><pre class="ruby"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">&quot;math_aux&quot;</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> ChartDSL
&nbsp;
	Template = <span style="color:#006600; font-weight:bold;">%</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&lt;</span>table border=<span style="color:#996600;">&quot;0&quot;</span> cellspacing=<span style="color:#996600;">&quot;5&quot;</span> cellpadding=<span style="color:#996600;">&quot;5&quot;</span><span style="color:#006600; font-weight:bold;">&gt;&lt;</span>caption<span style="color:#006600; font-weight:bold;">&gt;%%</span>CAPTION<span style="color:#006600; font-weight:bold;">%%&lt;/</span>caption<span style="color:#006600; font-weight:bold;">&gt;%%</span>ITEMS<span style="color:#006600; font-weight:bold;">%%&lt;/</span>table<span style="color:#006600; font-weight:bold;">&gt;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
	Background_colors = <span style="color:#006600; font-weight:bold;">%</span>w<span style="color:#006600; font-weight:bold;">&#40;</span>red blue green yellow grey<span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
	attr_reader <span style="color:#ff3333; font-weight:bold;">:values</span>
	<span style="color:#9966CC; font-weight:bold;">def</span> initialize
		<span style="color:#0066ff; font-weight:bold;">@charts</span> = <span style="color:#CC0066; font-weight:bold;">Array</span>.<span style="color:#9900CC;">new</span>
		<span style="color:#0066ff; font-weight:bold;">@values</span> = <span style="color:#CC00FF; font-weight:bold;">Hash</span>.<span style="color:#9900CC;">new</span>
	<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
	<span style="color:#9966CC; font-weight:bold;">def</span> chart<span style="color:#006600; font-weight:bold;">&#40;</span>name<span style="color:#006600; font-weight:bold;">&#41;</span>		
		<span style="color:#0066ff; font-weight:bold;">@name</span> = name
		<span style="color:#9966CC; font-weight:bold;">yield</span> <span style="color:#0000FF; font-weight:bold;">self</span>
		<span style="color:#0066ff; font-weight:bold;">@charts</span>.<span style="color:#9900CC;">push</span><span style="color:#006600; font-weight:bold;">&#40;</span>make_html<span style="color:#006600; font-weight:bold;">&#41;</span>
	<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
	<span style="color:#9966CC; font-weight:bold;">def</span> add<span style="color:#006600; font-weight:bold;">&#40;</span>name_and_value<span style="color:#006600; font-weight:bold;">&#41;</span>
		<span style="color:#0066ff; font-weight:bold;">@values</span> <span style="color:#006600; font-weight:bold;">||</span>= <span style="color:#CC00FF; font-weight:bold;">Hash</span>.<span style="color:#9900CC;">new</span>
 		<span style="color:#0066ff; font-weight:bold;">@values</span>.<span style="color:#9900CC;">merge</span>!<span style="color:#006600; font-weight:bold;">&#40;</span>name_and_value<span style="color:#006600; font-weight:bold;">&#41;</span>
	<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
	<span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#CC0066; font-weight:bold;">load</span><span style="color:#006600; font-weight:bold;">&#40;</span>filename<span style="color:#006600; font-weight:bold;">&#41;</span>
		<span style="color:#008000; font-style:italic;"># c = new</span>
		instance_eval<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">read</span><span style="color:#006600; font-weight:bold;">&#40;</span>filename<span style="color:#006600; font-weight:bold;">&#41;</span>, filename<span style="color:#006600; font-weight:bold;">&#41;</span>
		write_output
	<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
	<span style="color:#9966CC; font-weight:bold;">def</span> make_html
		sorted_pairs = <span style="color:#0066ff; font-weight:bold;">@values</span>.<span style="color:#9900CC;">sort_by</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>v<span style="color:#006600; font-weight:bold;">|</span> <span style="color:#006600; font-weight:bold;">-</span> v<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
		vals = sorted_pairs.<span style="color:#9900CC;">map</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>p<span style="color:#006600; font-weight:bold;">|</span> <span style="color:#CC0066; font-weight:bold;">p</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
		norm_values = MathAux::normalize<span style="color:#006600; font-weight:bold;">&#40;</span>vals, <span style="color:#006666;">100.0</span><span style="color:#006600; font-weight:bold;">&#41;</span>
		html = <span style="color:#CC0066; font-weight:bold;">Array</span>.<span style="color:#9900CC;">new</span>
		sorted_pairs.<span style="color:#9900CC;">each_with_index</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>pair, i<span style="color:#006600; font-weight:bold;">|</span>
			name, value = pair
			html.<span style="color:#9900CC;">push</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">%</span>Q<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&lt;</span>tr<span style="color:#006600; font-weight:bold;">&gt;&lt;</span>td<span style="color:#006600; font-weight:bold;">&gt;</span><span style="color:#008000; font-style:italic;">#{name}&lt;/td&gt;&lt;td&gt;&lt;div style=&quot;width:#{norm_values[i]}px;background-color:#{ChartDSL::Background_colors[i]}&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td&gt;#{value}&lt;/td&gt;&lt;/tr&gt;))</span>
		<span style="color:#9966CC; font-weight:bold;">end</span>
		filled_chart = <span style="color:#6666ff; font-weight:bold;">ChartDSL::Template</span>.<span style="color:#CC0066; font-weight:bold;">sub</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;%%CAPTION%%&quot;</span>, <span style="color:#0066ff; font-weight:bold;">@name</span><span style="color:#006600; font-weight:bold;">&#41;</span>		
		filled_chart.<span style="color:#CC0066; font-weight:bold;">sub</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;%%ITEMS%%&quot;</span>, html.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#41;</span>
	<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
	<span style="color:#9966CC; font-weight:bold;">def</span> write_output
		<span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#CC0066; font-weight:bold;">open</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;generated_charts.html&quot;</span>, <span style="color:#996600;">&quot;w&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>f<span style="color:#006600; font-weight:bold;">|</span>
			f.<span style="color:#9900CC;">write</span><span style="color:#006600; font-weight:bold;">&#40;</span>@charts<span style="color:#006600; font-weight:bold;">&#41;</span>
		<span style="color:#9966CC; font-weight:bold;">end</span>
	<span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p><strong>chart_loader.rb (the controller)</strong></p>

<div class="wp_syntax"><div class="code"><pre class="ruby"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">&quot;chart&quot;</span>
<span style="color:#9966CC; font-weight:bold;">class</span> ChartLoader
	<span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">load_chart</span><span style="color:#006600; font-weight:bold;">&#40;</span>dsl_filename<span style="color:#006600; font-weight:bold;">&#41;</span>
		c = ChartDSL.<span style="color:#9900CC;">new</span>
		c.<span style="color:#CC0066; font-weight:bold;">load</span><span style="color:#006600; font-weight:bold;">&#40;</span>dsl_filename<span style="color:#006600; font-weight:bold;">&#41;</span>
	<span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#0000FF; font-weight:bold;">__FILE__</span> == $<span style="color:#006666;">0</span>
	ChartLoader.<span style="color:#9900CC;">load_chart</span><span style="color:#006600; font-weight:bold;">&#40;</span>ARGV<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>For the sake of completeness here is <strong>math_aux.rb</strong>:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby"><span style="color:#9966CC; font-weight:bold;">module</span> MathAux
	<span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">normalize</span><span style="color:#006600; font-weight:bold;">&#40;</span>numbers, to=<span style="color:#006666;">1.0</span><span style="color:#006600; font-weight:bold;">&#41;</span>
		norm_rat = to <span style="color:#006600; font-weight:bold;">/</span> numbers.<span style="color:#9900CC;">max</span>
		numbers.<span style="color:#9900CC;">map</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>n<span style="color:#006600; font-weight:bold;">|</span> n <span style="color:#006600; font-weight:bold;">*</span> norm_rat <span style="color:#006600; font-weight:bold;">&#125;</span>
	<span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>To generate the charts, one only has to run &#8220;the interpreter&#8221; with a dsl file as the first parameter:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby">ruby chart_loader.<span style="color:#9900CC;">rb</span> browser_js_benchmarks.<span style="color:#9900CC;">dsl</span></pre></div></div>

<p>The output is called generated_charts.html and contains the following:</p>

<div class="wp_syntax"><div class="code"><pre class="xml"><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;table</span> <span style="color: #000066;">border</span>=<span style="color: #ff0000;">&quot;0&quot;</span> <span style="color: #000066;">cellspacing</span>=<span style="color: #ff0000;">&quot;5&quot;</span> <span style="color: #000066;">cellpadding</span>=<span style="color: #ff0000;">&quot;5&quot;</span><span style="font-weight: bold; color: black;">&gt;</span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;caption<span style="font-weight: bold; color: black;">&gt;</span></span></span>Score<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/caption<span style="font-weight: bold; color: black;">&gt;</span></span></span>
 <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;tr<span style="font-weight: bold; color: black;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;td<span style="font-weight: bold; color: black;">&gt;</span></span></span>Google Chrome<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/td<span style="font-weight: bold; color: black;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;td<span style="font-weight: bold; color: black;">&gt;</span></span></span><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;div</span> <span style="color: #000066;">style</span>=<span style="color: #ff0000;">&quot;width:100.0px;background-color:red&quot;</span><span style="font-weight: bold; color: black;">&gt;</span></span><span style="color: #ddbb00;">&amp;nbsp;</span><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/div<span style="font-weight: bold; color: black;">&gt;</span></span></span><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/td<span style="font-weight: bold; color: black;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;td<span style="font-weight: bold; color: black;">&gt;</span></span></span>1589<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/td<span style="font-weight: bold; color: black;">&gt;</span></span></span>
 <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/tr<span style="font-weight: bold; color: black;">&gt;</span></span></span>
 <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;tr<span style="font-weight: bold; color: black;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;td<span style="font-weight: bold; color: black;">&gt;</span></span></span>Safari 3.1.2<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/td<span style="font-weight: bold; color: black;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;td<span style="font-weight: bold; color: black;">&gt;</span></span></span><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;div</span> <span style="color: #000066;">style</span>=<span style="color: #ff0000;">&quot;width:10.3209565764632px;background-color:blue&quot;</span><span style="font-weight: bold; color: black;">&gt;</span></span><span style="color: #ddbb00;">&amp;nbsp;</span><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/div</span><span style="font-weight: bold; color: black;">&lt;/td<span style="font-weight: bold; color: black;">&gt;</span></span></span>  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;td<span style="font-weight: bold; color: black;">&gt;</span></span></span>164<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/td<span style="font-weight: bold; color: black;">&gt;</span></span></span><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/tr<span style="font-weight: bold; color: black;">&gt;</span></span></span>
 <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;tr<span style="font-weight: bold; color: black;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;td<span style="font-weight: bold; color: black;">&gt;</span></span></span>Firefox 3.0.1<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/td<span style="font-weight: bold; color: black;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;td<span style="font-weight: bold; color: black;">&gt;</span></span></span><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;div</span> <span style="color: #000066;">style</span>=<span style="color: #ff0000;">&quot;width:9.81749528005034px;background-color:green&quot;</span><span style="font-weight: bold; color: black;">&gt;</span></span><span style="color: #ddbb00;">&amp;nbsp;</span><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/div</span><span style="font-weight: bold; color: black;">&lt;/td<span style="font-weight: bold; color: black;">&gt;</span></span></span> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;td<span style="font-weight: bold; color: black;">&gt;</span></span></span>156<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/td<span style="font-weight: bold; color: black;">&gt;</span></span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/tr<span style="font-weight: bold; color: black;">&gt;</span></span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;tr<span style="font-weight: bold; color: black;">&gt;</span></span></span>
 <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;td<span style="font-weight: bold; color: black;">&gt;</span></span></span>Shiretoko<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/td<span style="font-weight: bold; color: black;">&gt;</span></span></span>
 <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;td<span style="font-weight: bold; color: black;">&gt;</span></span></span><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;div</span> <span style="color: #000066;">style</span>=<span style="color: #ff0000;">&quot;width:9.12523599748269px;background-color:yellow&quot;</span><span style="font-weight: bold; color: black;">&gt;</span></span><span style="color: #ddbb00;">&amp;nbsp;</span><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/div</span><span style="font-weight: bold; color: black;">&lt;/td<span style="font-weight: bold; color: black;">&gt;</span></span></span><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;td<span style="font-weight: bold; color: black;">&gt;</span></span></span>145<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/td<span style="font-weight: bold; color: black;">&gt;</span></span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/tr<span style="font-weight: bold; color: black;">&gt;</span></span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/table<span style="font-weight: bold; color: black;">&gt;</span></span></span></pre></div></div>

<p>Note that in ~30-40 code lines we have a &#8220;language interpreter&#8221;, one that understands the chart DSL and spits out some HTML code that represents the charts. Of course there is plenty of room for improvement, like having the same color denote the same actor between charts (Firefox 3.0.1 should always be the blue bar, for example, unlike in <a href="http://bucionrails.com/2008/09/17/v8-javascript-engine-benchmarks/">my post</a>), using a better solution for the template strings, adding the possibility of pie charts (although &#8220;standard&#8221; HTML is not very flexible on different chart forms, one would probably have to use a <a href="http://developer.mozilla.org/en/Canvas_tutorial">&lt;canvas&gt; </a>), and so on.</p>
<p>The essential thing is that it works and it does what the particular situation demanded. It took me a couple of interrupted hours plus the time to read through two related posts which is not that much given that I now have a &#8220;tool&#8221; (once again, I feel a bit conceited to call it that) which I can use for my future posts whenever the need arises. A custom hammer for my custom nail.</p>
<p>(If you care, feel free to download, use and modify the source code located <a href="http://github.com/balinterdi/chart-maker-dsl/tree/master">here</a>)</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/bucionrails?a=X1fPL"><img src="http://feeds.feedburner.com/~f/bucionrails?i=X1fPL" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/bucionrails?a=f09Sl"><img src="http://feeds.feedburner.com/~f/bucionrails?i=f09Sl" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/bucionrails/~4/398877079" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://bucionrails.com/2008/09/21/my-first-dsl-in-ruby/feed/</wfw:commentRss>
		<feedburner:origLink>http://bucionrails.com/2008/09/21/my-first-dsl-in-ruby/</feedburner:origLink></item>
		<item>
		<title>V8 javascript engine benchmarks</title>
		<link>http://feeds.feedburner.com/~r/bucionrails/~3/394877332/</link>
		<comments>http://bucionrails.com/2008/09/17/v8-javascript-engine-benchmarks/#comments</comments>
		<pubDate>Wed, 17 Sep 2008 05:08:19 +0000</pubDate>
		<dc:creator>balint</dc:creator>
		
		<category><![CDATA[benchmarking]]></category>

		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://bucionrails.com/?p=15</guid>
		<description><![CDATA[A few weeks back when I read about Chrome I became interested in V8, a javascript engine that Google integrated in their browser and that they claimed to be very fast due to the following reasons:

Hidden class transitions that enable dynamic optimizations since objects will use the same (hidden) class
generating machine code instead of interpreting [...]]]></description>
			<content:encoded><![CDATA[<p>A few weeks back when I read about <a href="http://www.google.com/googlebooks/chrome">Chrome</a> I became interested in V8, a javascript engine that Google integrated in their browser and that they claimed to be very fast due to the following reasons:</p>
<ul>
<li><strong>Hidden class transitions</strong> that enable dynamic optimizations since objects will use the same (hidden) class</li>
<li><strong>generating machine code</strong> instead of interpreting the source code each time</li>
<li><strong>incremental garbage collection</strong> which reduces the time needed for the cleanup to milliseconds and eliminates &#8220;second long pauses&#8221;</li>
</ul>
<p>All that sounded very promising but as an engineer by profession it left me with a desire to find out how much faster all these features made V8 (and any browser that might use it). Even more so since I love running benchmarks and compare numbers. Well, maybe Google sensed that since they provided all the necessary tools to run these tests on the <a href="http://code.google.com/apis/v8/benchmarks.html">V8 benchmark page</a> and to run them very easily. </p>
<p>There are 5 different algorithms in the testing suite exercising different qualities of the javascript engine. To be fair I closed all other tabs in browsers during the testing attempting to minimize operations that can have an effect on test performance. Also, the V8 tests were run from the command line so that might skew the results a bit towards V8. Anyyway, here are the results (numbers mean execution time so smaller is better):</p>
<table border="0" cellspacing="5" cellpadding="5">
<caption>Richards</caption>
<tr>
<td>Google Chrome</td>
<td>
<div style="width:100.0px;background-color:red">&nbsp;</div>
</td>
<td>2072</td>
</tr>
<tr>
<td>Firefox 3.0.1</td>
<td>
<div style="width:7.33590733590734px;background-color:blue">&nbsp;</div>
</td>
<td>152</td>
</tr>
<tr>
<td>Shiretoko</td>
<td>
<div style="width:5.5984555984556px;background-color:green">&nbsp;</div>
</td>
<td>116</td>
</tr>
<tr>
<td>Safari 3.1.2</td>
<td>
<div style="width:4.39189189189189px;background-color:yellow">&nbsp;</div>
</td>
<td>91</td>
</tr>
</table>
<table border="0" cellspacing="5" cellpadding="5">
<caption>DeltaBlue</caption>
<tr>
<td>Google Chrome</td>
<td>
<div style="width:100.0px;background-color:red">&nbsp;</div>
</td>
<td>1753</td>
</tr>
<tr>
<td>Firefox 3.0.1</td>
<td>
<div style="width:9.75470621791215px;background-color:blue">&nbsp;</div>
</td>
<td>171</td>
</tr>
<tr>
<td>Safari 3.1.2</td>
<td>
<div style="width:7.24472333143183px;background-color:green">&nbsp;</div>
</td>
<td>127</td>
</tr>
<tr>
<td>Shiretoko</td>
<td>
<div style="width:7.01654306902453px;background-color:yellow">&nbsp;</div>
</td>
<td>123</td>
</tr>
</table>
<table border="0" cellspacing="5" cellpadding="5">
<caption>Crypto</caption>
<tr>
<td>Google Chrome</td>
<td>
<div style="width:100.0px;background-color:red">&nbsp;</div>
</td>
<td>1415</td>
</tr>
<tr>
<td>Firefox 3.0.1</td>
<td>
<div style="width:10.6007067137809px;background-color:blue">&nbsp;</div>
</td>
<td>150</td>
</tr>
<tr>
<td>Shiretoko</td>
<td>
<div style="width:10.6007067137809px;background-color:green">&nbsp;</div>
</td>
<td>150</td>
</tr>
<tr>
<td>Safari 3.1.2</td>
<td>
<div style="width:9.54063604240283px;background-color:yellow">&nbsp;</div>
</td>
<td>135</td>
</tr>
</table>
<table border="0" cellspacing="5" cellpadding="5">
<caption>RayTrace</caption>
<tr>
<td>Google Chrome</td>
<td>
<div style="width:100.0px;background-color:red">&nbsp;</div>
</td>
<td>1021</td>
</tr>
<tr>
<td>Safari 3.1.2</td>
<td>
<div style="width:22.7228207639569px;background-color:blue">&nbsp;</div>
</td>
<td>232</td>
</tr>
<tr>
<td>Firefox 3.0.1</td>
<td>
<div style="width:12.3408423114594px;background-color:green">&nbsp;</div>
</td>
<td>126</td>
</tr>
<tr>
<td>Shiretoko</td>
<td>
<div style="width:11.1655239960823px;background-color:yellow">&nbsp;</div>
</td>
<td>114</td>
</tr>
</table>
<table border="0" cellspacing="5" cellpadding="5">
<caption>EarleyBoyer</caption>
<tr>
<td>Google Chrome</td>
<td>
<div style="width:100.0px;background-color:red">&nbsp;</div>
</td>
<td>1933</td>
</tr>
<tr>
<td>Safari 3.1.2</td>
<td>
<div style="width:16.9684428349715px;background-color:blue">&nbsp;</div>
</td>
<td>328</td>
</tr>
<tr>
<td>Shiretoko</td>
<td>
<div style="width:13.3988618727367px;background-color:green">&nbsp;</div>
</td>
<td>259</td>
</tr>
<tr>
<td>Firefox 3.0.1</td>
<td>
<div style="width:9.72581479565442px;background-color:yellow">&nbsp;</div>
</td>
<td>188</td>
</tr>
</table>
<table border="0" cellspacing="5" cellpadding="5">
<caption>Score</caption>
<tr>
<td>Google Chrome</td>
<td>
<div style="width:100.0px;background-color:red">&nbsp;</div>
</td>
<td>1589</td>
</tr>
<tr>
<td>Safari 3.1.2</td>
<td>
<div style="width:10.3209565764632px;background-color:blue">&nbsp;</div>
</td>
<td>164</td>
</tr>
<tr>
<td>Firefox 3.0.1</td>
<td>
<div style="width:9.81749528005034px;background-color:green">&nbsp;</div>
</td>
<td>156</td>
</tr>
<tr>
<td>Shiretoko</td>
<td>
<div style="width:9.12523599748269px;background-color:yellow">&nbsp;</div>
</td>
<td>145</td>
</tr>
</table>
<p>The superiority of V8 stunned me so much even to push me to ask whether all this is possible. Googe Chrome that uses V8 is on average (see Score) 10 times faster than all the other browsers (that pretty much flock together). I expected to find the speed of Firefox 3.1 (codename Shiretoko) close to that of Chrome but to my surprise it does not even surpass that of the other browsers. That made me a bit disappointed since I am a big Firefox fan. </p>
<p>Can it be that these benchmarks are somehow tailored to show V8&#8217;s dominance? (like some political polls are skewed to give the &#8220;correct&#8221; answer). That this is not such a far-fetched idea is supported by Mozilla&#8217;s announcement that TraceMonkey, <a href="http://www.techcrunch.com/2008/09/03/mozilla-fights-back-with-new-firefox-benchmarks/">Firefox&#8217;s javascript engine will be 16-28% faster than V8</a>. And they have their own benchmarking solution, SunSpider to prove their point.</p>
<p>So the life of javascript engine developers has got a lot harder. Not only they have to implement a fast engine but also a benchmarking system that shows there is nothing as fast as theirs!</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/bucionrails?a=WyrNL"><img src="http://feeds.feedburner.com/~f/bucionrails?i=WyrNL" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/bucionrails?a=w6ycl"><img src="http://feeds.feedburner.com/~f/bucionrails?i=w6ycl" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/bucionrails/~4/394877332" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://bucionrails.com/2008/09/17/v8-javascript-engine-benchmarks/feed/</wfw:commentRss>
		<feedburner:origLink>http://bucionrails.com/2008/09/17/v8-javascript-engine-benchmarks/</feedburner:origLink></item>
		<item>
		<title>Navigator for the Google Chrome comicbook</title>
		<link>http://feeds.feedburner.com/~r/bucionrails/~3/393218616/</link>
		<comments>http://bucionrails.com/2008/09/03/navigator-for-the-google-chrome-comicbook/#comments</comments>
		<pubDate>Wed, 03 Sep 2008 19:28:22 +0000</pubDate>
		<dc:creator>balint</dc:creator>
		
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://bucionrails.com/?p=12</guid>
		<description><![CDATA[The first beta version (for now only for Windows) of Google&#8217;s browser is out, but I don&#8217;t think Google needs the marketing power of my post so that&#8217;s not what I want to talk about. The browser is introduced by a ingenious comics of 39 pages. However, the navigator is too simple, in my opinion [...]]]></description>
			<content:encoded><![CDATA[<p>The first beta version (for now only for Windows) of <a href="http://googleblog.blogspot.com/2008/09/fresh-take-on-browser.html">Google&#8217;s browser is out, </a>but I don&#8217;t think Google needs the marketing power of my post so that&#8217;s not what I want to talk about. The browser is introduced by a <a href="http://www.google.com/googlebooks/chrome/">ingenious comics</a> of 39 pages. However, the navigator is too simple, in my opinion in that you cannot skip a page so if you read until say page 19 and you have to start over (e.g you closed the browser), you have to click on the &#8220;Next&#8221; link 18 times. There is no unique URL for each page, the whole navigation is done with a javascript snippet changing the image (the cartoon strip) when the user clicks &#8220;Prev&#8221; or &#8220;Next&#8221;.</p>
<p>So I took a peep at the source of the page and reverse-engineered the navigation which is simply a javascript call to goPage(&#8217;next&#8217;) when the user clicks the Next link. So now I can simply write</p>

<div class="wp_syntax"><div class="code"><pre class="javascript">javascript:<span style="color: #000066; font-weight: bold;">for</span> <span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i=<span style="color: #CC0000;">0</span>; i <span style="color: #66cc66;">&lt;</span> <span style="color: #CC0000;">10</span>; i++<span style="color: #66cc66;">&#41;</span> goPage<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'next'</span><span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<p>to the location bar to skip 10 pages ahead and do the same with &#8216;prev&#8217; to rewind 10 pages.</p>
<p>I know &#8220;reverse-engineering&#8221; is way too conceited a term for this but this kind of hacking tickles my brain in a very joyful way and feels a bit like outsmarting Google. And that&#8217;s not bad at all.</p>
<p><strong>UPDATE:</strong> I now realize the comics&#8217;s navigation has been redesigned so my above fix became obsolete. At least I cherish the knowledge my hack addressed a real UI problem (and did that faster than Google :) ).</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/bucionrails?a=2EJML"><img src="http://feeds.feedburner.com/~f/bucionrails?i=2EJML" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/bucionrails?a=yOJSl"><img src="http://feeds.feedburner.com/~f/bucionrails?i=yOJSl" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/bucionrails/~4/393218616" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://bucionrails.com/2008/09/03/navigator-for-the-google-chrome-comicbook/feed/</wfw:commentRss>
		<feedburner:origLink>http://bucionrails.com/2008/09/03/navigator-for-the-google-chrome-comicbook/</feedburner:origLink></item>
		<item>
		<title>Now that’s what I call Web2.0: Ubiquity</title>
		<link>http://feeds.feedburner.com/~r/bucionrails/~3/393218617/</link>
		<comments>http://bucionrails.com/2008/08/29/now-thats-what-i-call-web20-ubiquity/#comments</comments>
		<pubDate>Fri, 29 Aug 2008 21:18:31 +0000</pubDate>
		<dc:creator>balint</dc:creator>
		
		<category><![CDATA[productivity]]></category>

		<guid isPermaLink="false">http://bucionrails.com/?p=10</guid>
		<description><![CDATA[I&#8217;ve stumbled upon a great Firefox plugin, Ubiquity. It basically accesses several web services (GoogleMaps, Gmail, Flickr, etc.) via its own panel and with its own commands so that common online tasks (e.g looking up something on Wikipedia you have just found on a page) become amazingly simple. I was really stunned by how much [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve stumbled upon a great Firefox plugin, Ubiquity. It basically accesses several web services (GoogleMaps, Gmail, Flickr, etc.) via its own panel and with its own commands so that common online tasks (e.g looking up something on Wikipedia you have just found on a page) become amazingly simple. I was really stunned by how much this plugin is capable of doing after watching the <a href="http://vimeo.com/1561578?pg=embed&amp;sec=1561578" target="_blank">briefing video</a> and going through the <a href="https://wiki.mozilla.org/Labs/Ubiquity/Ubiquity_0.1_User_Tutorial" target="_blank">tutorial</a>. And that does not stop there: power users can add their own commands to extend the already vast capabilities of the plugin. It&#8217;s been a long time I&#8217;ve been so excited about a &#8220;web 2.0&#8243; tool.</p>
<p><a href="http://www.azarask.in/blog/" target="_blank">Here</a> is the blog post about Ubiquity on Aza Raskin&#8217;s blog who is the main developer of the plugin.</p>
<p><em>Note</em>: If you use a Mac, you&#8217;ll need <a href="http://growl.info/about.php" target="_blank">Growl</a> for Ubiquity to display its command panel.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/bucionrails?a=e5c7L"><img src="http://feeds.feedburner.com/~f/bucionrails?i=e5c7L" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/bucionrails?a=3wRzl"><img src="http://feeds.feedburner.com/~f/bucionrails?i=3wRzl" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/bucionrails/~4/393218617" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://bucionrails.com/2008/08/29/now-thats-what-i-call-web20-ubiquity/feed/</wfw:commentRss>
		<feedburner:origLink>http://bucionrails.com/2008/08/29/now-thats-what-i-call-web20-ubiquity/</feedburner:origLink></item>
		<item>
		<title>Can less work be more?</title>
		<link>http://feeds.feedburner.com/~r/bucionrails/~3/393218618/</link>
		<comments>http://bucionrails.com/2008/07/17/can-less-work-be-more/#comments</comments>
		<pubDate>Thu, 17 Jul 2008 09:27:56 +0000</pubDate>
		<dc:creator>balint</dc:creator>
		
		<category><![CDATA[productivity]]></category>

		<guid isPermaLink="false">http://bucionrails.com/?p=8</guid>
		<description><![CDATA[I saw the keynote speech David Heinemeier Hansson gave at this year&#8217;s Railsconf in Portland and I liked it a lot. I really like the idea of following the pattern of &#8220;Less software is more&#8221; to the work we do each day. In his speech he says developers should spend one day a week discovering [...]]]></description>
			<content:encoded><![CDATA[<p>I saw the <a href="http://onrails.org/articles/2008/05/31/railsconf-2008-david-heinemeier-hanssons-keynote-video">keynote speech David Heinemeier Hansson</a> gave at this year&#8217;s Railsconf in Portland and I liked it a lot. I really like the idea of following the pattern of &#8220;Less software is more&#8221; to the work we do each day. In his speech he says developers should spend one day a week discovering a subject of interest, writing code for a pet project, contributing to an open source project, etc. Basically anything but doing the work they do on the other four days of the week. This &#8220;day-off&#8221; raises the developer&#8217;s productivity so it is a net gain for the main work he is involved with, too.</p>
<p>I tend to agree. However, in this post I want to elaborate rather what &#8216;be more&#8217; means in both the &#8216;less software is more&#8217; and the &#8216;less work is more&#8217; phrases. Less software means less lines of code to achieve the same tasks. Less work means less time spent working producing code to achieve the same tasks. There are two underlying concepts here that make this possible: abstraction and productivity. More precisely: the  ideas in your (hacker) head and the tools that allow you to implement these ideas in abstract, high-level  terms and thus raise your productivity.</p>
<p>When you write a program, there are basically two phases of producing code that solves a problem: first, you think about how to solve it and second, you convert the ideas into code. There is always a gap between the ideas and the code you write and that the computer comprehends. The more high-level the language is, the smaller the gap that needs to be bridged. But there is a backward effect, too. Usually when you are in the first phase you already think in terms of the second. The expressive tools the language provides have a strong effect on how you think of the problem (generally you know what language your solution will be implemented in). And that is bad because it dumbs down your thinking before you get to the point where you should consider the possibilities of the language.</p>
<p>I tend to think less of the language specifics in the first phase if I know the language provides all the high-level tools and provides them neatly. &#8220;For&#8221; loops skews your thinking more than -all kinds of- iterators. If I know functions are first-class objects and metaprogramming is available I worry less about how (or whether!) my abstract solution, only existing on the plane of ideas can be converted to functioning code.</p>
<p>So, back to where I started, your choice of the language counts and it counts a lot. It can help you be more productive in several ways, not just the fewer-lines-of-code-to-do-the-same-thing way but also the minimizing-the-skewing-of-your-thinking way. However, a high-level language is no guarantee to achieve that. One can churn out C-like code in Ruby, it is just easier to realize you are not using the full arsenal. And that&#8217;s where it really kicks in: if you know you can basically do anything painlessly you will dare to think big, your ideas can get off the ground. Consequently they will be abstract enough for you to be more productive.</p>
<p>So armed with daringly abstract ideas and tools that make it possible to put them into code, one sets out to conquer the world. The limit to the amount of code generated is the number of hours one can spend each day programming. After about ~8 hours of work is it worth to put in some more time to produce more code? <a href="http://www.extremeprogramming.org/rules/overtime.html">Probably not</a>. Our thinking breaks down pretty fast after that. I have experienced on several occasions that I could do in 10 minutes the next morning what I could not do in 2 hours the evening before. This is not about dropping the keyboard when the clock strikes 5pm, of course. It is about <a href="http://www.extremeprogramming.org/rules/velocity.html">planning for measurable progress without too much overtime</a>.</p>
<p>I think David is right when asserting that replenishing your mind so it can come up with constructive ideas is equally important. I am sure there are numerous ways to attain that. Some of them are constructive activities in themselves (David&#8217;s example was playing the banjo), some may just give you peace (e.g friends, family) and some may simply drift your thoughts away from the very problem you are working on (e.g playing soccer) and help you that way.</p>
<p>So what do you think about all that? Can low-level languages still have advantages over high-level ones in certain situations? Do you think the language your are programming in can have an effect on your problem-solving thoughts? What activities switch you off in the most &#8220;productive&#8221; way? What other factors have an effect on your work? (of course your working environment is very relevant). Are <a href="http://www.boston.com/bostonglobe/ideas/naps/">naps </a>worth it? When would the official Railsconf&#8217;08 videos be online? :)</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/bucionrails?a=RnLPL"><img src="http://feeds.feedburner.com/~f/bucionrails?i=RnLPL" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/bucionrails?a=ZD5el"><img src="http://feeds.feedburner.com/~f/bucionrails?i=ZD5el" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/bucionrails/~4/393218618" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://bucionrails.com/2008/07/17/can-less-work-be-more/feed/</wfw:commentRss>
		<feedburner:origLink>http://bucionrails.com/2008/07/17/can-less-work-be-more/</feedburner:origLink></item>
	</channel>
</rss>
