<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">

 <title>Emmanuel Oga's Blog</title>
 
 <link href="http://emmanueloga.com/" />
 <updated>2011-11-28T15:19:56-08:00</updated>
 <id>http://emmanueloga.com/</id>
 <author>
   <name>Emmanuel Oga</name>
   <email>emmanueloga@gmail.com</email>
 </author>

 
 <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/EmmanuelOga" /><feedburner:info uri="emmanueloga" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry>
   <title>VIM config snippets</title>
   <link href="http://feedproxy.google.com/~r/EmmanuelOga/~3/sy336oxccww/a-small-vim-config-tip.html" />
   <updated>2011-11-28T00:00:00-08:00</updated>
   <id>http://emmanueloga.com/2011/11/28/a-small-vim-config-tip</id>
   <content type="html">&lt;p&gt;There are lots of things you can do to better organize your vim
configuration, starting with using
&lt;a href="http://www.vim.org/scripts/script.php?script_id=2332"&gt;pathogen&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Apart from using pathogen, what I like to do is &lt;em&gt;having small snippets
of configuration on separate files&lt;/em&gt; to tweak specific things. Here's &lt;a href="https://github.com/EmmanuelOga/vimrc/blob/master/vimrc"&gt;my
.vimrc&lt;/a&gt;:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="vim"&gt;&lt;span class="c"&gt;&amp;quot; Setup for pathogen.&lt;/span&gt;
&lt;span class="k"&gt;call&lt;/span&gt; pathogen#runtime_append_all_bundles&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;call&lt;/span&gt; pathogen#&lt;span class="k"&gt;helptags&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c"&gt;&amp;quot; Load additional plugin configurations and stuff&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; rc &lt;span class="k"&gt;in&lt;/span&gt; split&lt;span class="p"&gt;(&lt;/span&gt;globpath&lt;span class="p"&gt;(&lt;/span&gt;&amp;amp;&lt;span class="nb"&gt;rtp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c"&gt;&amp;quot;rc/*&amp;quot;), &amp;quot;\n&amp;quot;)&lt;/span&gt;
  execute &lt;span class="c"&gt;&amp;quot;source&amp;quot; rc&lt;/span&gt;
&lt;span class="k"&gt;endfor&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;First part is the setup for pathogen. The second part is what I'm
talking about, I go through every file in my
&lt;a href="https://github.com/EmmanuelOga/vimrc/tree/master/rc"&gt;.vim/rc&lt;/a&gt; directory
and load every snippet of that folder.&lt;/p&gt;

&lt;p&gt;A fun thing to try is to &lt;em&gt;make every snippet "self contained"&lt;/em&gt;. That
way, if someone browsing your config thinks the thing you are setting up
there is cool, all he has to do is copy that single file to get
the specific piece of functionality.&lt;/p&gt;

&lt;p&gt;BTW, since I use gvim most of the time, on the
&lt;a href="https://github.com/EmmanuelOga/vimrc/blob/master/gvimrc"&gt;.gvimrc&lt;/a&gt; I
just source the .vimrc, plus a few GUI tweaks (removing toolbars, menus,
etc).&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="vim"&gt;source &lt;span class="p"&gt;~&lt;/span&gt;&lt;span class="sr"&gt;/.vim/&lt;/span&gt;vimrc
&lt;span class="c"&gt;&amp;quot; ... some gui settings.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;



&lt;img src="http://feeds.feedburner.com/~r/EmmanuelOga/~4/sy336oxccww" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://emmanueloga.com/2011/11/28/a-small-vim-config-tip.html</feedburner:origLink></entry>
 
 <entry>
   <title>Beer Drinking Contest: Ruby versus Lua. Fight!</title>
   <link href="http://feedproxy.google.com/~r/EmmanuelOga/~3/UDUxpE8CoGM/drinking-contest.html" />
   <updated>2011-07-29T00:00:00-07:00</updated>
   <id>http://emmanueloga.com/2011/07/29/drinking-contest</id>
   <content type="html">&lt;p&gt;Grab a &lt;a href="https://gist.github.com/1113413"&gt;gist&lt;/a&gt;. You probably already
know what's the &lt;a href="http://www.99-bottles-of-beer.net/lyrics.html"&gt;output&lt;/a&gt; of these programs.&lt;/p&gt;

