<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <title>Rails on the Run - Home</title>
  <id>tag:www.railsontherun.com,2008:mephisto/</id>
  <generator uri="http://mephistoblog.com" version="0.7.3">Mephisto Noh-Varr</generator>
  <link href="http://www.railsontherun.com/feed/atom.xml" rel="self" type="application/atom+xml"/>
  <link href="http://www.railsontherun.com/" rel="alternate" type="text/html"/>
  <updated>2008-06-27T07:07:14Z</updated>
  <entry xml:base="http://www.railsontherun.com/">
    <author>
      <name>matt</name>
    </author>
    <id>tag:www.railsontherun.com,2008-06-27:1259</id>
    <published>2008-06-27T07:06:00Z</published>
    <updated>2008-06-27T07:07:14Z</updated>
    <category term="community"/>
    <category term="fork"/>
    <category term="gem"/>
    <category term="github"/>
    <category term="googlecharts"/>
    <link href="http://www.railsontherun.com/2008/6/27/googlecharts-featured-on-github" rel="alternate" type="text/html"/>
    <title>Googlecharts featured on Github</title>
<content type="html">
            &lt;p&gt;&lt;a href=&quot;http://github.com&quot;&gt;Github&lt;/a&gt;, probably the most famous social code hosting service just &lt;a href=&quot;http://github.com/blog/103-new-homepage&quot;&gt;redesigned their homepage&lt;/a&gt; and are now featuring hosted projects.&lt;/p&gt;

&lt;p&gt;I got a very good surprise when &lt;a href=&quot;http://github.com/takeo&quot;&gt;Takeo&lt;/a&gt; from &lt;a href=&quot;http://powerset.com&quot;&gt;Powerset&lt;/a&gt; &amp;amp; &lt;a href=&quot;http://stafftool.com&quot;&gt;Stafftool&lt;/a&gt; hall of fame mentioned to me that &lt;a href=&quot;http://github.com&quot;&gt;Github&lt;/a&gt; picked one of my gems as the first featured project!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://img.skitch.com/20080627-r14subqdx2ye3w13qefbx974gc.png&quot; alt=&quot;github&quot; /&gt;&lt;/p&gt;

&lt;p&gt;By the way, Takeo is also a Googlecharts contributor (+ a Merbist) and I had the honor to be the first one he ever forked!&lt;/p&gt;

&lt;p&gt;Another Googlecharts user, &lt;a href=&quot;http://graffletopia.com&quot;&gt;Mokolabs&lt;/a&gt; from Graffletopia and &lt;a href=&quot;http://icalshare.com/&quot;&gt;iCal Share&lt;/a&gt; also decided to try Git and Github. In no time he had forked my project, made some modifications and sent me a pull request. w00t w00t!&lt;/p&gt;

&lt;p&gt;To celebrate, we released version 1.3.4 with cleaner documentation, and enhanced features.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://googlecharts.rubyforge.org/&quot;&gt;Documentation&lt;/a&gt; &amp;amp; &lt;a href=&quot;http://github.com/mattetti/googlecharts&quot;&gt;Code Repo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thanks to everyone involved in this project. And special kudos to the &lt;a href=&quot;http://github.com&quot;&gt;GitHub&lt;/a&gt; team for offering such an awesome service!&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.railsontherun.com/">
    <author>
      <name>matt</name>
    </author>
    <id>tag:www.railsontherun.com,2008-06-18:1245</id>
    <published>2008-06-18T07:03:00Z</published>
    <updated>2008-06-18T07:05:21Z</updated>
    <category term="benchmarks"/>
    <category term="metaprogramming"/>
    <category term="ruby"/>
    <link href="http://www.railsontherun.com/2008/6/18/about-metaprogramming-speed" rel="alternate" type="text/html"/>
    <title>About Metaprogramming speed</title>
<content type="html">
            &lt;p&gt;In a &lt;a href=&quot;http://railsontherun.com/2008/5/4/avoid-using-metaprogramming&quot;&gt;previous article&lt;/a&gt; I took an example of bad metaprogramming and I pushed people to think twice before using metaprogramming.&lt;/p&gt;

&lt;p&gt;My main points were that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;you might make your code way slower if you don't know what you are doing&lt;/li&gt;
&lt;li&gt;readability might drop considerably&lt;/li&gt;
&lt;li&gt;maintainability can become an issue&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;People left some very good comments about how to write the same module using metaprogramming and keep things fast.&lt;/p&gt;

&lt;p&gt;Today &lt;a href=&quot;http://yehudakatz.com&quot;&gt;Wycats&lt;/a&gt; pinged me about this post and told me that the issue was define&lt;em&gt;method and that class&lt;/em&gt;eval is effectively the same as regular code, it gets evaluated in eval.c, just like regular Ruby code. On the other hand, defined_method has to marshall the proc.&lt;/p&gt;

&lt;p&gt;I cleaned up my benchmarks using &lt;a href=&quot;http://github.com/somebee/rbench/tree/master&quot;&gt;rbench&lt;/a&gt;, added some of the solutions provided to me and obtained the following results:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://img.skitch.com/20080618-ju8hy1b1pw8c3hb882ksr3hbed.jpg&quot; alt=&quot;results&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Here is the original/bad metaprogramming example:&lt;/p&gt;

&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;cl&quot;&gt;MetaTimeDSL&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    {&lt;span class=&quot;sy&quot;&gt;:second&lt;/span&gt; =&amp;gt; &lt;span class=&quot;i&quot;&gt;1&lt;/span&gt;, &lt;tt&gt;
&lt;/tt&gt;     &lt;span class=&quot;sy&quot;&gt;:minute&lt;/span&gt; =&amp;gt; &lt;span class=&quot;i&quot;&gt;60&lt;/span&gt;, &lt;tt&gt;
&lt;/tt&gt;     &lt;span class=&quot;sy&quot;&gt;:hour&lt;/span&gt; =&amp;gt; &lt;span class=&quot;i&quot;&gt;3600&lt;/span&gt;, &lt;tt&gt;
&lt;/tt&gt;     &lt;span class=&quot;sy&quot;&gt;:day&lt;/span&gt; =&amp;gt; [&lt;span class=&quot;i&quot;&gt;24&lt;/span&gt;,&lt;span class=&quot;sy&quot;&gt;:hours&lt;/span&gt;], &lt;tt&gt;
&lt;/tt&gt;     &lt;span class=&quot;sy&quot;&gt;:week&lt;/span&gt; =&amp;gt; [&lt;span class=&quot;i&quot;&gt;7&lt;/span&gt;,&lt;span class=&quot;sy&quot;&gt;:days&lt;/span&gt;], &lt;tt&gt;
&lt;/tt&gt;     &lt;span class=&quot;sy&quot;&gt;:month&lt;/span&gt; =&amp;gt; [&lt;span class=&quot;i&quot;&gt;30&lt;/span&gt;,&lt;span class=&quot;sy&quot;&gt;:days&lt;/span&gt;], &lt;tt&gt;
&lt;/tt&gt;     &lt;span class=&quot;sy&quot;&gt;:year&lt;/span&gt; =&amp;gt; [&lt;span class=&quot;fl&quot;&gt;364.25&lt;/span&gt;, &lt;span class=&quot;sy&quot;&gt;:days&lt;/span&gt;]}.each &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt; |meth, amount|&lt;tt&gt;
&lt;/tt&gt;      define_method &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;dl&quot;&gt;#{&lt;/span&gt;meth&lt;span class=&quot;dl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;        amount = amount.is_a?(&lt;span class=&quot;co&quot;&gt;Array&lt;/span&gt;) ? amount[&lt;span class=&quot;i&quot;&gt;0&lt;/span&gt;].send(amount[&lt;span class=&quot;i&quot;&gt;1&lt;/span&gt;]) : amount&lt;tt&gt;
&lt;/tt&gt;        &lt;span class=&quot;pc&quot;&gt;self&lt;/span&gt; * amount&lt;tt&gt;
&lt;/tt&gt;      &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      alias_method &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;dl&quot;&gt;#{&lt;/span&gt;meth&lt;span class=&quot;dl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;.intern, &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;dl&quot;&gt;#{&lt;/span&gt;meth&lt;span class=&quot;dl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;co&quot;&gt;Numeric&lt;/span&gt;.send &lt;span class=&quot;sy&quot;&gt;:include&lt;/span&gt;, &lt;span class=&quot;co&quot;&gt;MetaTimeDSL&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;The no metaprogramming module is available &lt;a href=&quot;http://pastie.textmate.org/217046&quot;&gt;there&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Refactored:&lt;/p&gt;

&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;cl&quot;&gt;RefaMetaTimeDSL&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  {&lt;span class=&quot;sy&quot;&gt;:second&lt;/span&gt; =&amp;gt; &lt;span class=&quot;i&quot;&gt;1&lt;/span&gt;, &lt;tt&gt;
&lt;/tt&gt;   &lt;span class=&quot;sy&quot;&gt;:minute&lt;/span&gt; =&amp;gt; &lt;span class=&quot;i&quot;&gt;60&lt;/span&gt;, &lt;tt&gt;
&lt;/tt&gt;   &lt;span class=&quot;sy&quot;&gt;:hour&lt;/span&gt; =&amp;gt; &lt;span class=&quot;i&quot;&gt;3600&lt;/span&gt;, &lt;tt&gt;
&lt;/tt&gt;   &lt;span class=&quot;sy&quot;&gt;:day&lt;/span&gt; =&amp;gt; [&lt;span class=&quot;i&quot;&gt;24&lt;/span&gt;,&lt;span class=&quot;sy&quot;&gt;:hours&lt;/span&gt;], &lt;tt&gt;
&lt;/tt&gt;   &lt;span class=&quot;sy&quot;&gt;:week&lt;/span&gt; =&amp;gt; [&lt;span class=&quot;i&quot;&gt;7&lt;/span&gt;,&lt;span class=&quot;sy&quot;&gt;:days&lt;/span&gt;], &lt;tt&gt;
&lt;/tt&gt;   &lt;span class=&quot;sy&quot;&gt;:month&lt;/span&gt; =&amp;gt; [&lt;span class=&quot;i&quot;&gt;30&lt;/span&gt;,&lt;span class=&quot;sy&quot;&gt;:days&lt;/span&gt;], &lt;tt&gt;
&lt;/tt&gt;   &lt;span class=&quot;sy&quot;&gt;:year&lt;/span&gt; =&amp;gt; [&lt;span class=&quot;fl&quot;&gt;364.25&lt;/span&gt;, &lt;span class=&quot;sy&quot;&gt;:days&lt;/span&gt;]}.each &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt; |meth, amount|&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;pc&quot;&gt;self&lt;/span&gt;.class_eval &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;lt;&amp;lt;-RUBY&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;k&quot;&gt;&lt;tt&gt;
&lt;/tt&gt;      def r_&lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;dl&quot;&gt;#{&lt;/span&gt;meth&lt;span class=&quot;dl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;dl&quot;&gt;#{&lt;/span&gt;amount.is_a?(&lt;span class=&quot;co&quot;&gt;Array&lt;/span&gt;) ? &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;dl&quot;&gt;#{&lt;/span&gt;amount[&lt;span class=&quot;i&quot;&gt;0&lt;/span&gt;]&lt;span class=&quot;dl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;dl&quot;&gt;#{&lt;/span&gt;amount[&lt;span class=&quot;i&quot;&gt;1&lt;/span&gt;]&lt;span class=&quot;dl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; : &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;dl&quot;&gt;#{&lt;/span&gt;amount&lt;span class=&quot;dl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;&lt;tt&gt;
&lt;/tt&gt;      end&lt;tt&gt;
&lt;/tt&gt;      alias_method :r_&lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;dl&quot;&gt;#{&lt;/span&gt;meth&lt;span class=&quot;dl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;s, :r_&lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;dl&quot;&gt;#{&lt;/span&gt;meth&lt;span class=&quot;dl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&lt;tt&gt;
&lt;/tt&gt;    RUBY&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;co&quot;&gt;Numeric&lt;/span&gt;.send &lt;span class=&quot;sy&quot;&gt;:include&lt;/span&gt;, &lt;span class=&quot;co&quot;&gt;RefaMetaTimeDSL&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;the refactor 2 or eval based solution provided by &lt;a href=&quot;http://pastie.caboo.se/191414&quot;&gt;Matt Jones&lt;/a&gt; which uses class_eval like the previous refactor.&lt;/p&gt;