&lt;h3&gt;Ruby&lt;/h3&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Crowd&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Struct&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:bottles&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;drink&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;    &lt;span class="nb"&gt;puts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Take one down and pass it around.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;bottles&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;drink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;buy_more&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Go to the store and buy some more.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;bottles&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;buy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;99&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;sing&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;     &lt;span class="nb"&gt;puts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;bottles&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; on the wall, &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;bottles&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Bottles&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Struct&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:qty&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;drink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;qty&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;buy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;qty&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;to_s&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;qty&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;No more bottles of beer&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;qty&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; bottle&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;s&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;qty&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; of beer&amp;quot;&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="no"&gt;Crowd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Bottles&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;99&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tap&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;crowd&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="mi"&gt;99&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;times&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;crowd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;drink&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;crowd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sing&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;crowd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;buy_more&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sing&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;h3&gt;Lua&lt;/h3&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="lua"&gt;&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;Crowd&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="n"&gt;Crowd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;drink&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="s"&gt;Take one down and pass it around.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bottles&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;drink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="n"&gt;Crowd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;buymore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="s"&gt;Go to the store and buy some more.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bottles&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;buy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;99&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="n"&gt;Crowd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sing&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;tostring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bottles&lt;/span&gt;&lt;span class="p"&gt;)..&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="s"&gt; on the wall, &amp;quot;&lt;/span&gt;&lt;span class="p"&gt;..&lt;/span&gt;&lt;span class="nb"&gt;tostring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bottles&lt;/span&gt;&lt;span class="p"&gt;)..&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="s"&gt;.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;Bottles&lt;/span&gt;      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="n"&gt;Bottles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__index&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Bottles&lt;/span&gt;
&lt;span class="n"&gt;Bottles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;drink&lt;/span&gt;      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;qty&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;qty&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="n"&gt;Bottles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;buy&lt;/span&gt;        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;qty&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;qty&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="n"&gt;Bottles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__tostring&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;qty&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="s"&gt;No more bottles of beer&amp;quot;&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;qty&lt;/span&gt;&lt;span class="p"&gt;..&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="s"&gt; bottle&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;..(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;qty&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="s"&gt;s&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)..&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="s"&gt; of beer&amp;quot;&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;crowd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;setmetatable&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="n"&gt;bottles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;setmetatable&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="n"&gt;qty&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;99&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="n"&gt;Bottles&lt;/span&gt;&lt;span class="p"&gt;)},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;__index&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;Crowd&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="n"&gt;crowd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;sing&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;99&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="n"&gt;crowd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;drink&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;&lt;span class="n"&gt;sing&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="n"&gt;crowd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;buymore&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;&lt;span class="n"&gt;sing&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;h3&gt;Let the games begin!&lt;/h3&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="c"&gt;#/usr/bin/env sh&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Baseline echo&amp;#39;&lt;/span&gt;
&lt;span class="nb"&gt;time &lt;/span&gt;&lt;span class="k"&gt;for &lt;/span&gt;i in &lt;span class="o"&gt;{&lt;/span&gt;0..20..1&lt;span class="o"&gt;}&lt;/span&gt;; &lt;span class="k"&gt;do &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;A long line with a number: $i&amp;quot;&lt;/span&gt; &amp;gt; /dev/null ; &lt;span class="k"&gt;done&lt;/span&gt;
&lt;span class="c"&gt;# real  0m0.001s user   0m0.000s sys    0m0.000s&lt;/span&gt;

lua -v
&lt;span class="nb"&gt;time &lt;/span&gt;&lt;span class="k"&gt;for &lt;/span&gt;i in &lt;span class="o"&gt;{&lt;/span&gt;0..20..1&lt;span class="o"&gt;}&lt;/span&gt;; &lt;span class="k"&gt;do &lt;/span&gt;lua beer.lua &amp;gt; /dev/null ; &lt;span class="k"&gt;done&lt;/span&gt;
&lt;span class="c"&gt;# Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio&lt;/span&gt;
&lt;span class="c"&gt;# real  0m0.054s user   0m0.000s sys    0m0.007s&lt;/span&gt;

luajit-2.0.0-beta6 -v
&lt;span class="nb"&gt;time &lt;/span&gt;&lt;span class="k"&gt;for &lt;/span&gt;i in &lt;span class="o"&gt;{&lt;/span&gt;0..20..1&lt;span class="o"&gt;}&lt;/span&gt;; &lt;span class="k"&gt;do &lt;/span&gt;luajit-2.0.0-beta6 beer.lua &amp;gt; /dev/null ; &lt;span class="k"&gt;done&lt;/span&gt;
&lt;span class="c"&gt;# LuaJIT 2.0.0-beta6 -- Copyright (C) 2005-2011 Mike Pall. http://luajit.org/&lt;/span&gt;
&lt;span class="c"&gt;# real  0m0.041s user   0m0.000s sys    0m0.007s&lt;/span&gt;

rvm 1.9.2 &lt;span class="nb"&gt;exec &lt;/span&gt;ruby -v
&lt;span class="nb"&gt;time &lt;/span&gt;&lt;span class="k"&gt;for &lt;/span&gt;i in &lt;span class="o"&gt;{&lt;/span&gt;0..20..1&lt;span class="o"&gt;}&lt;/span&gt;; &lt;span class="k"&gt;do &lt;/span&gt;rvm 1.9.2 &lt;span class="nb"&gt;exec &lt;/span&gt;ruby beer.rb &amp;gt; /dev/null ; &lt;span class="k"&gt;done&lt;/span&gt;
&lt;span class="c"&gt;# ruby 1.9.2p180 (2011-02-18 revision 30909) [x86_64-linux]&lt;/span&gt;
&lt;span class="c"&gt;# real  0m17.076s user  0m12.116s sys   0m3.323s&lt;/span&gt;

rvm jruby &lt;span class="nb"&gt;exec &lt;/span&gt;jruby -v
&lt;span class="nb"&gt;time &lt;/span&gt;&lt;span class="k"&gt;for &lt;/span&gt;i in &lt;span class="o"&gt;{&lt;/span&gt;0..20..1&lt;span class="o"&gt;}&lt;/span&gt;; &lt;span class="k"&gt;do &lt;/span&gt;rvm jruby &lt;span class="nb"&gt;exec &lt;/span&gt;jruby beer.rb &amp;gt; /dev/null ; &lt;span class="k"&gt;done&lt;/span&gt;
&lt;span class="c"&gt;# jruby 1.6.2 (ruby-1.8.7-p330) (2011-05-23 e2ea975) (OpenJDK 64-Bit Server VM 1.6.0_22) [linux-amd64-java]&lt;/span&gt;
&lt;span class="c"&gt;# real  1m35.087s user  2m21.537s sys   0m7.226s&lt;/span&gt;

rvm ree ruby -v
&lt;span class="nb"&gt;time &lt;/span&gt;&lt;span class="k"&gt;for &lt;/span&gt;i in &lt;span class="o"&gt;{&lt;/span&gt;0..20..1&lt;span class="o"&gt;}&lt;/span&gt;; &lt;span class="k"&gt;do &lt;/span&gt;rvm ree &lt;span class="nb"&gt;exec &lt;/span&gt;ruby beer.rb &amp;gt; /dev/null ; &lt;span class="k"&gt;done&lt;/span&gt;
&lt;span class="c"&gt;# ruby 1.8.7 (2011-02-18 patchlevel 334) [x86_64-linux], MBARI 0x6770, Ruby Enterprise Edition 2011.03&lt;/span&gt;
&lt;span class="c"&gt;# real  0m18.075s user  0m12.619s sys   0m3.526s&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;h3&gt;Conclusions&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;I don't give any chance to the jit capable interpreters to work their magic.&lt;/li&gt;
&lt;li&gt;I'm "measuring" the system's I/O too even when I'm directing the output to /dev/null, get over it.&lt;/li&gt;
&lt;li&gt;Lua, including its start-up time, is FAST!. Also, object oriented programming
in lua is flexible, simple and nice.&lt;/li&gt;
&lt;li&gt;Rails does not scale.&lt;/li&gt;
&lt;li&gt;I want a beer.&lt;/li&gt;
&lt;/ul&gt;

&lt;img src="http://feeds.feedburner.com/~r/EmmanuelOga/~4/UDUxpE8CoGM" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://emmanueloga.com/2011/07/29/drinking-contest.html</feedburner:origLink></entry>
 
 <entry>
   <title>Taming a Capybara</title>
   <link href="http://feedproxy.google.com/~r/EmmanuelOga/~3/8A4xInh1q3s/taming-a-capybara.html" />
   <updated>2011-07-26T00:00:00-07:00</updated>
   <id>http://emmanueloga.com/2011/07/26/taming-a-capybara</id>
   <content type="html">&lt;div class="align_center"&gt;
  &lt;img src="/images/capybara.jpg" title="Rude Capybara" alt="Rude Capybara"/&gt;
  &lt;br/&gt;
  &lt;a href="http://raxdakkar.com/2009/06/28/capybara-as-a-pet-i-want-one/"&gt;
    &lt;small&gt;photo from raxdakkar.com&lt;/small&gt;
  &lt;/a&gt;
&lt;/div&gt;




&lt;br/&gt;


&lt;p&gt;Running acceptance tests in our rails 3 application turned out to be non
trivial, even though there are excellent tools out there, and they keep
getting better.&lt;/p&gt;