&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;cl&quot;&gt;EvalMetaTimeDSL&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;pc&quot;&gt;self&lt;/span&gt;.included(base)&lt;tt&gt;
&lt;/tt&gt;      base.class_eval &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;        [ [&lt;span class=&quot;sy&quot;&gt;:e_second&lt;/span&gt;, &lt;span class=&quot;i&quot;&gt;1&lt;/span&gt;], &lt;tt&gt;
&lt;/tt&gt;          [&lt;span class=&quot;sy&quot;&gt;:e_minute&lt;/span&gt;, &lt;span class=&quot;i&quot;&gt;60&lt;/span&gt;], &lt;tt&gt;
&lt;/tt&gt;          [&lt;span class=&quot;sy&quot;&gt;:e_hour&lt;/span&gt;, &lt;span class=&quot;i&quot;&gt;3600&lt;/span&gt;], &lt;tt&gt;
&lt;/tt&gt;          [&lt;span class=&quot;sy&quot;&gt;:e_day&lt;/span&gt;, [&lt;span class=&quot;i&quot;&gt;24&lt;/span&gt;,&lt;span class=&quot;sy&quot;&gt;:e_hours&lt;/span&gt;]], &lt;tt&gt;
&lt;/tt&gt;          [&lt;span class=&quot;sy&quot;&gt;:e_week&lt;/span&gt;, [&lt;span class=&quot;i&quot;&gt;7&lt;/span&gt;,&lt;span class=&quot;sy&quot;&gt;:e_days&lt;/span&gt;]], &lt;tt&gt;
&lt;/tt&gt;          [&lt;span class=&quot;sy&quot;&gt;:e_month&lt;/span&gt;, [&lt;span class=&quot;i&quot;&gt;30&lt;/span&gt;,&lt;span class=&quot;sy&quot;&gt;:e_days&lt;/span&gt;]], &lt;tt&gt;
&lt;/tt&gt;          [&lt;span class=&quot;sy&quot;&gt;:e_year&lt;/span&gt;, [&lt;span class=&quot;fl&quot;&gt;365.25&lt;/span&gt;, &lt;span class=&quot;sy&quot;&gt;:e_days&lt;/span&gt;]]].each &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt; |meth, amount|&lt;tt&gt;
&lt;/tt&gt;            amount = amount.is_a?(&lt;span class=&quot;co&quot;&gt;Array&lt;/span&gt;) ? amount[&lt;span class=&quot;i&quot;&gt;0&lt;/span&gt;].send(amount[&lt;span class=&quot;i&quot;&gt;1&lt;/span&gt;]) : amount&lt;tt&gt;
&lt;/tt&gt;            eval &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def &lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;dl&quot;&gt;#{&lt;/span&gt;meth&lt;span class=&quot;dl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;; self*&lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;dl&quot;&gt;#{&lt;/span&gt;amount&lt;span class=&quot;dl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;; end&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;            alias_method &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;dl&quot;&gt;#{&lt;/span&gt;meth&lt;span class=&quot;dl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, meth&lt;tt&gt;
&lt;/tt&gt;          &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;co&quot;&gt;Numeric&lt;/span&gt;.send &lt;span class=&quot;sy&quot;&gt;:include&lt;/span&gt;, &lt;span class=&quot;co&quot;&gt;EvalMetaTimeDSL&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;and finally, the &quot;better metaprogramming&quot; version:&lt;/p&gt;

&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt; &lt;span class=&quot;r&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;cl&quot;&gt;GoodMetaTimeDSL&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;co&quot;&gt;SECOND&lt;/span&gt;  = &lt;span class=&quot;i&quot;&gt;1&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;co&quot;&gt;MINUTE&lt;/span&gt;  = &lt;span class=&quot;co&quot;&gt;SECOND&lt;/span&gt; * &lt;span class=&quot;i&quot;&gt;60&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;co&quot;&gt;HOUR&lt;/span&gt;    = &lt;span class=&quot;co&quot;&gt;MINUTE&lt;/span&gt; * &lt;span class=&quot;i&quot;&gt;60&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;co&quot;&gt;DAY&lt;/span&gt;     = &lt;span class=&quot;co&quot;&gt;HOUR&lt;/span&gt; * &lt;span class=&quot;i&quot;&gt;24&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;co&quot;&gt;WEEK&lt;/span&gt;    = &lt;span class=&quot;co&quot;&gt;DAY&lt;/span&gt; * &lt;span class=&quot;i&quot;&gt;7&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;co&quot;&gt;MONTH&lt;/span&gt;   = &lt;span class=&quot;co&quot;&gt;DAY&lt;/span&gt; * &lt;span class=&quot;i&quot;&gt;30&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;co&quot;&gt;YEAR&lt;/span&gt;    = &lt;span class=&quot;co&quot;&gt;DAY&lt;/span&gt; * &lt;span class=&quot;fl&quot;&gt;364.25&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;%w[&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;SECOND MINUTE HOUR DAY WEEK MONTH YEAR&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;]&lt;/span&gt;&lt;/span&gt;.each &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt; |const_name|&lt;tt&gt;
&lt;/tt&gt;      meth = const_name.downcase&lt;tt&gt;
&lt;/tt&gt;      class_eval &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;lt;&amp;lt;-RUBY&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;k&quot;&gt;&lt;tt&gt;
&lt;/tt&gt;        def g_&lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;dl&quot;&gt;#{&lt;/span&gt;meth&lt;span class=&quot;dl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt; &lt;tt&gt;
&lt;/tt&gt;          self * &lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;dl&quot;&gt;#{&lt;/span&gt;const_name&lt;span class=&quot;dl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt; &lt;tt&gt;
&lt;/tt&gt;        end &lt;tt&gt;
&lt;/tt&gt;        alias g_&lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;dl&quot;&gt;#{&lt;/span&gt;meth&lt;span class=&quot;dl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;s g_&lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;dl&quot;&gt;#{&lt;/span&gt;meth&lt;span class=&quot;dl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt; &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&lt;tt&gt;
&lt;/tt&gt;      RUBY&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;co&quot;&gt;Numeric&lt;/span&gt;.send &lt;span class=&quot;sy&quot;&gt;:include&lt;/span&gt;, &lt;span class=&quot;co&quot;&gt;GoodMetaTimeDSL&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;Looking at the refactored version by Wycats, you can see he's right and the major issue with the original version was define&lt;em&gt;method. Using class&lt;/em&gt;eval does make things almost as fast and even faster than the no metaprogramming version.&lt;/p&gt;

&lt;p&gt;Interesting enough, the benchmarks show that some methods from the meta modules are faster than the ones from the no meta module. Overall, an optimized metaprogramming can be more or else as fast as a non meta code. Of course, with the new VMs coming up, things might change a little bit depending on the language implementation.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;In conclusion, metaprogramming can be as fast as no metaprogramming but that won't help your code readability and maintainability, so make sure to only use this great trick when needed!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;p.s: &lt;a href=&quot;http://pastie.textmate.org/217071&quot;&gt;here&lt;/a&gt; is the benchmark file if you don't believe me ;)&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.railsontherun.com/">
    <author>
      <name>matt</name>
    </author>
    <id>tag:www.railsontherun.com,2008-06-18:1242</id>
    <published>2008-06-18T01:40:00Z</published>
    <updated>2008-06-18T02:29:15Z</updated>
    <category term="conf"/>
    <category term="merb"/>
    <category term="news"/>
    <category term="rails"/>
    <category term="ruby"/>
    <link href="http://www.railsontherun.com/2008/6/18/news-update" rel="alternate" type="text/html"/>
    <title>News update</title>
<content type="html">
            &lt;p&gt;I realized I haven't updated this blog in a while. Here is a quick update on what's happened and on things to come:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&quot;http://en.oreilly.com/rails2008/public/content/home&quot;&gt;RailsConf 08&lt;/a&gt;. Great conference, probably my last Rails Conf though. I'll be in Orlando for &lt;a href=&quot;http://rubyconf.org/&quot;&gt;Ruby Conf 08&lt;/a&gt; and I'll focus on 1 or 2 local conferences (probably &lt;a href=&quot;http://mtnwestrubyconf.org/&quot;&gt;mountain west&lt;/a&gt; and another one).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;MerbCamp 08 in San Diego this Fall organized by &lt;a href=&quot;http://sdruby.com&quot;&gt;SD Ruby&lt;/a&gt;. Details are not finalized yet but &lt;a href=&quot;http://yehudakatz.com/&quot;&gt;Yehuda Katz&lt;/a&gt; announced it during his Merb talk at RailsConf.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Moved this blog to a new &lt;a href=&quot;http://joyent.com&quot;&gt;Joyent accelerator&lt;/a&gt; with git support and finally have the possibility to use Ambition! (planning on moving from Mephisto to &lt;a href=&quot;http://crazycool.co.uk/2008/04/26/announcing-feather&quot;&gt;Feather&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Launched a client's Merb app and getting around 3 million hits/day. Merb is just awesome. (more info when the client's app gets out of beta)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I'll join &lt;a href=&quot;http://railsenvy.com/&quot;&gt;Gregg Pollack&lt;/a&gt; from &lt;a href=&quot;http://railsenvy.com/&quot;&gt;http://railsenvy.com/&lt;/a&gt; during &lt;a href=&quot;http://qcon.infoq.com&quot;&gt;Qcon&lt;/a&gt; and take part in the &lt;a href=&quot;http://qcon.infoq.com/sanfrancisco-2008/tracks/show_track.jsp?trackOID=172&quot;&gt;Ruby for the Enterprise&lt;/a&gt; track. &lt;a href=&quot;http://qcon.infoq.com/sanfrancisco-2008/speaker/Matt+Aimonetti&quot;&gt;My talk&lt;/a&gt; will focus on Merb usage in real life.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Renamed my github username, new repo url: &lt;a href=&quot;http://github.com/mattetti&quot;&gt;http://github.com/mattetti&lt;/a&gt; (sorry about that)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
          </content>  </entry>
  <entry xml:base="http://www.railsontherun.com/">
    <author>
      <name>matt</name>
    </author>
    <id>tag:www.railsontherun.com,2008-05-04:1128</id>
    <published>2008-05-04T08:29:00Z</published>
    <updated>2008-05-04T08:37:51Z</updated>
    <category term="benchmark"/>
    <category term="merb"/>
    <category term="metaprogramming"/>
    <category term="speed"/>
    <link href="http://www.railsontherun.com/2008/5/4/avoid-using-metaprogramming" rel="alternate" type="text/html"/>
    <title>Avoid using metaprogramming (seriously!)</title>
<content type="html">
            &lt;p&gt;Ruby is sexy, Ruby is cool and its metaprogramming potential offers some really cook features. However you might not realize that your cleverness is slowing down your code.&lt;/p&gt;

&lt;p&gt;Today I was working on cleaning up merb_helper a Merb plugin that brings a lot of the stuff Rails developers are used to. In Merb we aim for speed and try to avoid magic.&lt;/p&gt;

&lt;p&gt;merb_plugin didn't receive a lot of love from the main contributors but few features were added by different contributors and the code became hard to maintain. &lt;/p&gt;

&lt;p&gt;Looking at the code I quickly found this bad boy:&lt;/p&gt;

&lt;p&gt;(Old Merb Time DSL using metaprogramming)&lt;/p&gt;

&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;   &lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;cl&quot;&gt;MetaTimeDSL&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    {&lt;span class=&quot;sy&quot;&gt;:second&lt;/span&gt; =&amp;gt; &lt;span class=&quot;i&quot;&gt;1&lt;/span&gt;, &lt;tt&gt;
&lt;/tt&gt;     &lt;span class=&quot;sy&quot;&gt;:minute&lt;/span&gt; =&amp;gt; &lt;span class=&quot;i&quot;&gt;60&lt;/span&gt;, &lt;tt&gt;
&lt;/tt&gt;     &lt;span class=&quot;sy&quot;&gt;:hour&lt;/span&gt; =&amp;gt; &lt;span class=&quot;i&quot;&gt;3600&lt;/span&gt;, &lt;tt&gt;
&lt;/tt&gt;     &lt;span class=&quot;sy&quot;&gt;:day&lt;/span&gt; =&amp;gt; [&lt;span class=&quot;i&quot;&gt;24&lt;/span&gt;,&lt;span class=&quot;sy&quot;&gt;:hours&lt;/span&gt;], &lt;tt&gt;
&lt;/tt&gt;     &lt;span class=&quot;sy&quot;&gt;:week&lt;/span&gt; =&amp;gt; [&lt;span class=&quot;i&quot;&gt;7&lt;/span&gt;,&lt;span class=&quot;sy&quot;&gt;:days&lt;/span&gt;], &lt;tt&gt;
&lt;/tt&gt;     &lt;span class=&quot;sy&quot;&gt;:month&lt;/span&gt; =&amp;gt; [&lt;span class=&quot;i&quot;&gt;30&lt;/span&gt;,&lt;span class=&quot;sy&quot;&gt;:days&lt;/span&gt;], &lt;tt&gt;
&lt;/tt&gt;     &lt;span class=&quot;sy&quot;&gt;:year&lt;/span&gt; =&amp;gt; [&lt;span class=&quot;fl&quot;&gt;364.25&lt;/span&gt;, &lt;span class=&quot;sy&quot;&gt;:days&lt;/span&gt;]}.each &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt; |meth, amount|&lt;tt&gt;
&lt;/tt&gt;      define_method &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;m_&lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;dl&quot;&gt;#{&lt;/span&gt;meth&lt;span class=&quot;dl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;        amount = amount.is_a?(&lt;span class=&quot;co&quot;&gt;Array&lt;/span&gt;) ? amount[&lt;span class=&quot;i&quot;&gt;0&lt;/span&gt;].send(amount[&lt;span class=&quot;i&quot;&gt;1&lt;/span&gt;]) : amount&lt;tt&gt;
&lt;/tt&gt;        &lt;span class=&quot;pc&quot;&gt;self&lt;/span&gt; * amount&lt;tt&gt;
&lt;/tt&gt;      &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      alias_method &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;m_&lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;dl&quot;&gt;#{&lt;/span&gt;meth&lt;span class=&quot;dl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;.intern, &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;m_&lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;dl&quot;&gt;#{&lt;/span&gt;meth&lt;span class=&quot;dl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;co&quot;&gt;Numeric&lt;/span&gt;.send &lt;span class=&quot;sy&quot;&gt;:include&lt;/span&gt;, &lt;span class=&quot;co&quot;&gt;MetaTimeDSL&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;The above code looks awful to me and I decided to rewrite it a way I thought would be more efficient:&lt;/p&gt;