&lt;p&gt;We are currently using &lt;a href="https://github.com/jnicklas/capybara"&gt;capybara&lt;/a&gt;
with the &lt;a href="https://github.com/thoughtbot/capybara-webkit"&gt;capybara-webkit driver&lt;/a&gt;,
which is great because it runs in headless mode, without annoying
browser windows popping up. I heard the QT download can be pretty big
for mac users though, so have some spare bandwidth around if you have a
mac and are planning to give it a try.&lt;/p&gt;

&lt;p&gt;As we kept adding tests, the size of our &lt;strong&gt;spec/support/capybara.rb&lt;/strong&gt;
file grew with a lot of hacks. Here is an anotated version of that file
and some others related, should it be helpful to anybody out there.
Perhaps somebody will want to comment on better solutions for some of
the nasty hacks.&lt;/p&gt;

&lt;h3&gt;Gemfile&lt;/h3&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="n"&gt;group&lt;/span&gt; &lt;span class="ss"&gt;:test&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;capybara&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;~&amp;gt; 1.0.0&amp;#39;&lt;/span&gt;

  &lt;span class="c1"&gt;# The git version worked better for us at the time we installed it.&lt;/span&gt;
  &lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;capybara-webkit&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:git&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;git://github.com/thoughtbot/capybara-webkit&amp;quot;&lt;/span&gt;

  &lt;span class="c1"&gt;# This is needed by capybara&amp;#39;s save_and_open_page method.&lt;/span&gt;
  &lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;launchy&amp;#39;&lt;/span&gt;

  &lt;span class="c1"&gt;# This *might* be needed in some setups&lt;/span&gt;
  &lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;database_cleaner&amp;#39;&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;h3&gt;config/initializers/session_store.rb&lt;/h3&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="c1"&gt;# We deploy our application to several different subdomains, and we need&lt;/span&gt;
&lt;span class="c1"&gt;# to configure the domain for cookies in order to avoid the sessions&lt;/span&gt;
&lt;span class="c1"&gt;# getting mixed.&lt;/span&gt;
&lt;span class="c1"&gt;# But the domain option was messing with capybara browsers&amp;#39; ability to&lt;/span&gt;
&lt;span class="c1"&gt;# remember cookies, so we just exclude the domain config on the test environment.&lt;/span&gt;
&lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;:key&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;_our_app_session_&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:domain&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Settings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cookies_host&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;test?&lt;/span&gt;

&lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;session_store&lt;/span&gt; &lt;span class="ss"&gt;:cookie_store&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;h3&gt;spec/spec_helper.rb&lt;/h3&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="no"&gt;RSpec&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;configure&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="c1"&gt;# .. rspec stuff&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# This is how we load our support files for rspec, this keeps the size of&lt;/span&gt;
&lt;span class="c1"&gt;# the spec_helper.rb file manageable.&lt;/span&gt;
&lt;span class="no"&gt;Dir&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dirname&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;__FILE__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/support/**/*.rb&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;h3&gt;spec/support/capybara.rb&lt;/h3&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;capybara/rails&amp;quot;&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;capybara/rspec&amp;#39;&lt;/span&gt;

&lt;span class="c1"&gt;# Setup capybara webkit as the driver for javascript-enabled tests.&lt;/span&gt;
&lt;span class="no"&gt;Capybara&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;javascript_driver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;:webkit&lt;/span&gt;

&lt;span class="c1"&gt;# In our setup, for some reason the browsers capybara was driving were&lt;/span&gt;
&lt;span class="c1"&gt;# not openning the right host:port. Below, we force the correct&lt;/span&gt;
&lt;span class="c1"&gt;# host:port.&lt;/span&gt;
&lt;span class="no"&gt;Capybara&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;server_port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;7787&lt;/span&gt;

&lt;span class="c1"&gt;# We have more than one controller inheriting from&lt;/span&gt;
&lt;span class="c1"&gt;# ActionController::Base, and, in our app, ApplicationController redefines&lt;/span&gt;
&lt;span class="c1"&gt;# the default_url_options method, so we need to redefine the method for&lt;/span&gt;
&lt;span class="c1"&gt;# the two classes.&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="no"&gt;ApplicationController&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;ActionController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Listing&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;klass&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;klass&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;class_eval&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;default_url_options&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;:host&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;127.0.0.1&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:port&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Capybara&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;server_port&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# Here we do some selective configuration for tests which run with the&lt;/span&gt;
&lt;span class="c1"&gt;# rack backend and tests which run with the webkit backend.&lt;/span&gt;
&lt;span class="no"&gt;RSpec&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;configure&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="c1"&gt;# In order for the database to have the same data both for the&lt;/span&gt;
  &lt;span class="c1"&gt;# capybara process and the web application process, we need either to&lt;/span&gt;
  &lt;span class="c1"&gt;# disable transactional fixtures (which produces very slow runs),&lt;/span&gt;
  &lt;span class="c1"&gt;# or use the hack you can find below in this file.&lt;/span&gt;
  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;use_transactional_fixtures&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;

  &lt;span class="c1"&gt;# Uncomment in case your db gets dirty somehow.&lt;/span&gt;
  &lt;span class="c1"&gt;# DatabaseCleaner.clean_with(:truncation)&lt;/span&gt;

  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;before&lt;/span&gt; &lt;span class="ss"&gt;:each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="no"&gt;Capybara&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;current_driver&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="ss"&gt;:rack_test&lt;/span&gt;
      &lt;span class="c1"&gt;# With selenium/webkit the host is set automatically if it was nil.&lt;/span&gt;
      &lt;span class="no"&gt;Capybara&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;app_host&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;
    &lt;span class="c1"&gt;# config.use_transactional_fixtures = false&lt;/span&gt;
    &lt;span class="c1"&gt;# $use_truncation = true&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
      &lt;span class="c1"&gt;# We found Capybara.app_host needs to be nil when using rack backend,&lt;/span&gt;
      &lt;span class="c1"&gt;# but point to 127.0.0.1 when using selenium or webkit.&lt;/span&gt;
      &lt;span class="no"&gt;Capybara&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;app_host&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;http://127.0.0.1&amp;quot;&lt;/span&gt;
    &lt;span class="c1"&gt;# config.use_transactional_fixtures = true&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# config.after :each do&lt;/span&gt;
&lt;span class="c1"&gt;#   DatabaseCleaner.clean_with(:truncation) if $use_truncation&lt;/span&gt;
&lt;span class="c1"&gt;# end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# Big Fat Hack (TM) so the ActiveRecord connections are shared across threads.&lt;/span&gt;
&lt;span class="c1"&gt;# This is a variation of a hack you can find all over the web to make&lt;/span&gt;
&lt;span class="c1"&gt;# capybara usable without having to switch to non transactional&lt;/span&gt;
&lt;span class="c1"&gt;# fixtures.&lt;/span&gt;
&lt;span class="c1"&gt;# http://groups.google.com/group/ruby-capybara/browse_thread/thread/248e89ae2acbf603/e5da9e9bfac733e0&lt;/span&gt;
&lt;span class="no"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:activerecord_connection&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;retrieve_connection&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connection&lt;/span&gt;
  &lt;span class="no"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:activerecord_connection&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# Last but not least, when using capybara-webkit sometimes the response&lt;/span&gt;
&lt;span class="c1"&gt;# is not available when capybara tries to retrieve the contents of the&lt;/span&gt;
&lt;span class="c1"&gt;# page. Of all the possible solutions, this was the simplest for us:&lt;/span&gt;
&lt;span class="c1"&gt;# introducing a fixed delay each time something is clicked in the browser.&lt;/span&gt;
&lt;span class="c1"&gt;# https://github.com/thoughtbot/capybara-webkit/issues/111&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Capybara&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Driver&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Webkit&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Browser&lt;/span&gt;
  &lt;span class="k"&gt;alias&lt;/span&gt; &lt;span class="n"&gt;original_command&lt;/span&gt; &lt;span class="n"&gt;command&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;command&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;original_command&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;click&amp;quot;&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;h3&gt;Final Thoughts&lt;/h3&gt;

&lt;p&gt;Even though the config above allows our acceptance tests to merrily run,
I'm not completely satisfied with the hoops we needed to jump
in order to get things to work.&lt;/p&gt;

&lt;p&gt;I have the feeling having the acceptance tests completely isolated from
the main application (even in a separate repository) could be a good
thing. In this direction it would be worthy to try and write the
acceptance tests using a tool like &lt;a href="http://www.phantomjs.org/"&gt;phantomjs&lt;/a&gt;.
I'm not talking about getting a phantomjs driver for capybara, but
directly writing the whole acceptance suite with phantomjs in
javascript.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/EmmanuelOga/~4/8A4xInh1q3s" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://emmanueloga.com/2011/07/26/taming-a-capybara.html</feedburner:origLink></entry>
 
 <entry>
   <title>Downloading and unzipping a file with ruby</title>
   <link href="http://feedproxy.google.com/~r/EmmanuelOga/~3/-hWrgDGYW3M/dowloading-and-unzipping-a-file.html" />
   <updated>2011-06-21T00:00:00-07:00</updated>
   <id>http://emmanueloga.com/2011/06/21/dowloading-and-unzipping-a-file</id>
   <content type="html">&lt;p&gt;Quick! I need to download a zip file from an HTTP server and unzip it!