&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;25&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;27&lt;tt&gt;
&lt;/tt&gt;28&lt;tt&gt;
&lt;/tt&gt;29&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;30&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;31&lt;tt&gt;
&lt;/tt&gt;32&lt;tt&gt;
&lt;/tt&gt;33&lt;tt&gt;
&lt;/tt&gt;34&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;35&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;36&lt;tt&gt;
&lt;/tt&gt;37&lt;tt&gt;
&lt;/tt&gt;38&lt;tt&gt;
&lt;/tt&gt;39&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;40&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;41&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;cl&quot;&gt;TimeDSL&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;second&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class=&quot;pc&quot;&gt;self&lt;/span&gt; * &lt;span class=&quot;i&quot;&gt;1&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    alias_method &lt;span class=&quot;sy&quot;&gt;:seconds&lt;/span&gt;, &lt;span class=&quot;sy&quot;&gt;:second&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;minute&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class=&quot;pc&quot;&gt;self&lt;/span&gt; * &lt;span class=&quot;i&quot;&gt;60&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    alias_method &lt;span class=&quot;sy&quot;&gt;:minutes&lt;/span&gt;, &lt;span class=&quot;sy&quot;&gt;:minute&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;hour&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class=&quot;pc&quot;&gt;self&lt;/span&gt; * &lt;span class=&quot;i&quot;&gt;3600&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    alias_method &lt;span class=&quot;sy&quot;&gt;:hours&lt;/span&gt;, &lt;span class=&quot;sy&quot;&gt;:hour&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;day&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class=&quot;pc&quot;&gt;self&lt;/span&gt; * &lt;span class=&quot;i&quot;&gt;86400&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    alias_method &lt;span class=&quot;sy&quot;&gt;:days&lt;/span&gt;, &lt;span class=&quot;sy&quot;&gt;:day&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;week&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class=&quot;pc&quot;&gt;self&lt;/span&gt; * &lt;span class=&quot;i&quot;&gt;604800&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    alias_method &lt;span class=&quot;sy&quot;&gt;:weeks&lt;/span&gt;, &lt;span class=&quot;sy&quot;&gt;:week&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;month&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class=&quot;pc&quot;&gt;self&lt;/span&gt; * &lt;span class=&quot;i&quot;&gt;2592000&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    alias_method &lt;span class=&quot;sy&quot;&gt;:months&lt;/span&gt;, &lt;span class=&quot;sy&quot;&gt;:month&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;year&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class=&quot;pc&quot;&gt;self&lt;/span&gt; * &lt;span class=&quot;i&quot;&gt;31471200&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    alias_method &lt;span class=&quot;sy&quot;&gt;:years&lt;/span&gt;, &lt;span class=&quot;sy&quot;&gt;:year&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;co&quot;&gt;Numeric&lt;/span&gt;.send &lt;span class=&quot;sy&quot;&gt;:include&lt;/span&gt;, &lt;span class=&quot;co&quot;&gt;TimeDSL&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;To make sure I was right, I run the following benchmarks:&lt;/p&gt;