That's surely trivial with ruby... is it? &lt;em&gt;Yes, it is&lt;/em&gt;. But! Turns out
there are a bunch of zip handling gems out there, and I had to try a
a couple before arriving to my final solution.&lt;/p&gt;

&lt;p&gt;First, let's download the file. This particular resource is served via
an HTTP POST method. Yeah, unusual for a zip file.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;  &lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;net/http&amp;#39;&lt;/span&gt;

  &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;http://someweirdserver.com/a-zip-served-via-POST.zip&amp;quot;&lt;/span&gt;
  &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;some-bizarre-params&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;which-are-needed&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;zipbytes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Net&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;post_form&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;URI&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Done. Moving forward, let's unzip the file. One detail to bear in mind,
I have the zip file as a buffer (a String instance), and I don't want
to go trough a tempfile to unzip it. The good news is that the
&lt;a href="http://zipruby.rubyforge.org/"&gt;zipruby&lt;/a&gt; gem can work off buffers.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;  &lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;zipruby&amp;#39;&lt;/span&gt;

  &lt;span class="no"&gt;Zip&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Archive&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;open_buffer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;zipbytes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;zf&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="c1"&gt;# this is a single file archive, so read the first file&lt;/span&gt;
    &lt;span class="n"&gt;zf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fopen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;zf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;unzipped&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;
      &lt;span class="c1"&gt;# done! do something with the unzipped file.&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;



&lt;img src="http://feeds.feedburner.com/~r/EmmanuelOga/~4/-hWrgDGYW3M" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://emmanueloga.com/2011/06/21/dowloading-and-unzipping-a-file.html</feedburner:origLink></entry>
 
 <entry>
   <title>Lua's multiple arguments and the "select" function</title>
   <link href="http://feedproxy.google.com/~r/EmmanuelOga/~3/HhZokolzmF4/lua-select.html" />
   <updated>2010-12-09T00:00:00-08:00</updated>
   <id>http://emmanueloga.com/2010/12/09/lua-select</id>
   <content type="html">&lt;p&gt;When I first read about lua's select function I found it a little
confusing.&lt;/p&gt;

&lt;p&gt;According to &lt;a href="http://www.lua.org/manual/5.1/manual.html#pdf-select"&gt;lua's manual for version 5.1&lt;/a&gt;,
select behaves as follows:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="lua"&gt;&lt;span class="nb"&gt;select&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;···&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;




&lt;pre&gt;
If index is a number, returns all arguments after argument number
index.  Otherwise, index must be the string "#", and select returns
the total number of extra arguments it received.
&lt;/pre&gt;


&lt;p&gt;That wasn't clear to me at first, but then I remembered lua sports
&lt;em&gt;real&lt;/em&gt; multiple arguments. I remark the word &lt;em&gt;real&lt;/em&gt; because other
languages like ruby don't really support returning multiple arguments.
In ruby, if a method returns multiple arguments they are automatically
packed into an array. Lua, in the other hand, has built in multiple
arguments, which you can convert into a table if you really need to:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="lua"&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;multiple_args&lt;/span&gt;&lt;span class="p"&gt;(...)&lt;/span&gt;
  &lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;arguments&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{...}&lt;/span&gt;  &lt;span class="c1"&gt;-- pack the arguments in a table&lt;/span&gt;
  &lt;span class="c1"&gt;-- do something --&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;unpack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;-- return multiple arguments from a table (unpack)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Remembering the nature of lua's multiple arguments, and the fact that
multiple arguments are not returned on a lua table dressed as an array,
the description on the manual started to make sense.&lt;/p&gt;

&lt;p&gt;The select function takes as "index" the index of the first argument
that you want to retrieve, and any number of arguments afterward (the
count of arguments starts at 1).&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="lua"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;--&amp;gt; 1, 2, 3&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;--&amp;gt; 2, 3&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;--&amp;gt; 3&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;--&amp;gt; NOTHING&lt;/span&gt;

&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;}))&lt;/span&gt; &lt;span class="c1"&gt;--&amp;gt; table&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;}))&lt;/span&gt; &lt;span class="c1"&gt;--&amp;gt; nothing&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;In the last two examples, the number of variable arguments is just one,
consisting of a single table.&lt;/p&gt;

&lt;p&gt;By the way, note another subtlety of lua: if you select more that the
number of arguments available you get &lt;em&gt;absolutely nothing!&lt;/em&gt;. Not even
nil: nothing. If you try to pack NOTHING into a table, you get an empty
table:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="lua"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="p"&gt;{(&lt;/span&gt;&lt;span class="n"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)()})&lt;/span&gt; &lt;span class="c1"&gt;--&amp;gt; 0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Finally, if you pass "#" as index, the function returns a count of the
multiple arguments provided:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="lua"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="s"&gt;#&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;--&amp;gt; 0&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="s"&gt;#&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;}))&lt;/span&gt; &lt;span class="c1"&gt;--&amp;gt; 1 (single table as argument)&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="s"&gt;#&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;--&amp;gt; 3&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="s"&gt;#&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="c1"&gt;--&amp;gt; 4 (a table, 2 numbers, another table)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;



&lt;img src="http://feeds.feedburner.com/~r/EmmanuelOga/~4/HhZokolzmF4" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://emmanueloga.com/2010/12/09/lua-select.html</feedburner:origLink></entry>
 
 <entry>
   <title>Ruby conferences in Brazil and Uruguay</title>
   <link href="http://feedproxy.google.com/~r/EmmanuelOga/~3/T4y62ESfeT4/rubyconfs%21.html" />
   <updated>2010-10-31T00:00:00-07:00</updated>
   <id>http://emmanueloga.com/2010/10/31/rubyconfs!</id>
   <content type="html">&lt;p&gt;This year I could attend both rubyconf Brazil and Uruguay. Both conferences had
great talks and summarizing everything would be overkill, so I'll instead post
some brief notes.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://rubyconf.com.br/" title="RubyConf Brazil"&gt;RubyConf Brazil's Site&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.rubyconf.com.br/en/schedule" title="RubyConf Brazil's Schedule"&gt;RubyConf Brazil's Schedule&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://rubyconfuruguay.org" title="RubyConf Uruguay"&gt;RubyConf Uruguay's Site&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://rubyconfuruguay.org/en/agenda" title="Uruguay Schedule"&gt;RubyConf Uruguay's Schedule&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;My Notes&lt;/h2&gt;

&lt;h4&gt;Brazil Opening&lt;/h4&gt;

&lt;p&gt;&lt;a href="http://akitaonrails.com/"&gt;Fabio Akita&lt;/a&gt;'s talk was great in motivating the
audience to be more participative in open source projects as a way of
continuously improving as developers.&lt;/p&gt;

&lt;h4&gt;Client side development&lt;/h4&gt;

&lt;p&gt;&lt;a href="http://yehudakatz.com/"&gt;Yehuda Katz&lt;/a&gt; talked about focusing on the client side
of web applications.  Using Ajax techniques is a start but ajax still generates
a lot of latency waiting for server responses. In order to have
&lt;a href="http://www.sproutcore.com/"&gt;a better client side experience&lt;/a&gt;
techniques like buffered DOM manipulation, object bindings and
event loops on the client side, can help to do as much work on the client as
possible.&lt;/p&gt;