&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;25&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;27&lt;tt&gt;
&lt;/tt&gt;28&lt;tt&gt;
&lt;/tt&gt;29&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;30&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;31&lt;tt&gt;
&lt;/tt&gt;32&lt;tt&gt;
&lt;/tt&gt;33&lt;tt&gt;
&lt;/tt&gt;34&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;35&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;36&lt;tt&gt;
&lt;/tt&gt;37&lt;tt&gt;
&lt;/tt&gt;38&lt;tt&gt;
&lt;/tt&gt;39&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;40&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;41&lt;tt&gt;
&lt;/tt&gt;42&lt;tt&gt;
&lt;/tt&gt;43&lt;tt&gt;
&lt;/tt&gt;44&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;45&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;46&lt;tt&gt;
&lt;/tt&gt;47&lt;tt&gt;
&lt;/tt&gt;48&lt;tt&gt;
&lt;/tt&gt;49&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;50&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;51&lt;tt&gt;
&lt;/tt&gt;52&lt;tt&gt;
&lt;/tt&gt;53&lt;tt&gt;
&lt;/tt&gt;54&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;55&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;56&lt;tt&gt;
&lt;/tt&gt;57&lt;tt&gt;
&lt;/tt&gt;58&lt;tt&gt;
&lt;/tt&gt;59&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;60&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;61&lt;tt&gt;
&lt;/tt&gt;62&lt;tt&gt;
&lt;/tt&gt;63&lt;tt&gt;
&lt;/tt&gt;64&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;65&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;66&lt;tt&gt;
&lt;/tt&gt;67&lt;tt&gt;
&lt;/tt&gt;68&lt;tt&gt;
&lt;/tt&gt;69&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;70&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;71&lt;tt&gt;
&lt;/tt&gt;72&lt;tt&gt;
&lt;/tt&gt;73&lt;tt&gt;
&lt;/tt&gt;74&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;75&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;76&lt;tt&gt;
&lt;/tt&gt;77&lt;tt&gt;
&lt;/tt&gt;78&lt;tt&gt;
&lt;/tt&gt;79&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;80&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;81&lt;tt&gt;
&lt;/tt&gt;82&lt;tt&gt;
&lt;/tt&gt;83&lt;tt&gt;
&lt;/tt&gt;84&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;85&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;86&lt;tt&gt;
&lt;/tt&gt;87&lt;tt&gt;
&lt;/tt&gt;88&lt;tt&gt;
&lt;/tt&gt;89&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;90&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;91&lt;tt&gt;
&lt;/tt&gt;92&lt;tt&gt;
&lt;/tt&gt;93&lt;tt&gt;
&lt;/tt&gt;94&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;95&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;96&lt;tt&gt;
&lt;/tt&gt;97&lt;tt&gt;
&lt;/tt&gt;98&lt;tt&gt;
&lt;/tt&gt;99&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;100&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;101&lt;tt&gt;
&lt;/tt&gt;102&lt;tt&gt;
&lt;/tt&gt;103&lt;tt&gt;
&lt;/tt&gt;104&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;105&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;106&lt;tt&gt;
&lt;/tt&gt;107&lt;tt&gt;
&lt;/tt&gt;108&lt;tt&gt;
&lt;/tt&gt;109&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;110&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;111&lt;tt&gt;
&lt;/tt&gt;112&lt;tt&gt;
&lt;/tt&gt;113&lt;tt&gt;
&lt;/tt&gt;114&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;115&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;116&lt;tt&gt;
&lt;/tt&gt;117&lt;tt&gt;
&lt;/tt&gt;118&lt;tt&gt;
&lt;/tt&gt;119&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;120&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;121&lt;tt&gt;
&lt;/tt&gt;122&lt;tt&gt;
&lt;/tt&gt;123&lt;tt&gt;
&lt;/tt&gt;124&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;125&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;126&lt;tt&gt;
&lt;/tt&gt;127&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;require &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;benchmark&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;co&quot;&gt;TIMES&lt;/span&gt; = (&lt;span class=&quot;pc&quot;&gt;ARGV&lt;/span&gt;[&lt;span class=&quot;i&quot;&gt;0&lt;/span&gt;] || &lt;span class=&quot;i&quot;&gt;100_000&lt;/span&gt;).to_i&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;co&quot;&gt;Benchmark&lt;/span&gt;.bmbm &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt; |x|&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  x.report(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;metaprogramming 360.seconds&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;) &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;co&quot;&gt;TIMES&lt;/span&gt;.times &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;    &lt;tt&gt;
&lt;/tt&gt;      &lt;span class=&quot;i&quot;&gt;360&lt;/span&gt;.m_seconds&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  x.report(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;no metaprogramming 360.hours&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;) &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;co&quot;&gt;TIMES&lt;/span&gt;.times &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class=&quot;i&quot;&gt;360&lt;/span&gt;.seconds&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  x.report(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;metaprogramming 360.minutes&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;) &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;co&quot;&gt;TIMES&lt;/span&gt;.times &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;    &lt;tt&gt;
&lt;/tt&gt;      &lt;span class=&quot;i&quot;&gt;360&lt;/span&gt;.m_minutes&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  x.report(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;no metaprogramming 360.minutes&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;) &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;co&quot;&gt;TIMES&lt;/span&gt;.times &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class=&quot;i&quot;&gt;360&lt;/span&gt;.minutes&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  x.report(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;metaprogramming 360.hours&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;) &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;co&quot;&gt;TIMES&lt;/span&gt;.times &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;    &lt;tt&gt;
&lt;/tt&gt;      &lt;span class=&quot;i&quot;&gt;360&lt;/span&gt;.m_hours&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  x.report(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;no metaprogramming 360.hours&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;) &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;co&quot;&gt;TIMES&lt;/span&gt;.times &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class=&quot;i&quot;&gt;360&lt;/span&gt;.hours&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  x.report(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;metaprogramming 360.days&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;) &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;co&quot;&gt;TIMES&lt;/span&gt;.times &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;    &lt;tt&gt;
&lt;/tt&gt;      &lt;span class=&quot;i&quot;&gt;360&lt;/span&gt;.m_days&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  x.report(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;no metaprogramming 360.days&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;) &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;co&quot;&gt;TIMES&lt;/span&gt;.times &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class=&quot;i&quot;&gt;360&lt;/span&gt;.days&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  x.report(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;metaprogramming 360.weeks&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;) &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;co&quot;&gt;TIMES&lt;/span&gt;.times &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;    &lt;tt&gt;
&lt;/tt&gt;      &lt;span class=&quot;i&quot;&gt;360&lt;/span&gt;.m_weeks&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  x.report(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;no metaprogramming 360.weeks&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;) &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;co&quot;&gt;TIMES&lt;/span&gt;.times &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class=&quot;i&quot;&gt;360&lt;/span&gt;.weeks&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  x.report(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;metaprogramming 18.months&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;) &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;co&quot;&gt;TIMES&lt;/span&gt;.times &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;    &lt;tt&gt;
&lt;/tt&gt;      &lt;span class=&quot;i&quot;&gt;18&lt;/span&gt;.m_months&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  x.report(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;no metaprogramming 18.months&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;) &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;co&quot;&gt;TIMES&lt;/span&gt;.times &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class=&quot;i&quot;&gt;18&lt;/span&gt;.months&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  x.report(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;metaprogramming 7.years&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;) &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;co&quot;&gt;TIMES&lt;/span&gt;.times &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;    &lt;tt&gt;
&lt;/tt&gt;      &lt;span class=&quot;i&quot;&gt;7&lt;/span&gt;.m_years&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  x.report(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;no metaprogramming 7.years&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;) &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;co&quot;&gt;TIMES&lt;/span&gt;.times &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class=&quot;i&quot;&gt;7&lt;/span&gt;.years&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt; &lt;span class=&quot;co&quot;&gt;Rehearsal&lt;/span&gt; ------------------------------------------------------------------&lt;tt&gt;
&lt;/tt&gt;metaprogramming &lt;span class=&quot;i&quot;&gt;360&lt;/span&gt;.seconds      &lt;span class=&quot;fl&quot;&gt;0.130000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.000000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.130000&lt;/span&gt; (  &lt;span class=&quot;fl&quot;&gt;0.133164&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;no metaprogramming &lt;span class=&quot;i&quot;&gt;360&lt;/span&gt;.hours     &lt;span class=&quot;fl&quot;&gt;0.050000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.000000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.050000&lt;/span&gt; (  &lt;span class=&quot;fl&quot;&gt;0.042655&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;metaprogramming &lt;span class=&quot;i&quot;&gt;360&lt;/span&gt;.minutes      &lt;span class=&quot;fl&quot;&gt;0.130000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.000000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.130000&lt;/span&gt; (  &lt;span class=&quot;fl&quot;&gt;0.133327&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;no metaprogramming &lt;span class=&quot;i&quot;&gt;360&lt;/span&gt;.minutes   &lt;span class=&quot;fl&quot;&gt;0.040000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.000000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.040000&lt;/span&gt; (  &lt;span class=&quot;fl&quot;&gt;0.042401&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;metaprogramming &lt;span class=&quot;i&quot;&gt;360&lt;/span&gt;.hours        &lt;span class=&quot;fl&quot;&gt;0.140000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.000000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.140000&lt;/span&gt; (  &lt;span class=&quot;fl&quot;&gt;0.134312&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;no metaprogramming &lt;span class=&quot;i&quot;&gt;360&lt;/span&gt;.hours     &lt;span class=&quot;fl&quot;&gt;0.040000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.000000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.040000&lt;/span&gt; (  &lt;span class=&quot;fl&quot;&gt;0.043125&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;metaprogramming &lt;span class=&quot;i&quot;&gt;360&lt;/span&gt;.days         &lt;span class=&quot;fl&quot;&gt;0.130000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.000000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.130000&lt;/span&gt; (  &lt;span class=&quot;fl&quot;&gt;0.134949&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;no metaprogramming &lt;span class=&quot;i&quot;&gt;360&lt;/span&gt;.days      &lt;span class=&quot;fl&quot;&gt;0.050000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.000000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.050000&lt;/span&gt; (  &lt;span class=&quot;fl&quot;&gt;0.043745&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;metaprogramming &lt;span class=&quot;i&quot;&gt;360&lt;/span&gt;.weeks        &lt;span class=&quot;fl&quot;&gt;0.130000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.000000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.130000&lt;/span&gt; (  &lt;span class=&quot;fl&quot;&gt;0.135581&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;no metaprogramming &lt;span class=&quot;i&quot;&gt;360&lt;/span&gt;.weeks     &lt;span class=&quot;fl&quot;&gt;0.050000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.000000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.050000&lt;/span&gt; (  &lt;span class=&quot;fl&quot;&gt;0.043544&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;metaprogramming &lt;span class=&quot;i&quot;&gt;18&lt;/span&gt;.months        &lt;span class=&quot;fl&quot;&gt;0.130000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.000000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.130000&lt;/span&gt; (  &lt;span class=&quot;fl&quot;&gt;0.135234&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;no metaprogramming &lt;span class=&quot;i&quot;&gt;18&lt;/span&gt;.months     &lt;span class=&quot;fl&quot;&gt;0.050000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.000000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.050000&lt;/span&gt; (  &lt;span class=&quot;fl&quot;&gt;0.044354&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;metaprogramming &lt;span class=&quot;i&quot;&gt;7&lt;/span&gt;.years          &lt;span class=&quot;fl&quot;&gt;0.140000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.000000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.140000&lt;/span&gt; (  &lt;span class=&quot;fl&quot;&gt;0.144062&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;no metaprogramming &lt;span class=&quot;i&quot;&gt;7&lt;/span&gt;.years       &lt;span class=&quot;fl&quot;&gt;0.050000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.000000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.050000&lt;/span&gt; (  &lt;span class=&quot;fl&quot;&gt;0.044392&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;--------------------------------------------------------- total: &lt;span class=&quot;fl&quot;&gt;1.260000&lt;/span&gt;sec&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;                                     user     system      total        real&lt;tt&gt;
&lt;/tt&gt;metaprogramming &lt;span class=&quot;i&quot;&gt;360&lt;/span&gt;.seconds      &lt;span class=&quot;fl&quot;&gt;0.130000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.000000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.130000&lt;/span&gt; (  &lt;span class=&quot;fl&quot;&gt;0.132567&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;no metaprogramming &lt;span class=&quot;i&quot;&gt;360&lt;/span&gt;.hours     &lt;span class=&quot;fl&quot;&gt;0.040000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.000000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.040000&lt;/span&gt; (  &lt;span class=&quot;fl&quot;&gt;0.042777&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;metaprogramming &lt;span class=&quot;i&quot;&gt;360&lt;/span&gt;.minutes      &lt;span class=&quot;fl&quot;&gt;0.140000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.000000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.140000&lt;/span&gt; (  &lt;span class=&quot;fl&quot;&gt;0.132554&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;no metaprogramming &lt;span class=&quot;i&quot;&gt;360&lt;/span&gt;.minutes   &lt;span class=&quot;fl&quot;&gt;0.040000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.000000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.040000&lt;/span&gt; (  &lt;span class=&quot;fl&quot;&gt;0.043193&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;metaprogramming &lt;span class=&quot;i&quot;&gt;360&lt;/span&gt;.hours        &lt;span class=&quot;fl&quot;&gt;0.130000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.000000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.130000&lt;/span&gt; (  &lt;span class=&quot;fl&quot;&gt;0.133027&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;no metaprogramming &lt;span class=&quot;i&quot;&gt;360&lt;/span&gt;.hours     &lt;span class=&quot;fl&quot;&gt;0.050000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.000000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.050000&lt;/span&gt; (  &lt;span class=&quot;fl&quot;&gt;0.042613&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;metaprogramming &lt;span class=&quot;i&quot;&gt;360&lt;/span&gt;.days         &lt;span class=&quot;fl&quot;&gt;0.130000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.000000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.130000&lt;/span&gt; (  &lt;span class=&quot;fl&quot;&gt;0.138637&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;no metaprogramming &lt;span class=&quot;i&quot;&gt;360&lt;/span&gt;.days      &lt;span class=&quot;fl&quot;&gt;0.050000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.000000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.050000&lt;/span&gt; (  &lt;span class=&quot;fl&quot;&gt;0.043213&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;metaprogramming &lt;span class=&quot;i&quot;&gt;360&lt;/span&gt;.weeks        &lt;span class=&quot;fl&quot;&gt;0.130000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.000000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.130000&lt;/span&gt; (  &lt;span class=&quot;fl&quot;&gt;0.134049&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;no metaprogramming &lt;span class=&quot;i&quot;&gt;360&lt;/span&gt;.weeks     &lt;span class=&quot;fl&quot;&gt;0.040000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.000000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.040000&lt;/span&gt; (  &lt;span class=&quot;fl&quot;&gt;0.043713&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;metaprogramming &lt;span class=&quot;i&quot;&gt;18&lt;/span&gt;.months        &lt;span class=&quot;fl&quot;&gt;0.140000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.000000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.140000&lt;/span&gt; (  &lt;span class=&quot;fl&quot;&gt;0.134941&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;no metaprogramming &lt;span class=&quot;i&quot;&gt;18&lt;/span&gt;.months     &lt;span class=&quot;fl&quot;&gt;0.040000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.000000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.040000&lt;/span&gt; (  &lt;span class=&quot;fl&quot;&gt;0.043980&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;metaprogramming &lt;span class=&quot;i&quot;&gt;7&lt;/span&gt;.years          &lt;span class=&quot;fl&quot;&gt;0.150000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.000000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.150000&lt;/span&gt; (  &lt;span class=&quot;fl&quot;&gt;0.143389&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;no metaprogramming &lt;span class=&quot;i&quot;&gt;7&lt;/span&gt;.years       &lt;span class=&quot;fl&quot;&gt;0.040000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.000000&lt;/span&gt;   &lt;span class=&quot;fl&quot;&gt;0.040000&lt;/span&gt; (  &lt;span class=&quot;fl&quot;&gt;0.044585&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt; &lt;span class=&quot;fl&quot;&gt;0.136591&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;The metaprogramming version of the same implementation is almost 3 times slower! &lt;/p&gt;

&lt;p&gt;Moral of the story: only use metaprogramming if you really have to or if you don't care about speed of execution.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.railsontherun.com/">
    <author>
      <name>matt</name>
    </author>
    <id>tag:www.railsontherun.com,2008-04-27:1081</id>
    <published>2008-04-27T17:24:00Z</published>
    <updated>2008-04-28T03:20:38Z</updated>
    <category term="barcamp"/>
    <category term="sandiego"/>
    <link href="http://www.railsontherun.com/2008/4/27/barcamp-san-diego-rev-3" rel="alternate" type="text/html"/>
    <title>BarCamp San Diego rev.3</title>
<content type="html">
            &lt;p&gt;&lt;img src=&quot;http://www.barcampsd.org/badges_for_bcsd3/orange.png&quot; alt=&quot;BarCamp&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Just a reminder, this coming week end, San Diego presents &lt;a href=&quot;http://www.barcampsd.org/&quot;&gt;BarCamp&lt;/a&gt; for the third time.&lt;/p&gt;

&lt;p&gt;This time, the chosen Venue is &lt;a href=&quot;http://www.technicaltrainingresources.com/&quot;&gt;Microsoft&lt;/a&gt; in &lt;a href=&quot;http://maps.google.com/maps?hl=en&amp;amp;amp;ie=UTF8&amp;amp;amp;f=d&amp;amp;amp;daddr=9255+Towne+Centre+Dr+San+Diego,+CA+92121&quot;&gt;La Jolla&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I was thinking about preparing 2 intro talks, one on &lt;a href=&quot;http://merbivore.com&quot;&gt;Merb&lt;/a&gt; and one on &lt;a href=&quot;http://en.wikipedia.org/wiki/Unobtrusive_JavaScript&quot;&gt;Unobtrusive Javascript&lt;/a&gt; (jQuery, Prototype + LowPro etc...), then we'll see the crowd and what people are interested in. Feel free to give me your feedback, suggestions...&lt;/p&gt;

&lt;p&gt;I also heard that on top of the awesome people from san Diego, some other important people are coming just for the event:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://glu.ttono.us/&quot;&gt;Kevin Clark&lt;/a&gt; from the &lt;a href=&quot;http://www.powerset.com/&quot;&gt;Powerset&lt;/a&gt; hall of fame.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://derekneighbors.com/&quot;&gt;Derek Neighbors&lt;/a&gt; representing Phoenix's top Rails shop: &lt;a href=&quot;http://integrumtech.com&quot;&gt;Integrum&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Warning&lt;/h2&gt;

&lt;p&gt;Based on previous BarCamps, you might end up seeing &lt;a href=&quot;http://www.flickr.com/photos/kirinqueen/1993483057/sizes/m/in/pool-393912@N21/&quot;&gt;a guy wearing a kilt who talks about how he is his own imaginary friend&lt;/a&gt;, having to look at  &lt;a href=&quot;http://www.flickr.com/photos/techslut/2043825771/sizes/l/in/pool-393912@N21/&quot;&gt;ActionScript code&lt;/a&gt;, meet &lt;a href=&quot;http://www.flickr.com/photos/acphonehome/532658193/in/pool-barcampsd/&quot;&gt;a lot&lt;/a&gt; of &lt;a href=&quot;http://www.flickr.com/photos/kirinqueen/531272887/in/pool-barcampsd&quot;&gt;interesting people&lt;/a&gt; and even maybe learn about &lt;a href=&quot;http://www.flickr.com/photos/techslut/545216043/in/pool-barcampsd&quot;&gt;lock picking&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://farm2.static.flickr.com/1053/527321111_763e4ad085.jpg&quot;&gt;&lt;img src=&quot;http://farm2.static.flickr.com/1053/527321111_763e4ad085_m.jpg&quot; alt=&quot;last year barcamp sd crowd&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://farm3.static.flickr.com/2004/2044606386_2ee84dcce3.jpg&quot;&gt;&lt;img src=&quot;http://farm3.static.flickr.com/2004/2044606386_2ee84dcce3_m.jpg&quot; alt=&quot;outside&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://farm2.static.flickr.com/1082/529394507_f34d9015c0.jpg&quot;&gt;&lt;img src=&quot;http://farm2.static.flickr.com/1082/529394507_f34d9015c0_m.jpg&quot; alt=&quot;powerpoint karaoke&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://farm2.static.flickr.com/1114/527020113_cbe6393372.jpg&quot;&gt;&lt;img src=&quot;http://farm2.static.flickr.com/1114/527020113_cbe6393372_m.jpg&quot; alt=&quot;tshirt printing&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://farm3.static.flickr.com/2351/1994270564_3a0a2f5319.jpg&quot;&gt;&lt;img src=&quot;http://farm3.static.flickr.com/2351/1994270564_3a0a2f5319_m.jpg&quot; alt=&quot;presentation&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I even heard rumors saying that &lt;a href=&quot;http://blog.aisleten.com/&quot;&gt;Ryan Felton&lt;/a&gt; is organizing another &lt;a href=&quot;http://www.flickr.com/photos/kirinqueen/1994487718/in/pool-barcampsd&quot;&gt;wii tournament&lt;/a&gt;.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.railsontherun.com/">
    <author>
      <name>matt</name>
    </author>
    <id>tag:www.railsontherun.com,2008-04-16:959</id>
    <published>2008-04-16T08:21:00Z</published>
    <updated>2008-06-18T02:30:59Z</updated>
    <category term="freeze"/>
    <category term="git"/>
    <category term="rais"/>
    <link href="http://www.railsontherun.com/2008/4/16/freezing-rails-with-git" rel="alternate" type="text/html"/>
    <title>Freezing Rails with Git</title>
<content type="html">
            &lt;p&gt;As you've &lt;a href=&quot;http://blog.rubyonrails.com/2008/4/11/rails-premieres-on-github&quot;&gt;probably heard&lt;/a&gt;, Rails now moved to &lt;a href=&quot;http://github.com/rails/rails&quot;&gt;its own GitHub repo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If, like me you were a heavy &lt;a href=&quot;http://piston.rubyforge.org/&quot;&gt;piston&lt;/a&gt; user, you are wondering how you will be able to do the same thing if you switch to git. &lt;/p&gt;

&lt;p&gt;First off, you need to know that Piston will soon support git. As a matter a fact it already does. At least you can download a beta version from &lt;a href=&quot;http://blog.teksol.info/tags/piston&quot;&gt;François's blog&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can also go with &lt;a href=&quot;http://evil.che.lu/projects/braid&quot;&gt;giston/braids&lt;/a&gt; which was meant to make the svn/switch easy on you. I heard rumors that &lt;a href=&quot;http://evil.che.lu&quot;&gt;evilchelu&lt;/a&gt; might not keep on developing this project. You might want to check with him.&lt;/p&gt;

&lt;p&gt;Personally I didn't really like using any of these solutions. Rails also came with its' own approach. (&lt;a href=&quot;http://github.com/rails/rails/commit/4b17082107aced980fc4b511028ee763247bc5ab&quot;&gt;rake rails:freeze:edge&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;When I recently worked on &lt;a href=&quot;http://railsontherun.com/2008/4/15/merb-tip-how-to-freeze-a-project&quot;&gt;Merb's freezer&lt;/a&gt;, I discovered the power of &lt;a href=&quot;http://www.kernel.org/pub/software/scm/git/docs/git-submodule.html&quot;&gt;git submodules&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Submodules allow you to import &quot;modules&quot; from other git repos inside your own repo. Basically they do what piston does for SVN, apart that submodules are built-in git. Of course it has an expected limitation, you can only add git submodules. &lt;/p&gt;

&lt;p&gt;The good news is that Rails moved to git and now you can &quot;freeze&quot; Rails as a submodule and update really easily!&lt;/p&gt;

&lt;p&gt;First thing first, you need to move your project to git. If you are not confident it's a good move yet, you can use &quot;git-svn&quot;. However, I would personally recommend you don't. I did that for few months and when I finally moved to git only, it was a pain to restructure the entire path of the app.&lt;/p&gt;

&lt;p&gt;Anyways, let's say you created a new &lt;a href=&quot;http://github.com&quot;&gt;github&lt;/a&gt; project and if still wish to use git svn do:&lt;/p&gt;

&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;er&quot;&gt;$&lt;/span&gt; git-svn import svn&lt;span class=&quot;sy&quot;&gt;:/&lt;/span&gt;/path-to-your-svn-repo project-name&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;er&quot;&gt;$&lt;/span&gt; cd project-name&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;er&quot;&gt;$&lt;/span&gt; git remote add origin git&lt;span class=&quot;iv&quot;&gt;@github&lt;/span&gt;.com&lt;span class=&quot;sy&quot;&gt;:mattetti&lt;/span&gt;/project-name.git&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;er&quot;&gt;$&lt;/span&gt; git push origin master&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;Your project is now under git, but if you pistonized Rails, you can't update it anymore :(&lt;/p&gt;

&lt;p&gt;Do not fear my dear friend and do as follows:&lt;/p&gt;

&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;er&quot;&gt;$&lt;/span&gt; rm -rf vendor/rails&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;er&quot;&gt;$&lt;/span&gt; git commit&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;er&quot;&gt;$&lt;/span&gt; git submodule add git&lt;span class=&quot;sy&quot;&gt;:/&lt;/span&gt;/github.com/rails/rails.git vendor/rails&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;er&quot;&gt;$&lt;/span&gt; git submodule init&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;er&quot;&gt;$&lt;/span&gt; git commit&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;er&quot;&gt;$&lt;/span&gt; &lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;That's it you are done :)&lt;/p&gt;

&lt;p&gt;Next time you want to update just do:&lt;/p&gt;

&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;er&quot;&gt;$&lt;/span&gt; cd vendor/rails&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;er&quot;&gt;$&lt;/span&gt; git remote update&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;er&quot;&gt;$&lt;/span&gt; git merge origin/master&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;or you can also do&lt;/p&gt;

&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;er&quot;&gt;$&lt;/span&gt; cd vendor/rails&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;er&quot;&gt;$&lt;/span&gt; git pull&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;(yes, each plugin acts a a normal git repo)&lt;/p&gt;

&lt;p&gt;A quick note for gitHub users. If you browse your repo you won't see the vendor/rails folder and might freak out. Don't! Git is smart and wants to stay slim, instead of copying the files over, it just creates a reference to the original repo. If you try to pull your project in another folder you will see that the Rails folder gets created as expected.&lt;/p&gt;

&lt;p&gt;Personally, when plugins are not available in a git repo I usually do a simple svn export to my project vendor's folder. If I need to modify one of these plugins, I just import it to &lt;a href=&quot;http://github.com&quot;&gt;github&lt;/a&gt; and work on it from there.&lt;/p&gt;

&lt;p&gt;You might still want to stick to Piston or Braids and that's fine, but now you won't have an excuse not to switch to Git :)&lt;/p&gt;

&lt;p&gt;UPDATE: I just found out that Graeme wrote a &lt;a href=&quot;http://woss.name/2008/04/09/using-git-submodules-to-track-vendorrails/&quot;&gt;nice detailed post&lt;/a&gt; about tracking plugins using git, &lt;a href=&quot;http://woss.name/2008/04/09/using-git-submodules-to-track-vendorrails/&quot;&gt;check it out&lt;/a&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.railsontherun.com/">
    <author>
      <name>matt</name>
    </author>
    <id>tag:www.railsontherun.com,2008-04-15:944</id>
    <published>2008-04-15T07:42:00Z</published>
    <updated>2008-04-15T07:43:03Z</updated>
    <category term="freezer"/>
    <category term="merb"/>
    <category term="merb-freezer"/>
    <link href="http://www.railsontherun.com/2008/4/15/merb-tip-how-to-freeze-a-project" rel="alternate" type="text/html"/>
    <title>Merb tip - how to freeze a project?</title>
<content type="html">
            &lt;p&gt;After few of my patches got accepted by the &lt;a href=&quot;merbivore&quot;&gt;Merb&lt;/a&gt; lead team, I was given commit access to &lt;a href=&quot;http://github.com/wycats/merb-more&quot;&gt;merb-more&lt;/a&gt;. &lt;a href=&quot;merbivore&quot;&gt;Merb&lt;/a&gt; doesn't really have a core team per say. It's actually managed the same way &lt;a href=&quot;http://rubini.us&quot;&gt;Rubinius&lt;/a&gt; is managed meaning that few people such as &lt;a href=&quot;http://github.com/ezmobius&quot;&gt;Ezra&lt;/a&gt;, &lt;a href=&quot;http://github.com/wycats&quot;&gt;Wycats&lt;/a&gt; and &lt;a href=&quot;http://github.com/ivey&quot;&gt;Ivey&lt;/a&gt; lead the development while many other contributors have commit rights to the different repos.&lt;/p&gt;

&lt;p&gt;Patches are handled via &lt;a href=&quot;http://github.com&quot;&gt;GitHub pull Request&lt;/a&gt; and &lt;a href=&quot;http://merb.lighthouseapp.com/&quot;&gt;LightHouse tickets&lt;/a&gt;. Read the following &lt;a href=&quot;http://merbivore.com/contribute.html&quot;&gt;contribution documentation&lt;/a&gt; for more info.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://www.music-lyrics-chord.com/cover/Vanilla_Ice_Cool_as_Ice.jpg&quot; alt=&quot;vanilla ice&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Anyway, I've been working on a &lt;a href=&quot;http://github.com/wycats/merb-more&quot;&gt;merb-more&lt;/a&gt; gem called &lt;a href=&quot;http://github.com/wycats/merb-more/tree/master/merb-freezer&quot;&gt;merb-freezer&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We don't have a logo for the plugin yet so I picked a &quot;cool&quot; star from the late 80's to represent.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Vanilla Ice!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&amp;lt;object height=&quot;355&quot; width=&quot;425&quot;&gt;&amp;lt;param&gt;&amp;lt;/param&gt;&amp;lt;param&gt;&amp;lt;/param&gt;&amp;lt;embed src=&quot;http://www.youtube.com/v/Vp-is6S_b_g&amp;amp;amp;hl=en&quot; height=&quot;355&quot; width=&quot;425&quot;&gt;&amp;lt;/embed&gt;&amp;lt;/object&gt;&lt;/p&gt;

&lt;p&gt;Right, so you might wonder what's the connection between a &lt;a href=&quot;http://en.wikipedia.org/wiki/Kitsch&quot;&gt;kitsch&lt;/a&gt; white rapper and a new &lt;a href=&quot;merbivore&quot;&gt;Merb&lt;/a&gt; Gem? Not much, apart that they are both cool (or kinda cool).&lt;/p&gt;

&lt;p&gt;Let's forget about &quot;ice ice Baby&quot; and focus on &lt;a href=&quot;http://github.com/wycats/merb-more/tree/master/merb-freezer&quot;&gt;merb-freezer&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://github.com/wycats/merb-more/tree/master/merb-freezer&quot;&gt;merb-freezer&lt;/a&gt; has a simple goal: let you &quot;freeze&quot; your application and run it without dependencies. &lt;/p&gt;

&lt;h2&gt;Why would you want to freeze your app?&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;(This is only valid for Merb 0.9.3 and 0.9.2 edge as of April 14)&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;You might have multiple applications on the same server/slice/cluster. Different applications might require different versions of Merb or some other Merb gems.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You might work with a team of developers and want everyone to be using the same version of the gems.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You are using Merb Edge and want to make sure that your coworkers are developing/testing against the same revision.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;How to freeze your app?&lt;/h2&gt;

&lt;p&gt;First thing, in your init.rb file you need to require merb-freezer&lt;/p&gt;

&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;require &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;merb-freezer&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;Now that you required the plugin when you get new rake tasks:&lt;/p&gt;

&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;  rake freeze&lt;span class=&quot;sy&quot;&gt;:core&lt;/span&gt;            &lt;span class=&quot;c&quot;&gt;# Freeze core from git://github.com/wycats/merb...&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  rake freeze&lt;span class=&quot;sy&quot;&gt;:more&lt;/span&gt;            &lt;span class=&quot;c&quot;&gt;# Freeze more from git://github.com/wycats/merb...&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  rake freeze&lt;span class=&quot;sy&quot;&gt;:plugins&lt;/span&gt;         &lt;span class=&quot;c&quot;&gt;# Freeze plugins from git://github.com/wycats/m...&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;The rake freeze tasks use by default git submodules to freeze the various components. That means that you need to have your project under git to use that feature. However, if you didn't switch to git yet, do no worry, we have a plan B.&lt;/p&gt;

&lt;p&gt;When you run the freeze tasks a framework directory is created at the root of the folder and the gems are checked out there.&lt;/p&gt;

&lt;p&gt;Not a git user? We thought of you and added an option for you to use rubygems. &lt;/p&gt;

&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;  rake freeze&lt;span class=&quot;sy&quot;&gt;:core&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;MODE&lt;/span&gt;=rubygems&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;When doing that, you are freezing the latest version available on the rubygems server or installed locally.
Note that when using the default mode, you are pulling the latest version of Merb from the official git repo. If you want to do that using rubygems you will need to checkout the git repos locally and install the gems yourself before freezing them.&lt;/p&gt;

&lt;p&gt;Also it's worth noting that you can also do all of that manually, as long as you follow the same conventions you should be fine.&lt;/p&gt;

&lt;h2&gt;How to use the freezing gems?&lt;/h2&gt;

&lt;p&gt;If you are a Rails user, you might expect that Merb uses the frozen gems by default, at least that what I expected. Turns out, it's not the case since Merb avoids too much magic and unless you ask for it, Merb will use the available system gems.&lt;/p&gt;

&lt;p&gt;So how to start a frozen merb app? Easy enough:&lt;/p&gt;

&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;frozen-merb&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;That's it, you can uninstall merb-core from your system and as long as you froze merb-core, you can start your app.&lt;/p&gt;

&lt;h2&gt;How to update a frozen app?&lt;/h2&gt;

&lt;p&gt;simply re-freeze but with the UPDATE=true param&lt;/p&gt;

&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;  rake freeze&lt;span class=&quot;sy&quot;&gt;:core&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;UPDATE&lt;/span&gt;=&lt;span class=&quot;pc&quot;&gt;true&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;This option works for in both modes (rubygems and git submodules).&lt;/p&gt;

&lt;h2&gt;What's next?&lt;/h2&gt;

&lt;p&gt;I'd like to add a locking mechanism that would allow you to force your app to only run on specific versions of few gems. The main advantage of this approach is that you wouldn't need to freeze files in your repo as long as you have the required versions on your machine. &lt;/p&gt;

&lt;p&gt;I would also like to extend the freezer to let you use the submodules to freeze other gems.&lt;/p&gt;

&lt;p&gt;Other suggestions? Found a bug? Want to submit a patch?  Leave me a comment or use &lt;a href=&quot;http://merb.lighthouseapp.com/&quot;&gt;the Merb LightHouse ticketing system&lt;/a&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.railsontherun.com/">
    <author>
      <name>matt</name>
    </author>
    <id>tag:www.railsontherun.com,2008-04-10:872</id>
    <published>2008-04-10T08:10:00Z</published>
    <updated>2008-04-10T08:13:38Z</updated>
    <category term="benchmark"/>
    <category term="merb"/>
    <category term="rails"/>
    <link href="http://www.railsontherun.com/2008/4/10/rails-or-merb-what-s-best-for-you" rel="alternate" type="text/html"/>
    <title>Rails or Merb, what's best for you?</title>
<content type="html">
            &lt;p&gt;&lt;img src=&quot;http://brainspl.at/louiecon.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;If you follow my blog, you already know what &lt;a href=&quot;http://merbivore.com&quot;&gt;Merb&lt;/a&gt; is.&lt;/p&gt;

&lt;p&gt;I love Rails and I truly believe it has changed web development. At least it has changed the way I do web development. &lt;/p&gt;

&lt;p&gt;But Merb looks slick, apparently is way faster than Rails, and has less &quot;fluff&quot; and less magic. &lt;/p&gt;

&lt;p&gt;Now that we are getting really close to a Merb 1.0 (scheduled for Rails Conf '08) it's time to evaluate if Merb is the good choice for some of my clients' projects.&lt;/p&gt;

&lt;p&gt;However, according to Merb's author, Ezra, at MountainWest RubyConf 2008, &lt;a href=&quot;http://mwrc2008.confreaks.com/02zygmuntowicz.html&quot;&gt;Rails will get you there faster&lt;/a&gt;. In a client's case, they don't need to build a huge app but need a lot of speed and the ability to easily handle a heavy load right away without using caching. Also most of the traffic will go through an API so we won't have to manage too many views.&lt;/p&gt;

&lt;h2&gt;Let's see how fast Merb really is.&lt;/h2&gt;

&lt;p&gt;To test Merb's speed, I built the very same prototype using Merb 0.9.2 and Rails Edge (pre 2.1). Both apps use ActiveRecord and are connected to a UTF8 MySQL database, both apps have exactly the same views. (Note that Merb would run way faster using DataMapper, but I don't feel that DM 0.9x is production ready yet, also, using a rack handler would certainly be way faster but my goal was really to compare ActionPack vs Merb.)&lt;/p&gt;

&lt;p&gt;Both apps use the same ActiveRecord class, their controllers are a bit different but basically do the same thing.&lt;/p&gt;

&lt;p&gt;Here is what was tested:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The Merb/Rails app should receive a GET request with a JSON object in the query. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Merb/Rails app should route the request to a controller and pass the JSON object to an AR class.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The AR class should parse the JSON object (which contains an array of objects), extract each object, and try to find them in the database using one of the attributes. If the object isn't found, it should be created, otherwise it should return the AR object. The amount of hits should be incremented by 1 and the object should be saved back to the database.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A simple HTML view should be rendered&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Quick Merb benchmark&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;http://merbivore.com/img/header_logo.png&quot; alt=&quot;merb&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I setup Merb to run locally on my MacBook 2.16Ghz Core Duo 2, 2Gb Ram. To test the raw performance, Merb is started in production mode.&lt;/p&gt;

&lt;p&gt;I then used httperf to make 10000 connections to the server at a rate of 500 (--rate=500 --send-buffer=4096 --recv-buffer=16384 --num-conns=10000 --num-calls=1)&lt;/p&gt;

&lt;p&gt;Here are the results:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Maximum connect burst length: 29
Total: connections 4377 requests 4221 replies 2932 test-duration 41.629 s
Connection rate: 105.1 conn/s (9.5 ms/conn, &amp;lt;=1022 concurrent connections)
Connection time [ms]: min 41.0 avg 1920.4 max 35390.8 median 898.5 stddev 4887.3
Connection time [ms]: connect 2118.1
Connection length [replies/conn]: 1.000

Request rate: 101.4 req/s (9.9 ms/req)
Request size [B]: 321.0

*Reply rate [replies/s]: min 0.0 avg 73.3 max 143.0 stddev 65.8 (8 samples)*
Reply time [ms]: response 809.0 transfer 18.1
Reply size [B]: header 121.0 content 557.0 footer 0.0 (total 678.0)
*Reply status: 1xx=0 2xx=2932 3xx=0 4xx=0 5xx=0*

CPU time [s]: user 0.35 system 36.54 (user 0.8% system 87.8% total 88.6%)
Net I/O: 78.4 KB/s (0.6*10^6 bps)

Errors: total 7068 client-timo 0 socket-timo 0 connrefused 0 connreset 1445
Errors: fd-unavail 5623 addrunavail 0 ftab-full 0 other 0
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;What we care about is the reply rate/s. We have an average of &lt;em&gt;73.3 requests per second&lt;/em&gt; with a standard deviation of 65.8 using 8 samples.&lt;/p&gt;

&lt;p&gt;We also make sure that all the replies were successful. (status == 2xx)&lt;/p&gt;

&lt;p&gt;I also checked the database, made sure my AR object was created and that the hits were increased. AR object hits: 2932, which matches the amount of replies reported by httperf.&lt;/p&gt;

&lt;p&gt;We don't care so much about the rest of the httperf. Let's move on to the Rails benchmark.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2&gt;Quick Rails benchmark&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;http://www.rubyonrails.org/images/rails.png&quot; alt=&quot;rails&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Rails is set the same way, running locally in production mode, same httperf settings.&lt;/p&gt;

&lt;p&gt;Here are the results:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Maximum connect burst length: 44

Total: connections 2923 requests 2825 replies 1672 test-duration 37.418 s

Connection rate: 78.1 conn/s (12.8 ms/conn, &amp;lt;=1022 concurrent connections)
Connection time [ms]: min 382.7 avg 5635.4 max 36384.5 median 1887.5 stddev 10103.1
Connection time [ms]: connect 3631.2
Connection length [replies/conn]: 1.000

Request rate: 75.5 req/s (13.2 ms/req)
Request size [B]: 319.0

*Reply rate [replies/s]: min 0.0 avg 43.4 max 75.2 stddev 30.8 (7 samples)*
Reply time [ms]: response 1568.1 transfer 36.7
Reply size [B]: header 471.0 content 581.0 footer 0.0 (total 1052.0)
*Reply status: 1xx=0 2xx=1672 3xx=0 4xx=0 5xx=0*

CPU time [s]: user 0.25 system 31.31 (user 0.7% system 83.7% total 84.4%)
Net I/O: 69.4 KB/s (0.6*10^6 bps)

DB hits: 1672
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;First thing, the database object was created properly and the hits incremented to 1672 which matches the amount of replies reported by httperf.&lt;/p&gt;

&lt;p&gt;Then, we notice that on this test, we only got 7 samples, that's more than enough though. The standard deviation is 30.8 which is better than Merb's 65.8. That means that in our benchmarks, the reply speed difference in Merb's requests was bigger than Rails'. Not a big deal, this is not a scientific test but it's good to acknowledge it.&lt;/p&gt;

&lt;p&gt;What we really care about is the average reply rate: 43.4&lt;/p&gt;

&lt;p&gt;Let's also note that all the replies had a 2xx status, so everything went well.&lt;/p&gt;

&lt;h2&gt;Results&lt;/h2&gt;

&lt;p&gt;Based on this really basic benchmark, my Merb app had an average reply rate of &lt;em&gt;73.3 requests per second&lt;/em&gt; against Rails' &lt;em&gt;43.4 requests per second&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;That means that in this very specific case, &lt;/p&gt;

&lt;h2&gt;&lt;em&gt;Merb is 69% faster than Rails&lt;/em&gt;!  Sexy! &lt;/h2&gt;

&lt;p&gt;In other words, my Merb prototype could handle 69% more requests than the Rails prototype in the same amount of time.&lt;/p&gt;

&lt;p&gt;I heard people reporting than Merb was 3 to 5 times faster than Rails. Honestly, it really depends on what you do. By using ActiveRecord on both prototypes, I limited the speed difference since AR is not multithread and therefore Merb can't run as fast as it would using Sequel or DataMapper. By actually hitting the database on every single request, I also made sure to really compare ActionPack vs Merb.&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;The conclusion is simple, I recommended that my client go with Merb. Merb 1.0 is almost ready, the public API has been frozen. My client needs speed and simplicity. Using Merb I get exactly what I need and nothing more. Actually, we'll probably increase the performance by writing a rack handler and bypassing the entire framework for API calls (that should be wicked fast!).  Also, as soon as DataMapper becomes production ready, we'll switch to DM and should get way better performance!&lt;/p&gt;

&lt;p&gt;Am I suggesting to give up Rails and switch to Merb?
Absolutely not!  First off, Merb is a &quot;lower level&quot; framework. It requires a deeper understanding of Web Development in general and being more than just 'acquainted' with the Ruby language. So, unless you are an advanced developer or have time to learn, I would suggest to keep on using Rails (start using Merb on personal projects, it's a perfect way of learning).
If you have a lot of views and/or use loads of AJAX, RJS, built-in helpers, you probably want to stick to Rails and start looking at how you can do all of that from scratch. By default Rails uses nasty helpers that create inline javascript, and is something you really want to avoid. RJS is fun, but it goes against Merb's philosophy, so you need to make sure you can live without it (note that you can reproduce the same behavior in Merb rendering JS, it just requries more work). If you rely a lot of Rails plugins, you might want to delay your switch, Merb is pretty new and doesn't have a mass-load of plugins yet.&lt;/p&gt;

&lt;p&gt;Finally, Merb doesn't have a lot of documentation and changed a lot when 0.9 got released. To understand how Merb works, you will need to go through the source code, specs, Google, and ask on the Merb IRC channel.&lt;/p&gt;

&lt;p&gt;It turns out that in our case we have experienced developers, a great need for speed, not too many views and are following Merb's development really closely . I honestly think it's the best choice for my client and I'm excited they accepted to use Merb.&lt;/p&gt;

&lt;p&gt;Merb is addressing different issues than Rails and doing it well. I think there is a bright future for Merb. And don't even think that Rails is going away, that won't happen anytime soon! &lt;/p&gt;

&lt;p&gt;Recently, &lt;a href=&quot;http://www.us.playstation.com/Corporate/About&quot;&gt;Sony Playstation&lt;/a&gt; even posted a &lt;a href=&quot;https://www2.recruitingcenter.net/Clients/playstation/PublicJobs/controller.cfm?jbaction=JobProfile&amp;amp;amp;Job_Id=11424&amp;amp;amp;esid=az&quot;&gt;job post&lt;/a&gt; looking for a Rails/Merb developer. This is very promising for the Merb community!&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.railsontherun.com/">
    <author>
      <name>matt</name>
    </author>
    <id>tag:www.railsontherun.com,2008-04-08:865</id>
    <published>2008-04-08T02:11:00Z</published>
    <updated>2008-04-08T02:12:52Z</updated>
    <category term="logger"/>
    <category term="merb"/>
    <category term="routes"/>
    <category term="tips"/>
    <category term="tricks"/>
    <link href="http://www.railsontherun.com/2008/4/8/merb-tips-2" rel="alternate" type="text/html"/>
    <title>Merb tips II</title>
<content type="html">
            &lt;p&gt;I the &lt;a href=&quot;http://railsontherun.com/2008/4/5/merb-tips-1&quot;&gt;previous post&lt;/a&gt; I covered few useful tips for Merb 0.9. The good news is that Merb should get its wiki setup over the week end!&lt;/p&gt;

&lt;p&gt;Here is another batch of hopefully useful tips:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;In init.rb, you can define a dependency and specify a version number: &lt;em&gt;dependency &quot;merb_fu&quot;, &quot;&gt;= 1.0&quot;&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If you want to run your application from a subdirectory, once again, in your init.rb file, add: &lt;em&gt;c[:path_prefix] = &quot;/your_prefix&quot;&lt;/em&gt; &lt;em&gt;(note, that you can also do that in a specific environment file.)&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You feel like limiting a route to a specific request such as a DELETE? In your router.rb file add the following:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;  r.match(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;/:bucket_id&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;sy&quot;&gt;:method&lt;/span&gt; =&amp;gt; &lt;span class=&quot;sy&quot;&gt;:delete&lt;/span&gt;).to(&lt;span class=&quot;sy&quot;&gt;:controller&lt;/span&gt; =&amp;gt; &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;buckets&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;sy&quot;&gt;:action&lt;/span&gt; =&amp;gt; &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;destroy&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;ul&gt;
&lt;li&gt;Since we are talking about routes, what about an iPhone only route?&lt;/li&gt;
&lt;/ul&gt;

&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;  r.match(&lt;span class=&quot;rx&quot;&gt;&lt;span class=&quot;dl&quot;&gt;%r[&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;^/(.+)&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;]&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;sy&quot;&gt;:user_agent&lt;/span&gt; =&amp;gt; &lt;span class=&quot;rx&quot;&gt;&lt;span class=&quot;dl&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;iPhone&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;/&lt;/span&gt;&lt;/span&gt;).to(&lt;span class=&quot;sy&quot;&gt;:controller&lt;/span&gt; =&amp;gt; &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;mobile&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;sy&quot;&gt;:title&lt;/span&gt; =&amp;gt; &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Welcome Apple FanBoy&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;sy&quot;&gt;:action&lt;/span&gt; =&amp;gt; &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;show&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;ul&gt;
&lt;li&gt;what about an admin section for my blogposts?&lt;/li&gt;
&lt;/ul&gt;

&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;  r.match(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;/admin&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;) &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt; |admin|&lt;tt&gt;
&lt;/tt&gt;    admin.resources &lt;span class=&quot;sy&quot;&gt;:blogposts&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;ul&gt;
&lt;li&gt;To finish with the routes, look at the &lt;a href=&quot;http://github.com/wycats/merb-core/tree/master/spec/public/router/special_spec.rb#L39-46&quot;&gt;following merb-core spec&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;  it &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;should allow you to restrict routes based on protocol&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;co&quot;&gt;Merb&lt;/span&gt;::&lt;span class=&quot;co&quot;&gt;Router&lt;/span&gt;.prepare &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt; |r|&lt;tt&gt;
&lt;/tt&gt;      r.match(&lt;span class=&quot;sy&quot;&gt;:protocol&lt;/span&gt; =&amp;gt; &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;http://&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;).to(&lt;span class=&quot;sy&quot;&gt;:controller&lt;/span&gt; =&amp;gt; &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;sy&quot;&gt;:action&lt;/span&gt; =&amp;gt; &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;bar&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;      r.default_routes&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    route_to(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;/foo/bar&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;).should have_route(&lt;span class=&quot;sy&quot;&gt;:controller&lt;/span&gt; =&amp;gt; &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;sy&quot;&gt;:action&lt;/span&gt; =&amp;gt; &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;bar&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;    route_to(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;/boo/hoo&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;sy&quot;&gt;:protocol&lt;/span&gt; =&amp;gt; &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;https://&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;).should have_route(&lt;span class=&quot;sy&quot;&gt;:controller&lt;/span&gt; =&amp;gt; &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;boo&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;sy&quot;&gt;:action&lt;/span&gt; =&amp;gt; &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;hoo&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;You can set custom routes to only work when connected via SSL, that's just really nice!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Other quick tip. &lt;a href=&quot;http://railsontherun.com/2008/4/5/merb-tips-1&quot;&gt;Last time&lt;/a&gt; we saw how to install locally all the required gems. Well, you can also freeze merb by doing:&lt;/li&gt;
&lt;/ul&gt;

&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;  merb-gen frozen-merb&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;ul&gt;
&lt;li&gt;Another common IRC question, how do I use Merb's logger. It's really easy:&lt;/li&gt;
&lt;/ul&gt;

&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;co&quot;&gt;Merb&lt;/span&gt;.logger.info(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;our stuff&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;Where info is the debugging level you want to send your message to.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Finally, today in IRC a Rails user asked how reset a session in Merb. Rails has a &lt;em&gt;reset_session&lt;/em&gt; method that resets the session by clearing out all the objects stored within and initializing a new session object. Merb simply uses a hash to store sessions, so &lt;em&gt;session.clear&lt;/em&gt; will do it ;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Feel free to add a comment with your Merb tips or leave a question regarding something you can't seem to be able to do with Merb.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.railsontherun.com/">
    <author>
      <name>matt</name>
    </author>
    <id>tag:www.railsontherun.com,2008-04-05:851</id>
    <published>2008-04-05T05:59:00Z</published>
    <updated>2008-04-21T06:05:37Z</updated>
    <category term="logger"/>
    <category term="merb"/>
    <category term="tricks"/>
    <link href="http://www.railsontherun.com/2008/4/5/merb-tips-1" rel="alternate" type="text/html"/>
    <title>Merb tips I</title>
<content type="html">
            &lt;p&gt;I'm working on a post reporting a recent benchmark I did comparing Rails vs Merb performances for a client's app.&lt;/p&gt;

&lt;p&gt;In the meantime, here are few tricks you might need when using Merb 0.9x&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;In the init.rb file, uncomment and rename &lt;em&gt;c[:session_id_key]&lt;/em&gt;  (in the Merb::Config.use block)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the same block, add &lt;em&gt;c[:log_level] = :debug&lt;/em&gt;  to set a log level&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;By default, Merb logs to STDOUT, to log to a file, in the config block add &lt;em&gt;c[:log_file] = Merb.log_path + '/development.log'&lt;/em&gt;  (note that you need to create the file yourself, Merb won't do that)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;to save your gems locally, do: &lt;em&gt;sudo gem install gem_name -i gems&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;need basic HTTP auth? &lt;a href=&quot;http://github.com/wycats/merb-core/tree/e690bb81bb550e58dad519712de050141b8552d8/lib/merb-core/controller/mixins/authentication.rb#L15-46&quot;&gt;it's now available in core&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;don't forget to require any plugins, extra gems you need (such as &lt;em&gt;merb_helpers&lt;/em&gt; or &lt;em&gt;merb-assets&lt;/em&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;don't forget to select your ORM before using the generator( so your generated goodies will be adapted to your ORM)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;routes are easy to use. In the console (merb -i) type &lt;em&gt;merb.show_routes&lt;/em&gt; to see all your named routes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;if you want to use link&lt;em&gt;to, install &lt;a href=&quot;http://github.com/wycats/merb-plugins/tree/master/merb_assets&quot;&gt;merb&lt;/em&gt;assets&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;nested routes example:&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;  r.resources &lt;span class=&quot;sy&quot;&gt;:channels&lt;/span&gt; &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt; |channels|&lt;tt&gt;
&lt;/tt&gt;    channels.resources &lt;span class=&quot;sy&quot;&gt;:shows&lt;/span&gt; &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt; |shows|&lt;tt&gt;
&lt;/tt&gt;     shows.resources &lt;span class=&quot;sy&quot;&gt;:episodes&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;   &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;usage: &lt;/p&gt;

&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;  url(&lt;span class=&quot;sy&quot;&gt;:channel_shows&lt;/span&gt;, &lt;span class=&quot;sy&quot;&gt;:channel_id&lt;/span&gt; =&amp;gt; channel)&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  link_to h(channel.description), url(&lt;span class=&quot;sy&quot;&gt;:channel&lt;/span&gt;, &lt;span class=&quot;sy&quot;&gt;:id&lt;/span&gt; =&amp;gt; channel)&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;That's it for today :)&lt;/p&gt;

&lt;p&gt;In the meantime, check this &lt;a href=&quot;http://mwrc2008.confreaks.com/02zygmuntowicz.html&quot;&gt;Merb presentation by Ezra&lt;/a&gt; and &lt;a href=&quot;http://mwrc2008.confreaks.com/04katz.html&quot;&gt;this DataMapper presentation by Wycats&lt;/a&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.railsontherun.com/">
    <author>
      <name>matt</name>
    </author>
    <id>tag:www.railsontherun.com,2008-03-21:800</id>
    <published>2008-03-21T06:59:00Z</published>
    <updated>2008-03-21T06:59:57Z</updated>
    <category term="community"/>
    <category term="duplo"/>
    <category term="plugins"/>
    <category term="rails"/>
    <link href="http://www.railsontherun.com/2008/3/21/how-duplo-and-i-offended-people" rel="alternate" type="text/html"/>
    <title>How Duplo (and I) offended people</title>
<content type="html">
            &lt;p&gt;My &lt;a href=&quot;http://railsontherun.com/2008/3/17/rails-the-duplo-generation&quot;&gt;recent and certainly provocative post&lt;/a&gt; generated a lot of noise. Just by reading some of the &lt;a href=&quot;http://railsontherun.com/2008/3/17/rails-the-duplo-generation#comments&quot;&gt;comments&lt;/a&gt; on my blog or on &lt;a href=&quot;http://reddit.com/r/ruby/info/6cbwo/comments/&quot;&gt;reddit&lt;/a&gt; I could only notice that some people took offense and some people tried to push the metaphor way too far. At the same time, it generated a lot of interesting discussions even &lt;a href=&quot;http://msforums.ph/forums/p/47347/226547.aspx&quot;&gt;outside&lt;/a&gt; of our &lt;em&gt;small&lt;/em&gt; Ruby community.&lt;/p&gt;

&lt;h2&gt;A few clarifications:&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Rails is an awesome framework, and to be honest I really like the fact that it's accessible to newbies while offering great tools&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Rails Plugins that I like calling Duplo blocks are great and I use a bunch in most of my projects&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I, myself wrote a bunch of &lt;a href=&quot;http://github.com/matta/&quot;&gt;plugins and gems&lt;/a&gt; never as great as the one mentioned in &lt;a href=&quot;http://railsontherun.com/2008/3/17/rails-the-duplo-generation&quot;&gt;my post&lt;/a&gt; though&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No, I don't think you are dumb if you don't have a clue how Rails or Rails plugins work&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I also agree that the &lt;img src=&quot;http://cache.lego.com/upload/contentTemplating/LifestyleProductsBags/otherfiles/1033/uploadF2767709-6EFA-4D99-93FA-13F75766309B.jpg&quot; alt=&quot;Duplo&quot; /&gt; metaphor is very limited and doesn't stretch... but who cares.. it's funny.&lt;/p&gt;

&lt;h2&gt;&lt;em&gt;What did I mean to say&lt;/em&gt;&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Rails plugins are useful, use them and &lt;em&gt;ABUSE&lt;/em&gt; them. Even though most of them are very well written I strongly believe you would become a better developer if you understand how they work.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A &lt;em&gt;Duplo&lt;/em&gt; doesn't do exactly what you want it to do, don't &lt;em&gt;bitch&lt;/em&gt; about it. Try submitting a patch or if you can write your own plugin.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If you are using a plugin on a regular basis, give it some love. Submit some documentation, write a blog post, send a thank you email.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A great framework and a bunch of nice plugins are awesome tools for developers but they won't replace your brain.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, there you go, this time around I tried to be more straight forward and I even apologize if I offended you.&lt;/p&gt;

&lt;p&gt;Finally, I don't believe the Rails community is a bunch of &lt;em&gt;obnoxious-arrogant-wannabe-rockstars&lt;/em&gt;, and certainly not a ghetto. We all started as newbies and I hope a lot of newbies will join the fun and learn through Rails and later provide the community with a lot of awesome Duplos!&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.railsontherun.com/">
    <author>
      <name>matt</name>
    </author>
    <id>tag:www.railsontherun.com,2008-03-17:755</id>
    <published>2008-03-17T06:39:00Z</published>
    <updated>2008-03-17T07:19:57Z</updated>
    <category term="community"/>
    <category term="duplo"/>
    <category term="lego"/>
    <category term="plugins"/>
    <category term="rails"/>
    <link href="http://www.railsontherun.com/2008/3/17/rails-the-duplo-generation" rel="alternate" type="text/html"/>
    <title>Ruby on Rails: the Duplo generation</title>
<content type="html">
            &lt;p&gt;&lt;img src=&quot;http://cache.lego.com/upload/contentTemplating/LifestyleProductsBags/otherfiles/1033/uploadF2767709-6EFA-4D99-93FA-13F75766309B.jpg&quot; alt=&quot;duplo&quot; /&gt;
I'm sure, at least once in your life you played with Duplos. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Duplo bricks are eight times the size in volume, twice the length, height and width of traditional Lego bricks, and are &lt;strong&gt;easier to handle for younger children&lt;/strong&gt;. Despite their size, they are &lt;strong&gt;still compatible&lt;/strong&gt; with traditional Lego brick.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Duplos are great to introduce kids to the concept of Lego bricks and to get them to think about building their own creations. However you would freak out if your kid would grow up and not want to start playing with Legos and building more advanced/custom stuff.&lt;/p&gt;

&lt;p&gt;Unfortunately, that's exactly what's going on in the Rails community right now. We created a generation of Duplo developers. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rick Olson&lt;/strong&gt;, AKA &lt;a href=&quot;http://techno-weenie.net/&quot;&gt;Technoweenie&lt;/a&gt; fathered a great majority of this Duplo generation. Rick is a Rails core member and a prolific Rails plugin developer. He has written very popular plugins and Rails apps such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://github.com/technoweenie/restful-authentication/tree&quot;&gt;restful-authentication&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://github.com/technoweenie/attachment_fu/tree&quot;&gt;attachment_fu&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://github.com/technoweenie/acts_as_versioned/tree&quot;&gt;acts_as_versioned&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://github.com/technoweenie/permalink_fu/tree&quot;&gt;permalink_fu&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://mephistoblog.com/&quot;&gt;mephisto blog engine&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://beast.caboo.se/&quot;&gt;Beast forum&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If Rick is the father, the mother of this generation would obviously be &lt;a href=&quot;http://www.loudthinking.com/&quot;&gt;David Heinemeier Hansson&lt;/a&gt;, creator of the Ruby on Rails framework. David has always wanted to make our lives easier, providing us with tools to avoid repeating ourselves and a mass-load of tools to create web apps in no time.&lt;/p&gt;

&lt;p&gt;Rick, David and others worked hard to provide the community with tools that cut our development times by 20% to 30% and that's just awesome. They basically took their &lt;a href=&quot;http://www.meccano.com/&quot;&gt;meccano&lt;/a&gt; applications and extracted Duplo blocks you can play with.&lt;/p&gt;

&lt;p&gt;from &lt;img src=&quot;http://upload.wikimedia.org/wikipedia/en/thumb/b/b5/Meccano_model_Steam_shovel_excavator.jpg/250px-Meccano_model_Steam_shovel_excavator.jpg&quot; alt=&quot;meccano&quot; /&gt; to &lt;img src=&quot;http://upload.wikimedia.org/wikipedia/en/thumb/e/eb/Duplo_bricks.jpg/250px-Duplo_bricks.jpg&quot; alt=&quot;Duplo&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The problem is that a generation of Rubyists has grown up being used to getting everything pre written for them. They haven't yet passed the &quot;Duplo stage&quot; and basically write applications putting a few blocks together, only writing 10 to 20% and barely understand 5%.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;On top of that, what really annoys me is that, these very same developers complain about the existing plugins, always ask for more and don't give anything back to the community.&lt;/p&gt;

&lt;p&gt;The problem is that it's always the same people giving and helping. Relatively quickly, the community grows and people supporting it get tired. I won't go as far as &lt;a href=&quot;http://www.zedshaw.com/rants/rails_is_a_ghetto.html&quot;&gt;Zed and his funny rant&lt;/a&gt; but we need to wake up. We need to evolve, learn how Rails magic works, give up the &lt;a href=&quot;http://www.therailsway.com/2007/8/1/dangers-of-cargo-culting&quot;&gt;cargo culting&lt;/a&gt; and start giving back.&lt;/p&gt;

&lt;p&gt;The first thing would be to stop complaining about plugins you use on a daily basis and write your own or fork existing ones. &lt;a href=&quot;http://github.com&quot;&gt;GitHub&lt;/a&gt; is a good place to start forking existing projects, if you are a Rails/Ruby beginner, you can help with documentation or submit small patches. &lt;a href=&quot;http://hasmanythrough.com&quot;&gt;Josh Susser&lt;/a&gt; wrote a &lt;a href=&quot;http://hasmanythrough.com/layingtracks/LayingTracks.pdf&quot;&gt;nice tutorial&lt;/a&gt; on how to commit changes (patches/documentation).&lt;/p&gt;

&lt;p&gt;Why not blog about issues you have just faced and how you resolved them. Start writing small plugins/gems. Try helping people on the various mailing lists. &lt;/p&gt;

&lt;p&gt;And finally, drop the Duplos and start playing with Legos - don't use plugins just because they are available to you, make sure you fully understand what the plugins you use do! Learn more about Rails guts and start using it in a way that makes sense to you.&lt;/p&gt;

&lt;p&gt;Why not even switch to meccano and take a look at &lt;a href=&quot;http://merbivore.com&quot;&gt;Merb&lt;/a&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.railsontherun.com/">
    <author>
      <name>matt</name>
    </author>
    <id>tag:www.railsontherun.com,2008-03-05:682</id>
    <published>2008-03-05T07:48:00Z</published>
    <updated>2008-03-05T07:52:49Z</updated>
    <category term="git"/>
    <category term="plugins"/>
    <category term="projects"/>
    <link href="http://www.railsontherun.com/2008/3/5/starting-the-migration-to-github" rel="alternate" type="text/html"/>
    <title>starting the migration to GitHub</title>
<content type="html">
            &lt;p&gt;I started moving some of my projects to &lt;a href=&quot;http://github.com&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://github.com/matta&quot;&gt;Here&lt;/a&gt; is my &lt;a href=&quot;http://github.com&quot;&gt;GitHub&lt;/a&gt; account.&lt;/p&gt;

&lt;p&gt;Projects moved to &lt;a href=&quot;http://github.com&quot;&gt;GitHub&lt;/a&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&quot;http://github.com/matta/globalite/tree&quot;&gt;GlobaLite&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&quot;http://github.com/matta/ar-backup/tree&quot;&gt;ActiveRecord Backup&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&quot;http://github.com/matta/mimetype-fu/tree&quot;&gt;mimetype-fu&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'm planning on moving &lt;a href=&quot;http://rubyforge.org/projects/googlecharts/&quot;&gt;GoogleCharts&lt;/a&gt;, &lt;a href=&quot;http://rubyforge.org/projects/random-word-gen/&quot;&gt;RandomWordGenerator&lt;/a&gt; and some not released stuff to GitHub so people can have fun forking my projects.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://git.or.cz/&quot;&gt;Git&lt;/a&gt; and &lt;a href=&quot;http://github.com&quot;&gt;GitHub&lt;/a&gt; are the new cool things. GitHub is planning on setting up a gem server while they are already offering tarball download and a post-receive hook. (they also plan on becoming myspace for geeks, but that's another story)&lt;/p&gt;

&lt;p&gt;Do you have to switch to git and github? Honestly, ...no you don't.. 
Git can act as SVN, but let's be honest, if you switch to a new SCM it needs to do more. I've been using Git for a couple of months and even though I still don't have a full understanding of this SCM, I really enjoy using it.&lt;/p&gt;

&lt;p&gt;So, get over it, learn on your own or purchase &lt;a href=&quot;https://peepcode.com/products/git&quot;&gt;this excellent peepcode&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Email me to get a GitHub invite (Tom and Chris gave me some invites for readers) or/and try &lt;a href=&quot;http://gitorious.org/&quot;&gt;Gitorious&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The fact that some major players (&lt;a href=&quot;http://topfunky.com/&quot;&gt;Topfunky&lt;/a&gt;, &lt;a href=&quot;http://weblog.techno-weenie.net/2008/3/4/my-gushing-github-love-letter&quot;&gt;technoweenie&lt;/a&gt;, &lt;a href=&quot;http://errtheblog.com/&quot;&gt;Chris &amp;amp; PJ&lt;/a&gt;, &lt;a href=&quot;http://railstips.org/2008/2/16/git-and-github/&quot;&gt;jnunemaker&lt;/a&gt; and major projects such as &lt;a href=&quot;http://weblog.rubyonrails.com/2008/2/28/capistrano-2-2-0&quot;&gt;capistrano&lt;/a&gt;, &lt;a href=&quot;http://rubyhitsquad.com/Vlad_the_Deployer.html&quot;&gt;vlad the deployer&lt;/a&gt; and &lt;a href=&quot;http://merbivore.com&quot;&gt;Merb&lt;/a&gt; use and support Git is a sign that it's the next big thing. &lt;/p&gt;

&lt;p&gt;Also, I believe that a lot of developers will also be motivated to move their plugins/gems to GitHub because they simply can't always maintain their own libs and/or just hope people will fork their project and contribute back.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.railsontherun.com/">
    <author>
      <name>matt</name>
    </author>
    <id>tag:www.railsontherun.com,2008-03-03:668</id>
    <published>2008-03-03T08:22:00Z</published>
    <updated>2008-06-18T02:32:34Z</updated>
    <category term="contribute"/>
    <category term="git"/>
    <category term="github"/>
    <category term="merb"/>
    <link href="http://www.railsontherun.com/2008/3/3/how-to-use-github-and-submit-a-patch" rel="alternate" type="text/html"/>
    <title>How to use github and submit a patch</title>
<content type="html">
            &lt;p&gt;If you don't know about &lt;a href=&quot;http://git.or.cz/&quot;&gt;git&lt;/a&gt; and &lt;a href=&quot;http://github.com&quot;&gt;github&lt;/a&gt; yet, it's time you clean up your RSS feeds and find some good source of information.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://github.com&quot;&gt;Github&lt;/a&gt; is used by the &lt;a href=&quot;http://merbivore.com&quot;&gt;Merb core team&lt;/a&gt; and I'll show you how to use github to fork Merb, make your modifications and &quot;submit your patch&quot;.&lt;/p&gt;

&lt;p&gt;This is the exact reason why github is simply awesome, it makes forking projects just super simple and submitting changes even easier.&lt;/p&gt;

&lt;p&gt;First thing, you need to have a github account, if you don't have one yet, email me, I have a couple of invitations left, otherwise, just wait until github gets public.&lt;/p&gt;

&lt;p&gt;Now, let's go to &lt;a href=&quot;http://github.com/wycats/merb-core/tree/master&quot;&gt;Merb's repository&lt;/a&gt; and fork Merb-core by clicking on the fork button.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://img.skitch.com/20080303-q2aceaadcqk59kqck4b199bdmh.jpg&quot; alt=&quot;fork merb&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Actually, for this example, I'll fork &lt;a href=&quot;http://github.com/wycats/merb-plugins/tree/master&quot;&gt;merb-plugins&lt;/a&gt; because I want to improve the ActiveRecord rake tasks.&lt;/p&gt;

&lt;p&gt;Because I forked merb-plugins, I now have my own forked repo: !&lt;img src=&quot;http://img.skitch.com/20080303-g8jas46gq1enn9fhu1t7rsyunj.jpg&quot; alt=&quot;my forked repo&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I'll start by checking out/cloning my forked repo locally.&lt;/p&gt;

&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;git clone git&lt;span class=&quot;iv&quot;&gt;@github&lt;/span&gt;.com&lt;span class=&quot;sy&quot;&gt;:mattetti&lt;/span&gt;/merb-plugins.git&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;!&lt;img src=&quot;http://img.skitch.com/20080303-rf87t44c3c6m6hqy5b38ksycua.jpg&quot; alt=&quot;git clone&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Great I can now make my own changes.... but wait, what if the merb core team makes a change to the code? Well, I need to track their changes. Here is how:&lt;/p&gt;

&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;git remote add coreteam git&lt;span class=&quot;sy&quot;&gt;:/&lt;/span&gt;/github.com/wycats/merb-plugins.git&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;FYI, it adds the following to edit .git/config:&lt;/p&gt;

&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;  [remote &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;coreteam&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;]&lt;tt&gt;
&lt;/tt&gt;  url = git&lt;span class=&quot;sy&quot;&gt;:/&lt;/span&gt;/github.com/wycats/merb-plugins.git&lt;tt&gt;
&lt;/tt&gt;  fetch = +refs/heads/*&lt;span class=&quot;sy&quot;&gt;:refs&lt;/span&gt;/remotes/coreteam/*&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;then &lt;/p&gt;

&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;git fetch coreteam&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;and finally&lt;/p&gt;

&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;git checkout -b coreteam coreteam/master&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;You can now track the latest change and merge them with your branch. Note that you can also track other forks and merge some other changes. (just that feature is worth using git)&lt;/p&gt;

&lt;p&gt;Alright, now you can do your stuff, and push your local change to your remote repo at github.&lt;/p&gt;

&lt;p&gt;Once you are done, you can simply click on the &quot;pull request button&quot;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://img.skitch.com/20080303-xxh5d3a2uu65ksf8u4i9tga59e.jpg&quot; alt=&quot;pull request button&quot; /&gt;&lt;/p&gt;

&lt;p&gt;fill up the form and select the recipient. (wycats in this example if you want him to merge your changes into the official version of Merb).&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://img.skitch.com/20080303-dei7bxpt577gqe3d1x4ncpmq6w.jpg&quot; alt=&quot;pull request&quot; /&gt;&lt;/p&gt;

&lt;p&gt;p.s: The github guys are working on a gem to make our loves easier, give &lt;a href=&quot;http://github.com/defunkt/github-gem/tree/master&quot;&gt;http://github.com/defunkt/github-gem/tree/master&lt;/a&gt; a try. I'll post about the gem when it will be a bit more stable.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.railsontherun.com/">
    <author>
      <name>matt</name>
    </author>
    <id>tag:www.railsontherun.com,2008-02-29:648</id>
    <published>2008-02-29T22:40:00Z</published>
    <updated>2008-02-29T22:48:09Z</updated>
    <category term="git"/>
    <category term="git-svn"/>
    <category term="repository"/>
    <category term="scm"/>
    <category term="subversion"/>
    <category term="svn"/>
    <link href="http://www.railsontherun.com/2008/2/29/resolving-git-svn-conflicts" rel="alternate" type="text/html"/>
    <title>resolving git-svn conflict