&lt;h4&gt;Rails 3.1&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://github.com/josevalim"&gt;José Valim&lt;/a&gt; talked about some great features
that will be packaged on rails 3.1, as better asset packaging (in line with the
functionality provided by the sprockets gems), making rails serve the
stylesheets and javascript and use sass, and general improvements on a lot of
areas (new ActiveRecord's identity map, better generators, etc.).&lt;/p&gt;

&lt;h4&gt;Rubinius&lt;/h4&gt;

&lt;p&gt;Both &lt;a href="http://blog.fallingsnow.net/"&gt;Evan Phoenix&lt;/a&gt; in Brazil and &lt;a href="http://blog.brightredglow.com/"&gt;Brian
Ford&lt;/a&gt; in Uruguay described great features
packed on of &lt;a href="http://rubini.us/"&gt;rubinius&lt;/a&gt;. Some of the impressive features are
the integrated console and the profiler (both triggable by command line, no
additional gems required). They also talked about the modularity and
extensibility of the tools bundled in the rubinius environment, made evident by
the possibility to implement 3rd party languages (like the
&lt;a href="http://www.fancy-lang.org/"&gt;fancy programming language&lt;/a&gt;).&lt;/p&gt;

&lt;h4&gt;JRuby&lt;/h4&gt;

&lt;p&gt;&lt;a href="http://blog.headius.com/"&gt;Charles Nutter&lt;/a&gt;
&lt;a href="http://www.slideshare.net/CharlesNutter/rubyconf-uruguay-2010-jruby"&gt;showcased&lt;/a&gt;
some cool demos on jruby, including live coding a swt GUI from irb, using the
VisualVM profiler to profile some code, running a multithreaded java
environment from the command line using the &lt;a href="https://github.com/calavera/trinidad"&gt;trinidad
gem&lt;/a&gt;, and a 3D game. He also showed a
demo of the &lt;a href="mirah.org"&gt;mirah programming language&lt;/a&gt;, which has a syntax
similar to ruby's but contains type annotations and can produce either java
code or jvm bytecode.&lt;/p&gt;

&lt;h4&gt;Webfinger&lt;/h4&gt;

&lt;p&gt;&lt;a href="http://romeda.org/"&gt;Blaine Cook&lt;/a&gt; talked about
&lt;a href="http://webfinger.org/"&gt;webfinger&lt;/a&gt;, a solution to provide users with an
identity on the web in such a way they becomes the owners of it (as opposed as
tying the identity on the web to any given service, like twitter, facebook or
linkedin profile names). Slides &lt;a href="http://lanyrd.com/2010/rubyconf-uruguay/smzm/"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;Ruby 1.9.x fibers&lt;/h4&gt;

&lt;p&gt;&lt;a href="http://tenderlovemaking.com/"&gt;Aaron Patterson&lt;/a&gt; gave a talk about scheduling,
fibers and coroutines.&lt;/p&gt;

&lt;h4&gt;OOP and SOLID&lt;/h4&gt;

&lt;p&gt;&lt;a href="http://onestepback.org/"&gt;Jim Weirich&lt;/a&gt; gave a talk about OOP and the
&lt;a href="http://en.wikipedia.org/wiki/SOLID"&gt;SOLID&lt;/a&gt; principles.&lt;/p&gt;

&lt;h4&gt;Git&lt;/h4&gt;

&lt;p&gt;&lt;a href="http://jointheconversation.org/"&gt;Scott Chacon&lt;/a&gt; gave a tutorial for git,
starting from the fundamentals and the differences with other VCS like rcs or
svn.&lt;/p&gt;

&lt;h4&gt;Clojure&lt;/h4&gt;

&lt;p&gt;&lt;a href="http://twitter.com/fbru02"&gt;Federico Brubacher&lt;/a&gt; talked about
&lt;a href="http://clojure.org/"&gt;clojure&lt;/a&gt;, a very nice functional programming language for
the jvm, and a great alternative to scala as it is a much more simple language.&lt;/p&gt;

&lt;h4&gt;ActiveRecord and Identity Maps&lt;/h4&gt;

&lt;p&gt;&lt;a href="http://miloops.com/"&gt;Emilio Tagua&lt;/a&gt; talked the addition of an Identity Map to
ActiveRecord to shield great memory and performance savings.&lt;/p&gt;

&lt;h4&gt;Programming patterns&lt;/h4&gt;

&lt;p&gt;&lt;a href="http://nucleartesuji.com/"&gt;Ignacio Facello&lt;/a&gt; talked about patterns for Ruby.&lt;/p&gt;

&lt;h4&gt;Metaprogramming&lt;/h4&gt;

&lt;p&gt;&lt;a href="http://twitter.com/spastorino"&gt;Santiago Pastorino&lt;/a&gt; talked about
&lt;a href="http://www.slideshare.net/spastorino/metaprogramming-5634072"&gt;metaprogramming&lt;/a&gt;
ruby techniques.&lt;/p&gt;

&lt;h4&gt;Android&lt;/h4&gt;

&lt;p&gt;&lt;a href="http://www.tbray.org/ongoing/"&gt;Tim Bray&lt;/a&gt; gave a 30 minutes long advertisement
on &lt;a href="http://www.android.com/"&gt;android&lt;/a&gt;, quickly dismissing ruby as a viable
development option while it was on it. Despite that, android is a great
platform to develop mobile applications.&lt;/p&gt;

&lt;h4&gt;Uruguay Keynote&lt;/h4&gt;

&lt;p&gt;Evan Henshaw-Plath (&lt;a href="http://twitter.com/rabble"&gt;@rabble&lt;/a&gt;) closed the Uruguay
conference with a great keynote where he talked about the characteristics of
the ruby community.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/EmmanuelOga/~4/T4y62ESfeT4" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://emmanueloga.com/2010/10/31/rubyconfs%21.html</feedburner:origLink></entry>
 
 <entry>
   <title>See you at rubyconf.br!</title>
   <link href="http://feedproxy.google.com/~r/EmmanuelOga/~3/f-ZrKKojAJw/rubyconf-br.html" />
   <updated>2010-10-24T00:00:00-07:00</updated>
   <id>http://emmanueloga.com/2010/10/24/rubyconf-br</id>
   <content type="html">&lt;p&gt;Tomorrow I'm travelling to Sao Pablo, Brazil, to attend my first
&lt;a href="http://rubyconf.com.br/" title="RubyConf Brazil"&gt;http://rubyconf.com.br/&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Exiting times! See you there?&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/EmmanuelOga/~4/f-ZrKKojAJw" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://emmanueloga.com/2010/10/24/rubyconf-br.html</feedburner:origLink></entry>
 

</feed>

