<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Programblings</title>
	<atom:link href="http://programblings.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://programblings.com</link>
	<description>Rambling about programming and life as a programmer - by Mathieu Martin</description>
	<lastBuildDate>Sun, 06 Jun 2010 14:40:52 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>A new Ruby and Rails blog is born</title>
		<link>http://programblings.com/2009/02/16/a-new-ruby-and-rails-blog-is-born/</link>
		<comments>http://programblings.com/2009/02/16/a-new-ruby-and-rails-blog-is-born/#comments</comments>
		<pubDate>Mon, 16 Feb 2009 21:43:04 +0000</pubDate>
		<dc:creator>Mathieu Martin</dc:creator>
				<category><![CDATA[blogging]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://programblings.com/?p=259</guid>
		<description><![CDATA[I haven&#8217;t been blogging much lately. I&#8217;ve been too busy with some vacation time and, of course, work.
This is going to change, but it&#8217;s not all going to happen on Programblings.
It&#8217;s been a long time coming, but giraffesoft finally has a blog. We&#8217;re going to kickstart our blog with a week of open source releases.
At <a href='http://programblings.com/2009/02/16/a-new-ruby-and-rails-blog-is-born/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>I haven&#8217;t been blogging much lately. I&#8217;ve been too busy with some vacation time and, of course, work.</p>
<p>This is going to change, but it&#8217;s not all going to happen on Programblings.</p>
<p>It&#8217;s been a long time coming, but <a href='http://giraffesoft.ca'>giraffesoft</a> finally has a blog. We&#8217;re going to kickstart our blog with a week of open source releases.</p>
<p>At giraffesoft we like DRY code. We all know that creating Rails plugins is barely more work than actually implementing the functionality inside of a specific application. For that reason, we create plugins all the time when working on projects.</p>
<p>So this week, we&#8217;re going to polish up a few of them &#8211; big and small &#8211; and officially introduce them to the world.</p>
<p>For now, please let me direct you to the brand-spanking new <a href='http://giraffesoft.ca/blog'>giraffesoft blog</a>.</p>
<p>If you&#8217;re too lazy to read the introductory post, here&#8217;s the punchlines:</p>
<ul>
<li><a href='http://feeds.giraffesoft.ca/giraffesoft-the-blog'>follow our RSS feed</a> or</li>
<li><a href='http://twitter.com/giraffesoft'>follow us on Twitter</a>.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://programblings.com/2009/02/16/a-new-ruby-and-rails-blog-is-born/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rubinius for the Layman, Part 3 &#8211; Try Rubinius in 20 minutes</title>
		<link>http://programblings.com/2008/11/25/rubinius-for-the-layman-part-3-try-rubinius-in-20-minutes/</link>
		<comments>http://programblings.com/2008/11/25/rubinius-for-the-layman-part-3-try-rubinius-in-20-minutes/#comments</comments>
		<pubDate>Tue, 25 Nov 2008 13:38:05 +0000</pubDate>
		<dc:creator>Mathieu Martin</dc:creator>
				<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://programblings.com/?p=227</guid>
		<description><![CDATA[I guess we&#8217;ve all heard last week&#8217;s sad news about Engine Yard diminishing the awesome support they&#8217;ve given the Rubinius project. That&#8217;s personally how I see it: they&#8217;ve put the project on steroids for roughly a year, rather than &#8220;they&#8217;re now cutting back&#8221; x people.
As Brian Ford pointed out, Rubinius is a community project. And <a href='http://programblings.com/2008/11/25/rubinius-for-the-layman-part-3-try-rubinius-in-20-minutes/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>I guess we&#8217;ve all heard <a href='http://blog.fallingsnow.net/2008/11/18/a-sad-day/'>last week&#8217;s sad news</a> about Engine Yard <a href='http://blog.engineyard.com/2008/11/17/rubinius-past-present-and-future'>diminishing the awesome support</a> they&#8217;ve given the Rubinius project. That&#8217;s personally how I see it: they&#8217;ve put the project on steroids for roughly a year, rather than &#8220;they&#8217;re now cutting back&#8221; x people.</p>
<p>As Brian Ford <a href='http://blog.brightredglow.com/2008/11/18/rubinius-is-a-community-project'>pointed out</a>, Rubinius is a community project. And Rubinius is not going away. A lot of people can&#8217;t wait to have a Ruby written more in Ruby than in C or C++. Koichi Sasada (lead developer on Ruby 1.9) even recently projected that Rubinius would eventually be the Ruby implementation of choice.</p>
<p>Rubinius&#8217; future is promising. I&#8217;d like to go from that positive note, and have YOU try Rubinius now. I promise that in 20 minutes, you&#8217;ll be running Rubinius and enjoying it. The longest parts of the process will be waiting (cloning, compiling), so it won&#8217;t even be difficult. Note: the article may look long, but it&#8217;s not. Half of it is code samples and the results returned.</p>
<p>So it&#8217;s been aeons since the last article of the RFTL series. But yes, this article is part of a series. You can look at the first 2 parts if you want. Some details<a href='#footnote_1'><sup>1</sup></a> won&#8217;t be up to date anymore, but it&#8217;ll help you get the gist of Rubinius if you&#8217;re not familiar with the project yet.</p>
<ul>
<li><a href='http://programblings.com/2008/04/01/rubinius-for-the-layman-part-1-rubies-all-the-way-down/'>Rubinius for the Layman, Part 1: Rubies All the Way Down</a></li>
<li><a href='http://programblings.com/2008/04/15/rubinius-for-the-layman-part-2-how-rubinius-is-friendly/'>Rubinius for the Layman, Part 2: How Rubinius is Friendly</a></li>
<li>Rubinius for the Layman, Part 3 &#8211; Try Rubinius in 20 minutes</li>
</ul>
<p>The 20 minutes timer starts now, for those who went ahead and read the past articles.</p>
<h1 id='install_rubinius'>Install Rubinius</h1>
<h2 id='prerequisites'>Prerequisites</h2>
<p>Prerequisites are probably already taken care of on most Ruby developers&#8217; machines:</p>
<ul>
<li>ruby 1.8, rubygems, rake and ParseTree (<code>sudo gem install rake ParseTree</code>)</li>
<li>git (no need to understand it, really, just having it installed)</li>
<li>general C++ building tools</li>
</ul>
<h3 id='dependencies_for_mac_users'>Dependencies for Mac users</h3>
<p>Leopard users should have all they need when Xcode is installed. Insert your Leopard upgrade DVD and from your terminal:</p>
<pre><code>open /Volumes/Mac\ OS\ X\ Upgrade\ DVD/Optional\ Installs/Xcode\ Tools/XcodeTools.mpkg </code></pre>
<h3 id='dependencies_for_linux_users'>Dependencies for Linux users</h3>
<p>Linux users have to make sure the following packages are installed. Use your the equivalent command for your distro:</p>
<pre><code>sudo apt-get install gcc bison make pkg-config libtool git</code></pre>
<p>(where make == GNU make)</p>
<h2 id='get_the_rubinius_code'>Get the Rubinius code</h2>
<p>Right now the GitHub feature to download a tarball is disabled for big projects like Rubinius. They say the feature on the radar as one of the things to fix in the next few weeks. Which will be awesome.</p>
<p>For now we have have to clone the repo, which in this case takes a few minutes. Find yourself a comfortable directory and:</p>
<pre><code>git clone git://github.com/evanphx/rubinius.git
# go make coffee
cd rubinius</code></pre>
<h2 id='build_rubinius'>Build Rubinius</h2>
<p>Assuming you&#8217;ve installed all the dependencies, the following should work right off the bat. If it&#8217;s not the case, check out the <a href='#footnote_2'>notes on the subject</a>.</p>
<pre><code>rake build
# go get a http://www.brawndo.com/</code></pre>
<p>Later, when you want to recompile from a clean slate, just run <code>rake distclean</code>.</p>
<p>If you have not gotten a BRAWNDO, please <a href='#run_rubinius'>skip over the next paragraph</a>.</p>
<p>RUBINIUS, like BRAWNDO, is one of the CRAZIEST ideas of the LAST DECADE! Can you realize you&#8217;re ABOUT to try the Ruby IMPLEMENTATION that&#8217;s got the BEST Ruby code ratio AMONG THEM ALL! Isn&#8217;t that FREAKING AWESOME? You can also do some of the CRAZIEST INTROSPECTION with MethodContext, StaticScope and other classes like THAT!</p>
<h1 id='run_rubinius'>Run Rubinius</h1>
<p>The Rubinius executable is rbx in the &#8216;bin&#8217; subdirectory. It&#8217;s a bit different from MRI in that rbx starts an irb session if you don&#8217;t specify a file to run. So let&#8217;s do that:</p>
<pre><code>bin/rbx
# in irb
puts &quot;Don&#39;t you spring a hello world on me&quot;
#=&gt; Don&#39;t you spring a hello world on me</code></pre>
<p>Ok then. Well, technically you&#8217;ve now tried Rubinius in less than 20 minutes. Now if you keep reading, you&#8217;ll really taste some true Rubinius awesomeness.</p>
<h2 id='kickass_introspection'>Kick-ass introspection</h2>
<p>Let&#8217;s start slow by patching <code>Object</code> to help us quickly grok the new kinds of objects we may encounter:</p>
<pre><code>class Object
  # Return only the methods not present on basic objects
  def interesting_methods
    (self.methods - Object.new.methods).sort
  end
end
#=&gt; #&lt;CompiledMethod interesting_methods file=(irb)&gt;</code></pre>
<p>And now let&#8217;s create a basic little class that will help us start our exploration of a <code>MethodContext</code> instance.</p>
<pre><code>class C
  def initialize
    @inst = 42
  end
  def get_mc
    local_var = &#39;value&#39;
    MethodContext.current
  end
end
#=&gt; #&lt;CompiledMethod get_mc file=(irb)&gt;</code></pre>
<p>So with the help of an instance of the class <code>C</code>, let&#8217;s start poking gently at a <code>MethodContext</code>.</p>
<pre><code>c   = C.new
ctx = c.get_mc
#=&gt; #&lt;MethodContext:0xcc #&lt;C:0xca&gt;#get_mc (irb):7&gt;

ctx.interesting_methods
#=&gt; [&quot;__add_method__&quot;, &quot;_get_field&quot;, &quot;_set_field&quot;, &quot;activate&quot;,
 &quot;active_path&quot;, &quot;alias_method&quot;, &quot;back_ref&quot;, &quot;block&quot;, &quot;class_variable_defined?&quot;,
 &quot;const_defined?&quot;, &quot;const_path_defined?&quot;, &quot;context_from_proc&quot;, &quot;context_stack&quot;,
 &quot;copy&quot;, &quot;current_scope&quot;, &quot;describe&quot;, &quot;disable_long_return!&quot;, &quot;dynamic_locals&quot;,
 &quot;file&quot;, &quot;fp&quot;, &quot;from_eval?&quot;, &quot;get_eval_local&quot;, &quot;ip&quot;, &quot;ip=&quot;, &quot;last_match&quot;,
 &quot;last_match=&quot;, &quot;line&quot;, &quot;lines&quot;, &quot;locals&quot;, &quot;locals=&quot;, &quot;location&quot;,
 &quot;make_independent&quot;, &quot;method=&quot;, &quot;method_module&quot;, &quot;method_scope&quot;,
 &quot;method_scope=&quot;, &quot;name&quot;, &quot;normalized_name&quot;, &quot;nth_ref&quot;, &quot;position_info&quot;,
 &quot;receiver&quot;, &quot;receiver=&quot;, &quot;reload_method&quot;, &quot;script_object&quot;, &quot;send_private?&quot;,
 &quot;sender&quot;, &quot;set_eval_local&quot;, &quot;set_iseq&quot;, &quot;sp&quot;, &quot;stack_trace_starting_at&quot;]

ctx.name
#=&gt; :get_mc

ctx.describe
#=&gt; &quot;C\#get_mc&quot;

ctx.method_module
#=&gt; C</code></pre>
<p>Interesting, that reminds me of the monkey-patching discussion that often comes up in the Ruby community. Let&#8217;s try something else:</p>
<pre><code>module ModuleMC
  def module_mc
    MethodContext.current
  end
end
#=&gt; #&lt;CompiledMethod module_mc file=(irb)&gt;

C.include ModuleMC
#=&gt; [ModuleMC]

c.module_mc.method_module
#=&gt; #&lt;IncludedModule:0xd6&gt;

c.module_mc.method_module.name
#=&gt; &quot;ModuleMC&quot;</code></pre>
<p>Wouldn&#8217;t it be nice if we had that kind of introspection, when comes time to debug some mixin magic?</p>
<p>Now let&#8217;s go back our <code>MethodContext</code> object. Or rather, its <code>method</code> accessor, which gives us a <code>CompiledMethod</code> instance:</p>
<pre><code>m = ctx.method
#=&gt; #&lt;CompiledMethod get_mc file=(irb)&gt;

m.interesting_methods
#=&gt; [&quot;__ivars__&quot;, &quot;__ivars__=&quot;, &quot;activate&quot;, &quot;activate_as_script&quot;,
&quot;as_script&quot;, &quot;child_methods&quot;, &quot;compile&quot;, &quot;decode&quot;, &quot;describe&quot;,
&quot;exceptions&quot;, &quot;exceptions=&quot;, &quot;file&quot;, &quot;file=&quot;, &quot;first_ip_on_line&quot;,
&quot;first_line&quot;, &quot;from_string&quot;, &quot;hints&quot;, &quot;hints=&quot;, &quot;inherit_scope&quot;,
&quot;is_block?&quot;, &quot;iseq&quot;, &quot;iseq=&quot;, &quot;line_from_ip&quot;, &quot;lines&quot;, &quot;lines=&quot;,
&quot;literals&quot;, &quot;literals=&quot;, &quot;local_count&quot;, &quot;local_count=&quot;, &quot;local_names&quot;,
&quot;local_names=&quot;, &quot;locate_line&quot;, &quot;min_stack_size&quot;, &quot;name&quot;, &quot;name=&quot;,
&quot;primitive&quot;, &quot;primitive=&quot;, &quot;private?&quot;, &quot;protected?&quot;, &quot;public?&quot;,
&quot;required_args&quot;, &quot;required_args=&quot;, &quot;scope&quot;, &quot;scope=&quot;, &quot;send_sites&quot;,
&quot;serial&quot;, &quot;serial=&quot;, &quot;splat&quot;, &quot;splat=&quot;, &quot;stack_size&quot;, &quot;stack_size=&quot;,
&quot;total_args&quot;, &quot;total_args=&quot;]

m.describe
#=&gt; &quot;method get_mc: 0 arg(s), 0 required&quot;

m.local_names
#=&gt; #&lt;Tuple: :local_var&gt;

m.literals
#=&gt; #&lt;Tuple: &quot;value&quot;, :MethodContext, #&lt;SendSite:0xda
#     name=current hits=0 misses=0&gt;&gt;

m.file
#=&gt; :&quot;(irb)&quot;</code></pre>
<p>The <code>local_names</code> method sounds extremely promising, but unfortunately for now, there&#8217;s no primitive for actually getting the local variable&#8217;s value, but it&#8217;s perfectly possible<a href='#footnote_3'><sup>3</sup></a>. It&#8217;s just not been done yet.</p>
<p>By the way, what is that? <code>#describe</code> summarizes the arguments? Let&#8217;s try something more interesting with it:</p>
<pre><code>def method_with_args(arg1, arg2=&#39;default&#39;, *args)
  MethodContext.current
end
#=&gt; #&lt;CompiledMethod method_with_args file=(irb)&gt;

ctx2 = method_with_args(42, &#39;towel&#39;, &quot;don&#39;t panic&quot;)
#=&gt; #&lt;MethodContext:0x16e main#method_with_args (irb):4&gt;

m2 = ctx2.method
#=&gt; #&lt;CompiledMethod method_with_args file=(irb)&gt;

m2.describe
#=&gt; &quot;method method_with_args: 2 arg(s), 1 required, splatted.&quot;

m2.local_names
#=&gt; #&lt;Tuple: :arg1, :arg2, :args&gt;

m2.literals
#=&gt; #&lt;Tuple: &quot;default&quot;, :MethodContext, #&lt;SendSite:0x16c
#     name=current hits=1 misses=0&gt;&gt;</code></pre>
<p>Nice! Ok, now let&#8217;s come back to our <code>CompiledMethod</code> instance and check out it&#8217;s <code>scope</code> accessor.</p>
<pre><code>ss = m.scope
#=&gt; #&lt;StaticScope:0xea parent=#&lt;StaticScope:0xe8 parent=nil
#     module=Object&gt; module=C&gt;

ss.interesting_methods
#=&gt; [&quot;initialize&quot;, &quot;module&quot;, &quot;parent&quot;, &quot;script&quot;, &quot;script=&quot;]

ss.parent
#=&gt; #&lt;StaticScope:0xe8 parent=nil module=Object&gt;</code></pre>
<p>So now we&#8217;ve essentially poked 2 levels deep: <code>ctx.method.scope</code>. Let&#8217;s rewind again and look at a our context&#8217;s <code>receiver</code> and <code>sender</code> accessors. To better understand both, let&#8217;s come back to our OO roots of 30 years back and start calling &#8216;method calls&#8217; &#8216;messages&#8217; instead.</p>
<p>sender (sends message &#8216;get_mc&#8217;) =&gt; receiver</p>
<p><code>sender</code> is then the caller of the method, and <code>receiver</code> is, the object receiving the message. Also known as <code>self</code>, during the execution of the method.</p>
<p>Let&#8217;s see that in action:</p>
<pre><code>r  = ctx.receiver
#=&gt; #&lt;C:0xca @inst=42&gt;

r == c
#=&gt; true</code></pre>
<p>So ctx.receiver is a reference to the instance we&#8217;d put in the variable <code>c</code>. From there of course we can do Ruby&#8217;s regular meta-poking around:</p>
<pre><code>r.instance_variable_get &#39;@inst&#39;
#=&gt; 42</code></pre>
<p>Now let&#8217;s look at the sender:</p>
<pre><code>s = ctx.sender
#=&gt; #&lt;BlockContext:0xf0 main#irb_binding (irb):1&gt;

s.class.ancestors
#=&gt; [BlockContext, MethodContext, Object, PP::ObjectMixin, Kernel]

s.interesting_methods - ctx.interesting_methods
#=&gt; [&quot;env&quot;, &quot;home&quot;]

s.home
#=&gt; #&lt;MethodContext:0xf6 main#irb_binding
#     /Users/mat/dev/_rubies/rubinius/rubinius/lib/irb/workspace.rb:1&gt;

s.env
#=&gt; #&lt;BlockEnvironment:0xf8 @initial_ip=0 @last_ip=268435456
#     @post_send=0 @bonus=#&lt;Tuple: true&gt;&gt;</code></pre>
<p>When calling a method from IRB, we&#8217;re in a BlockContext instead of a MethodContext, but it&#8217;s still in the family.</p>
<pre><code>s = ctx.sender
#=&gt; #&lt;BlockContext:0xfe main#irb_binding (irb):1&gt;

s.class.ancestors
#=&gt; [BlockContext, MethodContext, Object, Kernel]</code></pre>
<p>Anything new we need to know about?</p>
<pre><code>s.interesting_methods - ctx.interesting_methods
#=&gt; [&quot;env&quot;, &quot;home&quot;]

s.home
#=&gt; #&lt;MethodContext:0x102 main#irb_binding
#     /Users/mat/dev/_rubies/rubinius/rubinius/lib/irb/workspace.rb:1&gt;

s.env
#=&gt; #&lt;BlockEnvironment:0xf8 @initial_ip=0 @last_ip=268435456
#     @post_send=0 @bonus=#&lt;Tuple: true&gt;&gt;</code></pre>
<p>All of this is strangely reminiscent of a stack trace. Before you go collecting all senders to explore the execution stack, let me point you to the convenient <code>context_stack</code>:</p>
<pre><code>ctx.context_stack.length
#=&gt; 27

puts *ctx.context_stack
# Too noisy to output here

puts *ctx.context_stack.map{ |s| s.describe }

#=&gt;
# C#get_mc
# Object#irb_binding {}
# Kernel(IRB::WorkSpace)#eval
# IRB::WorkSpace#evaluate
# IRB::Context#evaluate
# IRB::IrbRubinius#process_statements {}
# IRB::Irb(IRB::IrbRubinius)#signal_status
# IRB::IrbRubinius#process_statements {}
# RubyLex#each_top_level_statement {}
# Kernel(RubyLex)#catch {}
# ThrownValue.register
# Kernel(RubyLex)#catch
# RubyLex#each_top_level_statement
# IRB::IrbRubinius#process_statements
# IRB::Irb(IRB::IrbRubinius)#eval_input
# IRB.start {}
# Kernel(Module)#catch {}
# ThrownValue.register
# Kernel(Module)#catch
# IRB.start
# main.__script__
# CompiledMethod#activate_as_script
# CompiledMethod#as_script
# Compile.single_load
# Compile.unified_load
# Kernel(Object)#require
# Object#__script__
# #=&gt; nil</code></pre>
<p>I&#8217;m pretty sure there&#8217;s other areas specific to Rubinius that can be explored like that. Please share any insight in the comments.</p>
<h2 id='sexpressions'>S-Expressions</h2>
<p>Rubinius groks s-expressions out of the box (similar to standard Ruby with <a href='http://parsetree.rubyforge.org/'>ParseTree or ruby_parser</a>. <a href='http://gist.github.com/27156'>An example</a>).</p>
<pre><code>require &#39;pp&#39;
pp sx = &quot;
  class C
    def meth(arg)
      arg * 2
    end
  end&quot;.to_sexp

#=&gt;
# s(:class,
#  :C,
#  nil,
#  s(:scope,
#   s(:defn,
#    :meth,
#    s(:args, :arg),
#    s(:scope,
#     s(:block, s(:call, s(:lvar, :arg), :*, s(:arglist, s(:fixnum, 2))))))))

sx[0]
#=&gt; :class

sx[3][1][1]
#=&gt; :meth</code></pre>
<p>With something that reminiscent to Lisp, it&#8217;s probably better to explore recursively, though.</p>
<p>S-expressions are used by a lot of the Ruby <a href='http://devver.net/blog/2008/10/ruby-tools-roundup/'>code inspection tools</a> to understand your ugly Ruby code.</p>
<h2 id='gems'>Gems</h2>
<p>I won&#8217;t touch trying out gems for today. There seems to be little issues as the moment. They do install, but I&#8217;ve been having problems running them. Please leave a comment if you&#8217;ve had success with specific gems.</p>
<p>If you&#8217;re curious and want to try playing with gems, Rubygems is already installed.</p>
<pre><code>rbx gem install rails --no-rdoc --no-ri</code></pre>
<p>Pro tip: always skip the documentation when playing with gems Rubinius. The doc takes unusually long to compile.</p>
<h2 id='run_the_famous_test_suite'>Run the famous test suite</h2>
<p>The spec suite that&#8217;s been keeping all Ruby implementations honest was born from the Rubinius project. It&#8217;s been split into a separate project a while ago, since it&#8217;s now such an important and central piece of the Ruby ecosystem.</p>
<h3 id='update_the_specs'>Update the specs</h3>
<p>Since they are now in a different project, we first have to get the most recent version. Easy stuff:</p>
<pre><code>rake rubyspec:update</code></pre>
<h3 id='rbx_in_your_path'>rbx in your PATH</h3>
<p>Before you run the specs, you need to do one little thing. One of the specs expects a shell call to rbx to start Rubinius (as in, the executable must be in your path).</p>
<p>The simplest way to do that for now is just to temporarily add the directory to your path (right in your console, not in your .bash_profile).</p>
<pre><code>pwd
#=&gt; /path/to/project/rubinius
export PATH=$PATH:/path/to/project/rubinius/bin
rbx -v</code></pre>
<h3 id='run_the_specs'>Run the specs</h3>
<pre><code>rake spec
# Time for another BRAWNDO!</code></pre>
<p>Or rather, time to actually look at some of the specs you&#8217;re currently running. If you look in the spec directory, you&#8217;ll see that it&#8217;s pretty extensive, to say the least. To start with something familiar, navigate to spec/ruby/1.8, in subdirectories core or library. Open up a few of the specs in there and stare at them for a few minutes. Or better, improve a few of them and try them out on MRI, JRuby and of course, Rubinius.</p>
<h1 id='conclusion'>Conclusion</h1>
<p>Well, now I&#8217;ve tricked you into putting the Rubinius project on your hard drive. And you&#8217;re a Ruby developer. What are you waiting for?</p>
<ul>
<li><a href='http://github.com/evanphx/rubinius/tree/master/doc/contributing.txt'>Contribute</a></li>
<li><a href='http://github.com/evanphx/rubinius/tree/master/doc'>Documentation</a></li>
<li><a href='http://rubinius.lighthouseapp.com/projects/5089-rubinius/overview'>Tickets overview</a></li>
</ul>
<p>I think Rubinius will be an awesome runtime for our Ruby programs. It probably won&#8217;t be <em>only</em> Ruby in the close future, but the kernel of Ruby (base classes &amp; stuff) is mostly implemented in Ruby, and the compiler is also implemented in Ruby. This is awesome to help understand the workings of the language and to lower the barrier to contribution. Which is already pretty low.</p>
<p>Rubinius is here to stay and it&#8217;s gonna keep rocking.</p>
<h1 id='footnotes'>Footnotes</h1>
<ol>
<li id='footnote_1'>
    Examples of details not up to date in the old articles are: the LOC numbers and the base language of the VM (used to be C, now C++).
  </li>
<li id='footnote_2'>
    If the build craps out with a message you understand, cool. Try to install the dependency through apt-get or macports/fink, or search your hard drive to see if the tool&#8217;s just not in your PATH. Otherwise, here are a few related pointers.</p>
<ul>
<li>
        <a href='http://github.com/evanphx/rubinius/tree/master/doc/getting_started.txt'>Getting Started</a>
      </li>
<li>
        <a href='http://github.com/evanphx/rubinius/tree/master/INSTALL'>Installation</a>
      </li>
<li>
        <a href='http://github.com/evanphx/rubinius/tree/master/doc/common_problems.txt'>Common Problems</a>
      </li>
<li>
        If you can&#8217;t find an answer in the doc, don&#8217;t hesitate and ask on IRC in #rubinius (freenode.org). The crew&#8217;s very friendly.
      </li>
</ul>
</li>
<li id='footnote_3'>
    For a quick discussion about getting local variable&#8217;s values out of a CompiledMethod, check the [IRC logs around 19:20][9].
  </li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://programblings.com/2008/11/25/rubinius-for-the-layman-part-3-try-rubinius-in-20-minutes/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>git-config has autocomplete?</title>
		<link>http://programblings.com/2008/11/21/git-config-has-autocomplete/</link>
		<comments>http://programblings.com/2008/11/21/git-config-has-autocomplete/#comments</comments>
		<pubDate>Fri, 21 Nov 2008 21:27:54 +0000</pubDate>
		<dc:creator>Mathieu Martin</dc:creator>
				<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://programblings.com/?p=219</guid>
		<description><![CDATA[Seen on a git 1.6.0.4 installation (dunno about previous versions), installed through MacPorts 1 with the +bash_completion option.
$ git config #tab
apply.whitespace               core.compression        ...
branch.            <a href='http://programblings.com/2008/11/21/git-config-has-autocomplete/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>Seen on a git 1.6.0.4 installation (dunno about previous versions), installed through MacPorts <a href='#footnote_1'><sup>1</sup></a> with the <a href='http://trac.macports.org/wiki/howto/bash-completion'>+bash_completion</a> option.</p>
<pre><code>$ git config #tab
apply.whitespace               core.compression        ...
branch.                        core.fileMode
clean.requireForce             core.gitProxy
color.branch                   core.ignoreStat
color.branch.current           core.logAllRefUpdates
...</code></pre>
<p>With sub-options too, on words ending with a dot:</p>
<pre><code>$ git config remote.origin. #tab
remote.origin.fetch               remote.origin.receivepack      ...
remote.origin.push                remote.origin.skipDefaultUpdate</code></pre>
<p>And as usual, calling git-config with a setting name without specifying a new value displays the current value.</p>
<pre><code>$ git config remote.origin.url
git://github.com/evanphx/rubinius.git</code></pre>
<p>Git&#8217;s getting easier by the day. Awesome!</p>
<p id='footnote_1'>
  1. A recent change from <a href='http://programblings.com/2008/11/18/installing-ruby-19preview1-on-os-x-leopard/#comment-914'>a previous position</a>!</p>
]]></content:encoded>
			<wfw:commentRss>http://programblings.com/2008/11/21/git-config-has-autocomplete/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Installing ruby 1.9preview1 on OS X Leopard</title>
		<link>http://programblings.com/2008/11/18/installing-ruby-19preview1-on-os-x-leopard/</link>
		<comments>http://programblings.com/2008/11/18/installing-ruby-19preview1-on-os-x-leopard/#comments</comments>
		<pubDate>Tue, 18 Nov 2008 06:26:57 +0000</pubDate>
		<dc:creator>Mathieu Martin</dc:creator>
				<category><![CDATA[garbage out]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://programblings.com/?p=192</guid>
		<description><![CDATA[Tonight I&#8217;m trying conciseness.
Editor&#8217;s note: I failed.
I recently decided to test my git_remote_branch gem with Ruby 1.9, for the heck of it. Well, I was making sure it ran on a bunch of platforms: Windows, Ruby 1.8.7 and with the most recent Git version (1.6.0.2, get it). So it seemed fitting to check it out <a href='http://programblings.com/2008/11/18/installing-ruby-19preview1-on-os-x-leopard/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>Tonight I&#8217;m trying conciseness.</p>
<p><em>Editor&#8217;s note: I failed.</em></p>
<p>I recently decided to test my <a href='http://grb.rubyforge.org/'>git_remote_branch gem</a> with Ruby 1.9, for the heck of it. Well, I was making sure it <a href='http://programblings.com/2008/11/14/git_remote_branch-03-awesomeness-for-the-masses/'>ran on a bunch of platforms</a>: Windows, Ruby 1.8.7 and with the most recent Git version (1.6.0.2, <a href='http://git.or.cz/#download'>get it</a>). So it seemed fitting to check it out under Ruby 1.9.</p>
<p>On Leopard, the only missing dependency to Ruby 1.9 is readline 5.2. This article will present the installation of both. And help heat up your apartment.</p>
<h3 id='linux_too'>Linux too</h3>
<p>These instructions will mostly work on Linux as well (tried on Ubuntu). There will be a few minor differences though.</p>
<ul>
<li>Make sure you download the original readline from the gnu site and patch it yourself;</li>
<li>Uninstall older versions of Ruby1.9;</li>
<li>Make sure you have the basic dev tools installed, like gcc and make;</li>
<li>Skip the part about installing Xcode :-)</li>
</ul>
<h2 id='prerequisites'>Prerequisites</h2>
<p>You first need to have the Apple developer tools installed on your mac. They&#8217;re available on your installation CD. Put it in, run the installer. It&#8217;s pretty straightforward.</p>
<pre><code># in your terminal
open /Volumes/Mac\ OS\ X\ Upgrade\ DVD/Optional\ Installs/Xcode\ Tools/XcodeTools.mpkg </code></pre>
<p>If you don&#8217;t compile your own stuff often, you may have to set up your PATH variable in your ~/.bash_profile.</p>
<pre><code># file  ~/.bash_profile
export PATH=&quot;/usr/local/bin:$PATH&quot;</code></pre>
<p>Now, prepare a working directory to keep the source close to the corresponding executables.</p>
<pre><code># in your terminal
sudo mkdir -p /usr/local/src
sudo chgrp admin /usr/local/src
sudo chmod -R 775 /usr/local/src
cd /usr/local/src</code></pre>
<p>Once you&#8217;ve set yourself up, if you don&#8217;t care about the details, you can skip to the end for <a href='#cliffs_notes'>the Cliff&#8217;s notes</a>.</p>
<h2 id='installing_readline'>Installing readline</h2>
<p>This one&#8217;s not as straightforward as it could have been. The gzipped readline library available on the gnu site is 12 patches behind. It so happens that the 12th patch fixes a problem with compilation under OS X. So I applied all 12 to the code and repackaged it. The example uses that file, compiled by me.</p>
<p>You can also do do the patching by yourself if you so wish. Here&#8217;s where you can download the readline code:</p>
<ul>
<li>
<p><a href='ftp://ftp.gnu.org/gnu/readline/readline-5.2.tar.gz'>The main file</a></p>
</li>
<li>
<p><a href='ftp://ftp.gnu.org/gnu/readline/readline-5.2-patches'>The patches</a></p>
</li>
</ul>
<p>So let&#8217;s get on with the instructions to install readline from my patched package:</p>
<pre><code># in your terminal
curl -O http://s3.amazonaws.com/webmat-public/readline-5.2-patch012.tar.gz
md5 readline-5.2-patch012.tar.gz
# should be a9f37d2a22d181f8c23c6a320907917d
tar xzf readline-5.2-patch012.tar.gz
cd readline-5.2-patch012

./configure --prefix=/usr/local
make
sudo make install
cd ..</code></pre>
<h2 id='build_ruby_19'>Build Ruby 1.9</h2>
<h3 id='build_options'>Build options</h3>
<p>Note that here you have a few options as to how you want to distinguish your 1.9 stack from your main 1.8 one.</p>
<p>In the following example, I build Ruby with the &#8216;1.9&#8217; suffix, which means all executables will be suffixed with 1.9: ruby1.9, gem1.9, irb1.9, rake1.9 and so on. This approach is ideal for casual use of two versions side by side. If you don&#8217;t care about the details, skip right over the next paragraph.</p>
<p>The industrial approach would be to put ruby in a non standard directory and only add it to your path when you want to use that version (or use the explicit path to invoke executables). To go industrial, you can simply use the <code>--prefix=/usr/local/ruby1.9</code> option and then drop the <code>--program-suffix</code> argument when you run configure for Ruby. This setup is ideal if you really want to have a bunch of versions living side by side (e.g. all 1.9 versions as well as 1.8.7 in addition to the current 1.8.6).</p>
<h3 id='actual_installation_of_ruby_19'>Actual installation of Ruby 1.9</h3>
<p>Pick the most recent version or Ruby 1.9 on the <a href='ftp://ftp.ruby-lang.org/pub/ruby/'>ftp server</a>. At the time of writing, 1.9.1-preview1 is the most recent.</p>
<p>So, still from /usr/local/src:</p>
<pre><code># in your terminal
curl -O ftp://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.1-preview1.tar.gz
tar xzvf ruby-1.9.1-preview1.tar.gz
cd ruby-1.9.1-preview1
./configure --prefix=/usr/local --program-suffix=1.9 --enable-pthread --with-readline-dir=/usr/local --enable-shared
make
sudo make install</code></pre>
<p>Now you&#8217;re about to see some of the funniest looking progress indicators around. Ruby&#8217;s about making the programmer happy, and it delivers even in the details!</p>
<p>Note: the recent source packages of Ruby1.9 automatically include the documentation, as the end of the make install attests.</p>
<h2 id='try_ruby_19'>Try Ruby 1.9</h2>
<pre><code># in your terminal
ruby1.9 --version
gem1.9 --version
irb1.9</code></pre>
<p>Once inside the Ruby interactive shell,</p>
<pre><code># in irb1.9
RUBY_VERSION
#=&gt; &quot;1.9.1&quot;
stabby = -&gt;(msg=&#39;inside the stabby lambda&#39;) { puts msg }
stabby.call
# =&gt; &quot;inside the stabby lambda&quot;
stabby.call &#39;hello world&#39;
# =&gt; &quot;hello world&quot;</code></pre>
<p>Yep, Ruby 1.9 introduces the very cool stabby lambda syntax. Ruby 1.8&#8217;s lambdas couldn&#8217;t have optional parameters (unless you fiddled with *args). 1.9&#8217;s stabby lambdas can, with a syntax as clean as a simple method definition, as you just experimented.</p>
<p>Now install the gems you use everyday (or kindly make available to your peers) and help make them 1.9 compatible.</p>
<p>For the sake of the stabby lambda!</p>
<p>That&#8217;s it! (Except for those who skipped to the <a href='#cliffs_notes'>Cliff&#8217;s Notes</a>).</p>
<h2 id='cliffs_notes'>Cliff&#8217;s Notes</h2>
<pre><code># Install patched readline
cd /usr/local/src
curl -O http://s3.amazonaws.com/webmat-public/readline-5.2-patch012.tar.gz
md5 readline-5.2-patch012.tar.gz
# should be a9f37d2a22d181f8c23c6a320907917d
tar xzf readline-5.2-patch012.tar.gz
cd readline-5.2-patch012
./configure --prefix=/usr/local
make
sudo make install
cd ..

# Install Ruby1.9
curl -O ftp://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.1-preview1.tar.gz
tar xzvf ruby-1.9.1-preview1.tar.gz
cd ruby-1.9.1-preview1
./configure --prefix=/usr/local --program-suffix=1.9 --enable-pthread --with-readline-dir=/usr/local --enable-shared
make
sudo make install

# Try Ruby 1.9
ruby1.9 --version
gem1.9 --version
irb1.9

# in irb1.9
RUBY_VERSION
stabby = -&gt;(msg=&#39;inside the stabby lambda&#39;) { puts msg }
stabby.call
stabby.call &#39;hello world&#39;</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://programblings.com/2008/11/18/installing-ruby-19preview1-on-os-x-leopard/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>git_remote_branch is github-agnostic</title>
		<link>http://programblings.com/2008/11/17/git_remote_branch-is-github-agnostic/</link>
		<comments>http://programblings.com/2008/11/17/git_remote_branch-is-github-agnostic/#comments</comments>
		<pubDate>Mon, 17 Nov 2008 12:15:05 +0000</pubDate>
		<dc:creator>Mathieu Martin</dc:creator>
				<category><![CDATA[git_remote_branch]]></category>

		<guid isPermaLink="false">http://programblings.com/?p=180</guid>
		<description><![CDATA[Josh Knowles recently suggested that maybe I could merge grb’s functionality to the github gem.
Both gems being command-line tools that help you use Git in a friendlier manner, the question makes a lot of sense. It makes so much sense in fact, that I decided to blog about it. A post about it will scale <a href='http://programblings.com/2008/11/17/git_remote_branch-is-github-agnostic/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://joshknowles.com">Josh Knowles</a> recently suggested that maybe I could merge grb’s functionality to the github gem.</p>
<p>Both gems being command-line tools that help you use Git in a friendlier manner, the question makes a lot of sense. It makes so much sense in fact, that I decided to blog about it. A post about it will scale much better to answer other users who may potentially ask the same question.</p>
<p>So here’s a slightly edited excerpt from the answer I gave him. And yes, I also ramble in email.</p>
<blockquote><p>I’ve seen what Scott added to the github gem. Pretty cool stuff indeed. I think the idea of merging with the github gem has merit. I definitely can see a future where we start having too many distinct command-line tools that help deal with Git’s sometimes obscure or numerous commands.</p>
<p>However I’m not sure I’d like to merge grb into the gh gem, despite the additional awareness it would get. Here’s why.</p>
<p>In my mind, the github gem should be mostly features about GitHub itself, like managing pull requests (the way GitHub does them). It’s starting to accumulate features that probably aren’t GitHub-specific, which I don’t mind, of course. But grb’s features really are GitHub-agnostic. I’ve started working on it before I even started using GitHub, in fact :-)</p>
<p>Reinforcing the previous point, I wouldn’t want someone who doesn’t use GitHub to not realize the features of grb are available to him because they’re included in a gem called ‘github’ ;-)</p>
<p>Also, one of the goals of git_remote_branch is to explicitly teach the underlying git commands. I do this by always spewing out the underlying commands in red, and by having the explain command. I’m pretty sure an unsuspecting user would wonder what hit him if a few of the github commands started spewing out red text in his console ;-) Having explain for a few commands (ported from grb) and not for the rest of the github gem’s commands would be weird, too.</p>
<p>There’s also a few other architectural decisions of grb that may not fit with github’s, like having aliases. Once again, grb being a teaching tool, I want to offer a bunch of aliases for forgetful people like me. So far I don’t see anything like aliases in github and I’m not sure how the authors of github-gem would react to a pull request polluting it with a bunch of aliases ;-)</p>
<p>Last but not least, the github gem already has a track command, which conflicts with grb’s. github’s is used to track a new remote repo in your local repo while grb’s is to track another branch from your current remote repo.</p></blockquote>
<p>So git_remote_branch is GitHub-agnostic. You can use it with any Git hosting solution: GitHub, your own <a href="http://scie.nti.st/2007/11/14/hosting-git-repositories-the-easy-and-secure-way">Gitosis</a> / gitweb / <a href="http://gitorious.org/projects/gitorious">Gitorious installation</a>, <a href="http://gitorious.org">Gitorious.org</a> hosting, Rubyforge or any other.</p>
<p>Better, grb supports working with all of them at the same time. All grb commands support an optional origin argument.</p>
<p><a href="http://grb.rubyforge.org">Learn more about git_remote_branch</a></p>
]]></content:encoded>
			<wfw:commentRss>http://programblings.com/2008/11/17/git_remote_branch-is-github-agnostic/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>git_remote_branch 0.3 &#8211; Awesomeness for the masses</title>
		<link>http://programblings.com/2008/11/14/git_remote_branch-03-awesomeness-for-the-masses/</link>
		<comments>http://programblings.com/2008/11/14/git_remote_branch-03-awesomeness-for-the-masses/#comments</comments>
		<pubDate>Fri, 14 Nov 2008 17:59:04 +0000</pubDate>
		<dc:creator>Mathieu Martin</dc:creator>
				<category><![CDATA[garbage in]]></category>
		<category><![CDATA[garbage out]]></category>
		<category><![CDATA[git_remote_branch]]></category>

		<guid isPermaLink="false">http://programblings.com/?p=149</guid>
		<description><![CDATA[Awesomeness for the masses
git_remote_branch 0.3 has been released!
Previous releases were pretty much only usable by rubyists on OS X. 

No more. This release is mostly focused on making sure git_remote_branch works on a broader range of platforms. A few actual features squeaked in, but nothing big like introducing new commands.
If you don&#8217;t care about the <a href='http://programblings.com/2008/11/14/git_remote_branch-03-awesomeness-for-the-masses/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<h2 id="awesomeness_for_the_masses">Awesomeness for the masses</h2>
<p>git_remote_branch 0.3 has been released!</p>
<p>Previous releases were pretty much only usable by rubyists on OS X. </p>
<p><a title="Works on my machine logo" href="http://www.codinghorror.com/blog/archives/000818.html"><img src="http://programblings.com/wp-content/uploads/2008/06/works-on-my-machine.png" alt="Works on my machine logo" /></a></p>
<p>No more. This release is mostly focused on making sure git_remote_branch works on a broader range of platforms. A few actual features squeaked in, but nothing big like introducing new commands.</p>
<p>If you don&#8217;t care about the details just type the following at your command-line.</p>
<pre><code>sudo gem install git_remote_branch
</code></pre>
<p>And check the help</p>
<pre><code>grb --help
</code></pre>
<p>If you encounter installation problems, refer to <a href="http://grb.rubyforge.org">the readme</a>.</p>
<h3 id="platforms">Platforms</h3>
<p>git_remote_branch 0.3 has been tested with the following configurations:</p>
<ul>
<li>OS X Leopard / Ruby 1.8.6 / Git 1.5.4.3 and 1.6.0.2</li>
<li>OS X Leopard / Ruby 1.9.1 / Git 1.5.4.3 and 1.6.0.2</li>
<li>Ubuntu Intrepid Ibex / Ruby 1.8.7 / Git 1.5.6.3</li>
<li>Windows XP / Ruby 1.8.6 / Git 1.6.0.2 (the msys version)</li>
</ul>
<h3 id="features">Features</h3>
<h4 id="better_track">Better track</h4>
<p>Track now works even if you already have a local branch of the same name. It uses git config instead of branch &#8212;track in that case. The subtlety can be observed by running (from a git repository):</p>
<pre><code>grb explain track master
grb explain track non_existent_branch
</code></pre>
<h4 id="force_the_use_of_a_specific_git_executable">Force the use of a specific git executable</h4>
<p>Set the environment variable GRB_GIT to point to it and grb will use this one for all its operations.</p>
<h2 id="documentation_">Documentation </h2>
<p>I&#8217;ve also worked quite a bit on the actual documentation. I used to be ashamed at the quality and availability of the documentation of git_remote_branch. At last I&#8217;ll be able to sleep at night :-)</p>
<h3 id="git_remote_branch_in_a_nutshell">git_remote_branch in a nutshell</h3>
<p>I&#8217;ve rewritten the intro of the readme to be (hopefully) a bit clearer.</p>
<blockquote>
<p>git_remote_branch is a simple command-line tool that makes it very easy to manipulate branches published in shared repositories.</p>
<p>It achieves this goal by sticking to a few principles:</p>
<ul>
<li>keep grb&#8217;s commands extremely regular (they all look alike)</li>
<li>support aliases for commands</li>
<li>print all commands it runs on your behalf in red, so you eventually learn them</li>
</ul>
<p>Another nice thing about git_remote_branch is that it can simply explain a command (print out all the corresponding git commands) instead of running them on your behalf.</p>
<p>Note: git_remote_branch assumes that the local and<br />
  remote branches have the same name. Multiple remote<br />
  repositories (or origins) are supported.</p>
</blockquote>
<h3 id="documentation_availability">Documentation availability</h3>
<p>The main readme is now available on the main <a href="http://grb.rubyforge.org">grb page on rubyforge</a>.</p>
<h3 id="documentation_quality">Documentation quality</h3>
<p>I&#8217;ve added clearer information on getting grb to run in different kinds of situation, due to helpful feedback from <a href="http://github.com/axelson">Axelson</a> and <a href="http://github.com/grempe">Glenn Rempe</a>.</p>
<p>I&#8217;ve also added some information for playing with the code for git_remote_branch (test dependencies and so on). See the end of <a href="http://grb.rubyforge.org">the readme</a>.</p>
<p>Finally, I&#8217;ve updated the links section quite a bit:</p>
<table>
<tr>
<th>Documentation</th>
<td><a href="http://grb.rubyforge.org">http://grb.rubyforge.org</a></td>
</tr>
<tr>
<th>News</th>
<td><a href="http://programblings.com/category/git/git\_remote\_branch/">http://programblings.com/category/git/git_remote_branch/</a></td>
</tr>
<tr>
<th>Bug tracker</th>
<td><a href="http://git-remote-branch.lighthouseapp.com/projects/19198-git\_remote\_branch/overview">Lighthouse</a></td>
</tr>
<tr>
<th>Code</th>
<td><a href="http://github.com/webmat/git_remote_branch">http://github.com/webmat/git_remote_branch</a></td>
</tr>
<tr>
<th>Mailing list</th>
<td><a href="http://groups.google.com/group/git_remote_branch">http://groups.google.com/group/git_remote_branch</a></td>
</tr>
</table>
<h2 id="dare">Dare</h2>
<p>I dare you to find a platform on which git_remote_branch doesn&#8217;t work :-)</p>
<p>If you do, please send me feedback through GitHub or via email. I&#8217;m using gmail and, as usual, I go by the handle of webmat.</p>
<h3 id="last_note_the_git_remote_branch_gem_on_github">Last note: the git_remote_branch gem on GitHub</h3>
<p>Excerpt from the readme:</p>
<blockquote>
<p>Note that the only stable version of the gem you should trust is the one from <strong>Rubyforge</strong>. The GitHub gem is a development gem. The GitHub gem WILL be rebuilt with the same version number, and other horrible things like that. If you use the GitHub version of git_remote_branch, children will die!</p>
</blockquote>
<p>You&#8217;ve been warned.</p>
]]></content:encoded>
			<wfw:commentRss>http://programblings.com/2008/11/14/git_remote_branch-03-awesomeness-for-the-masses/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Installing gems with command-line interfaces on Ubuntu 8.10</title>
		<link>http://programblings.com/2008/11/04/installing-gems-with-command-line-interfaces-on-ubuntu-810/</link>
		<comments>http://programblings.com/2008/11/04/installing-gems-with-command-line-interfaces-on-ubuntu-810/#comments</comments>
		<pubDate>Tue, 04 Nov 2008 15:50:41 +0000</pubDate>
		<dc:creator>Mathieu Martin</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[command line]]></category>
		<category><![CDATA[gem]]></category>

		<guid isPermaLink="false">http://programblings.com/?p=137</guid>
		<description><![CDATA[To install any ruby gem which has a command-line interface on Ubuntu 8.10, you have to add a path to your PATH environment variable. In your .bashrc file, add the following line:
export PATH=$PATH:/var/lib/gems/1.8/bin
Also worth noting is the fact that the default ruby interpreter on 8.10 is back to the 1.8 branch: it&#8217;s 1.8.7 (1.9 was <a href='http://programblings.com/2008/11/04/installing-gems-with-command-line-interfaces-on-ubuntu-810/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>To install any ruby gem which has a command-line interface on Ubuntu 8.10, you have to add a path to your PATH environment variable. In your .bashrc file, add the following line:</p>
<pre>export PATH=$PATH:/var/lib/gems/1.8/bin</pre>
<p>Also worth noting is the fact that the default ruby interpreter on 8.10 is back to the 1.8 branch: it&#8217;s 1.8.7 (1.9 was the default on 8.04 iirc). 1.9  also be installed right besides 1.8.</p>
<pre>$ ruby --version
ruby 1.8.7 (2008-08-11 patchlevel 72) [i486-linux]
$ ruby1.9 --version
ruby 1.9.0 (2008-06-20 revision 17482) [i486-linux]</pre>
<p>Neither comes installed by default, however. You must install them explicitly.</p>
<pre>sudo aptitude install ruby irb rubygems</pre>
<p>While I&#8217;m at it, why not mention that rubygems 1.2.0 is installed by default. It doesn&#8217;t want to update to 1.3.0 with the usual &#8220;gem update &#8211;system&#8221; command. Since it&#8217;s not my main machine I didn&#8217;t investigate further, but the suggestion is to use apt-get or aptitude. The repos don&#8217;t seem to be up to date with 1.3.0, but rather with a version named something like 1.3.0really1.2.0.</p>
]]></content:encoded>
			<wfw:commentRss>http://programblings.com/2008/11/04/installing-gems-with-command-line-interfaces-on-ubuntu-810/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Two Shoulda best practices</title>
		<link>http://programblings.com/2008/10/31/two-shoulda-best-practices/</link>
		<comments>http://programblings.com/2008/10/31/two-shoulda-best-practices/#comments</comments>
		<pubDate>Fri, 31 Oct 2008 18:38:58 +0000</pubDate>
		<dc:creator>Mathieu Martin</dc:creator>
				<category><![CDATA[garbage out]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[shoulda]]></category>

		<guid isPermaLink="false">http://programblings.com/?p=117</guid>
		<description><![CDATA[In praise of Shoulda macros
Shoulda contexts let you to share setup code between different tests. This is for me one of Shoulda’s most attractive features.
When you combine this with the technique of defining your own macros to encapsulate assertions or setups that come up often, you end up with seriously DRY and readable tests.
I see <a href='http://programblings.com/2008/10/31/two-shoulda-best-practices/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<h2 id="in_praise_of_shoulda_macros">In praise of Shoulda macros</h2>
<p>Shoulda contexts let you to share setup code between different tests. This is for me one of Shoulda’s most attractive features.</p>
<p>When you combine this with the technique of defining your own macros to encapsulate assertions or setups that come up often, you end up with seriously DRY and readable tests.</p>
<p>I see a few different kinds of Shoulda macros:</p>
<h3 id="assertion_macros">Assertion macros</h3>
<p>Assertions macros often begin with should_. They encapsulate one or a few assertions.</p>
<p>For ActiveRecord models:</p>
<pre><code>should_require_attributes :name, :phone_number
</code></pre>
<p>They may even accept a block and do assertions on its execution, like <a href="http://programblings.com/2008/10/27/this-should_raise-an-exception/">should_raise</a>:</p>
<pre><code>should_raise(LoadError, :message =&gt; /vespene/) do
  require "more vespene gas"
end
</code></pre>
<p>To learn more about assertion macros, you can take a look at <a href="http://technicalpickles.com/posts/shoulda-macros-allows-you-to-embrace-your-inner-slacker">Shoulda macros allows you to embrace your inner slacker</a> by Josh Nichols. Inner slacker? I’m right there!</p>
<h3 id="setup_macros">Setup macros</h3>
<p>This kind of macro encapsulates a setup that comes up often in your test suite. One inspired by Restful Authentication’s login_as helper method could be used like this:</p>
<pre><code>logged_in_as :mat do
  # Shoulda tests
end
</code></pre>
<p>These kinds of macros accept a block that defines more Shoulda tests, rather than a block of code testing your app per se.</p>
<h3 id="turnkey_macros">Turnkey macros</h3>
<p>Turnkey macros are beefed up assertion macros. The main difference is their extent. They contain many contexts and a lot of should blocks. They usually accept substantial options hashes or are configured with a setup block. Like should_be_restful in the following example, inspired by the Shoulda documentation:</p>
<pre><code>logged_in_as :stranger do
  should_be_restful do |resource|
    resource.create.params   = { :subject =&gt; "test", :body =&gt; "message" }
    resource.denied.actions  = [:edit, :update, :destroy]
    resource.denied.redirect = "login_url"
    resource.denied.flash    = /only the owner can/i
  end
end
</code></pre>
<h2 id="two_shoulda_best_practices_around_setup_macros">Two Shoulda best practices around setup macros</h2>
<p>This article is specifically about setup macros.</p>
<p>Here’s the implementation of a pretty generic Shoulda macro I could define in my test_helper<a href="#footnote_star">*</a>. This is an implementation of the macro I mentioned at the beginning:</p>
<pre><code># Sets the current person in the session from the person fixtures.
def self.logged_in_as(person, &amp;block)
  context "logged in as #{person}" do
    setup do
      @request.session[:person] = people(person).id
    end

    yield
  end
end
</code></pre>
<p>Which can then be used like this in any controller test:</p>
<pre><code>logged_in_as :mat do
  # tests for users
end

logged_in_as :admin do
  # tests for admin
end
</code></pre>
<p>Setup macros have a very subtle catch, however. Here’s a modified version of the first example above:</p>
<pre><code>logged_in_as :mat do
  setup do
    @request.session[:last_login] = Time.now
  end
  # Some tests
end
</code></pre>
<p>The setup block you see here is never going to be executed. Why?</p>
<p>If we were to replace the logged_in_as macro by the actual code it contains, here’s what it would look like:</p>
<pre><code>context "logged in as #{person}" do
  setup do
    @request.session[:person] = people(person).id
  end
  setup do
    @request.session[:last_login] = Time.now
  end
  # Some tests
end
</code></pre>
<p>Does that make sense? Not so sure.</p>
<p>Shoulda doesn’t like to have multiple setup blocks for a given context. That part <em>does</em> make sense.</p>
<h2 id="best_practice_1_always_describe_the_situation_with_a_context">Best practice #1: Always describe the situation with a context.</h2>
<p>You should always describe the situation in which your test takes place (what your setup is doing) with a context.</p>
<pre><code>logged_in_as :mat do
  context "with last login set to now" do
    setup do
      @request.session[:last_login] = Time.now
    end
    # Some tests
  end
end
</code></pre>
<p>Fair enough. We blame it on the user of the macro :-)</p>
<p>Since we’re using Ruby, most of us are probably in agreement with Matz’ “Make the programmer happy” motto.</p>
<p>So can we also solve the problem from the other end? Create a setup macro that supports a direct inner setup block? Of course we can, this is <strong>Ru</strong>by, not <strong>V</strong>B.</p>
<h2 id="best_practice_2_create_setup_macros_that_support_a_second_setup_block">Best practice #2: Create setup macros that support a second setup block</h2>
<p>A setup is grafted to a context that describes it. As the creator of the macro, I don’t know what crazy setup blocks programmers will put inside their macro. So I simply create a mute context:</p>
<pre><code># Sets the current person in the session from the person fixtures.
def self.logged_in_as(person, &amp;block)
  context "logged in as #{person}" do
    setup do
      @request.session[:person] = people(person).id
    end

    context '' do
      yield
    end
  end
end
</code></pre>
<p>Now my macro supports the following test without a hitch:</p>
<pre><code>logged_in_as :mat do
  setup do
    @request.session[:last_login] = Time.now
  end
  # Some tests
end
</code></pre>
<p>And of course, programmers who stick to best practice #1 can still write a cleaner test without a problem. The awesomeness of contexts lies in the fact that they can be nested:</p>
<pre><code>logged_in_as :mat do
  context "with last login set to now" do
    setup do
      @request.session[:last_login] = Time.now
    end
    # Some tests
  end
end
</code></pre>
<h2 id="conclusion">Conclusion</h2>
<p>Best practice #1 is simple. A setup block should be described by its encompassing context. It’s a question of readability. Nesting a setup block immediately inside a Shoulda macro is a dubious practice.</p>
<p>Best practice #2 is a more pragmatic solution to the problem. Ok, nesting a block right inside a macro isn’t always the best idea.</p>
<p>But when you don’t have the macro right under your nose, it may take you a while before you think about looking at said macro. I don’t know about you, but I have a tendency to have a great deal of confidence in macros that work well across my test suite.</p>
<p>So after you’ve spent an hour questioning Shoulda (or your sanity, or whether you should have become a gardener instead of a software developer) because your setup block isn’t executing, best practice #2 starts to make sense.</p>
<p>It may or may not be necessary in all your setup macros. I find it’s especially useful for macros that are generic enough to be used across your test suite. Or most of all, in setup macros you will share with the world.</p>
<p>Best practice #2 makes setup macros bulletproof to the problem of multiple setups.</p>
<p>Now go refactor your setup macros!</p>
<p>To learn more about Shoulda, check out <a href="http://thoughtbot.com/projects/shoulda">Thoughtbot’s comprehensive documentation</a>.</p>
<p id="footnote_star">* A note on where to define Shoulda macros. Shoulda 2 can now auto load macros that are in the right location. This will help you keep your test_helper cleaner. Read more about it succinctly in <a href="http://technicalpickles.com/posts/shoulda-can-automatically-load-custom-macros">Shoulda can automatically load custom macros</a> by Josh Nichols or in the <a href="http://giantrobots.thoughtbot.com/2008/9/30/shoulda-2-0">Shoulda 2.0 release post</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://programblings.com/2008/10/31/two-shoulda-best-practices/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>This should_raise an exception</title>
		<link>http://programblings.com/2008/10/27/this-should_raise-an-exception/</link>
		<comments>http://programblings.com/2008/10/27/this-should_raise-an-exception/#comments</comments>
		<pubDate>Mon, 27 Oct 2008 05:39:58 +0000</pubDate>
		<dc:creator>Mathieu Martin</dc:creator>
				<category><![CDATA[garbage out]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[shoulda]]></category>

		<guid isPermaLink="false">http://programblings.com/?p=104</guid>
		<description><![CDATA[If you use Shoulda and, like me, you hate Test::Unit’s assert_raise(), I may have something of interest for you.
Why the hate?
Well, assert_raise accepts an *args list of exception types.
If you don’t pass any, you get some nonsense because an empty array doesn’t jive with the exception raised by your block. Useful. So if you don’t <a href='http://programblings.com/2008/10/27/this-should_raise-an-exception/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>If you use Shoulda and, like me, you hate Test::Unit’s assert_raise(), I may have something of interest for you.</p>
<h2 id="why_the_hate">Why the hate?</h2>
<p>Well, assert_raise accepts an <code>*args</code> list of exception types.</p>
<p>If you don’t pass any, you get some nonsense because an empty array doesn’t jive with the exception raised by your block. Useful. So if you don’t care what exception is raised, assert_raise isn’t gonna help you.</p>
<p>Also, assert_raise doesn’t let you specify what kind of exception message you’re expecting. I actually don’t mind that a given assertion should verify exactly one thing. On the other hand I have to jump through hoops to capture the exception if I want to assert on the error message.</p>
<h2 id="a_shoulda_macro_to_the_rescue">A shoulda macro to the rescue</h2>
<p>As usual, Shoulda is there to help us keep our test code DRY and intuitive. I’ve concocted a useful macro called should_raise. <a href="http://gist.github.com/20019">Here’s the gist</a>:</p>
<p>It must be called with the block you expect to raise an exception, of course. You can also specify two optional arguments, the exception type and the message.</p>
<h3 id="kindof_or_instanceof">:kind_of or :instance_of</h3>
<p>If not specified, an assertion is made that an exception was raised, but with no restriction on the type of the exception.</p>
<p>If you specify :kind_of, the assertion will be that much more precise. It will check that the exception raised was of the type specified, or a descendant.</p>
<p>If you specify :instance_of, the assertion is now that the exception raised was <em>exactly</em> of the type specified.</p>
<p>A shorthand is also available, where the type of the exception is supplied directly, like should_raise(LoadError), in which case the assertion is the same as with :instance_of.</p>
<p>In all of these cases, exactly one assertion is generated, whether or not :type is specified.</p>
<h3 id="message">:message</h3>
<p>If :message is specified, a second assertion will be added in order to make sure the error message matches the parameter. This can either be a string or a regex. The assertion is simply an assert_match.</p>
<p>If not specified, no assertion is generated for the message.</p>
<h2 id="examples">Examples</h2>
<pre><code><strong>should_raise do
  require "more vespene gas"
end
# 1 assertion

should_raise(LoadError) do
  require "more vespene gas"
end
# 1 more restrictive assertion

should_raise(:instance_of =&gt; LoadError) do
  require "more vespene gas"
end
# 1 assertion, the same as should_raise(LoadError)

should_raise(:kind_of =&gt; ScriptError) do
  require "more vespene gas"
end
# 1 assertion, slightly less strict than with :instance_of (note: LoadError &lt; ScriptError)

should_raise(:message =&gt; "no such file to load") do
  require "more vespene gas"
end
# 2 assertions

should_raise(:message =&gt; /vespene/) do
  require "more vespene gas"
end
# 2 assertions

should_raise(LoadError, :message =&gt; "such file to load") do
  require "more vespene gas"
end
# 2 assertions

should_raise(:kind_of =&gt; LoadError, :message =&gt; "file to load") do
  require "more vespene gas"
end
# 2 assertions

should_raise(:instance_of =&gt; LoadError, :message =&gt; "to load") do
  require "more vespene gas"
end
# 2 assertions
</strong></code></pre>
<h2 id="conclusion">Conclusion</h2>
<p>As you can tell, I’m eagerly awaiting <a href="http://www.starcraft2.com/">Starcraft II</a>.</p>
<p>No, I meant: check out the code on <a href="http://gist.github.com/20019">gist 20019</a>. I’ve included a reasonable suite of unit tests in a comment at the end.</p>
<p>Feel free to use it in any way you like. Just make sure you don’t sue me.</p>
]]></content:encoded>
			<wfw:commentRss>http://programblings.com/2008/10/27/this-should_raise-an-exception/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Git global ignores</title>
		<link>http://programblings.com/2008/10/22/git-global-ignores/</link>
		<comments>http://programblings.com/2008/10/22/git-global-ignores/#comments</comments>
		<pubDate>Thu, 23 Oct 2008 02:08:36 +0000</pubDate>
		<dc:creator>Mathieu Martin</dc:creator>
				<category><![CDATA[garbage out]]></category>
		<category><![CDATA[git]]></category>

		<guid isPermaLink="false">http://programblings.com/?p=96</guid>
		<description><![CDATA[I don’t know about you, but for me, using git is so low-friction that I use it basically for everything where I may need a powerful undo button. In other words, I don’t use it only for team software development projects.
For example, I’ve frequently used it in the past to keep track of the modifications <a href='http://programblings.com/2008/10/22/git-global-ignores/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>I don’t know about you, but for me, using git is so low-friction that I use it basically for everything where I may need a powerful undo button. In other words, I don’t use it only for team software development projects.</p>
<p>For example, I’ve frequently used it in the past to keep track of the modifications I make to an article I work on for few days. God knows <a href="http://programblings.com/2008/04/01/rubinius-for-the-layman-part-1-rubies-all-the-way-down/">I</a> <a href="http://programblings.com/2008/04/15/rubinius-for-the-layman-part-2-how-rubinius-is-friendly/">write</a> <a href="http://programblings.com/2008/06/07/the-illustrated-guide-to-recovering-lost-commits-with-git/">a</a> <a href="http://programblings.com/2008/06/23/git-remote-branches/">lot</a> <a href="http://programblings.com/2008/07/21/setting-up-a-long-term-fork-with-git/">of</a> <a href="http://programblings.com/2008/08/06/time-to-git-collaborating-with-git_remote_branch/">these</a>. There’s a reason I called this blog Prog<strong>ramblings</strong> ;-)</p>
<p>To be honest, I’m using git as I write even this short article.</p>
<p>I also use it for trivial one evening coding projects. As soon as I spend more than an hour on code, whatever it is, I’ll usually create a local git repo for it.</p>
<p>One of the annoying things I realized when creating repositories more and more often, is that I always ended up ignoring the same files. Over and over again. Boring.</p>
<p>Fortunately for me, git can be configured to take into consideration a global ignore file. Heck, I can even create a system-wide ignore file if I want (check out git config’s doc for more info).</p>
<h2 id="configure_your_personal_ignore_file">Configure your personal ignore file</h2>
<p>I like to stick to conventions so I call my file .gitignore, and I put it in my home directory. But that’s up to you, really.</p>
<pre><code>git config --global core.excludesfile ~/.gitignore
</code></pre>
<p>Note that there’s one little gotcha to be aware of. If you prefer to edit the .gitconfig file directly (or if you use a weird shell), git expects an absolute path. In the example above, bash converted the ~ shorthand to my home directory.</p>
<p>Now I just add ignore globs to it like any other project level (directory level, really) git ignore file.</p>
<pre><code>echo .DS_Store &gt;&gt; ~/.gitignore
</code></pre>
<p id="you8217ll_still_have_to_ignore">Once I&#8217;ve ignored all my favorite useless files, I can get cracking and never worry about them again.</p>
<h2>I still have to ignore files</h2>
<p>When I create a new repository on which people may actually contribute, I’ll still create a proper ignore file, however. Otherwise I’d convey the message that I consider contributors as slaves who only deserve the boring work of creating ignore files. Since I’m pure of heart, that’s not how I roll.</p>
]]></content:encoded>
			<wfw:commentRss>http://programblings.com/2008/10/22/git-global-ignores/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Discovering great tools &#8211; qgit</title>
		<link>http://programblings.com/2008/09/19/discovering-great-tools-qgit/</link>
		<comments>http://programblings.com/2008/09/19/discovering-great-tools-qgit/#comments</comments>
		<pubDate>Fri, 19 Sep 2008 18:13:32 +0000</pubDate>
		<dc:creator>Mathieu Martin</dc:creator>
				<category><![CDATA[git]]></category>
		<category><![CDATA[tool]]></category>

		<guid isPermaLink="false">http://programblings.com/?p=90</guid>
		<description><![CDATA[I can&#8217;t believe I hadn&#8217;t taken the time to try out qgit yet. Check this out:
Install qgit from source on Leopard with these instructions.
Warning: installing the Qt 4.3 prerequisite takes an eternity or two (instructions for that are included as well).
Also note that you should make sure to use the newest versions of the downloads: <a href='http://programblings.com/2008/09/19/discovering-great-tools-qgit/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>I can&#8217;t believe I hadn&#8217;t taken the time to try out <a href="http://digilander.libero.it/mcostalba/">qgit</a> yet. Check this out:</p>
<div id="attachment_92" class="wp-caption alignnone" style="width: 310px"><a href="http://programblings.com/wp-content/uploads/2008/09/qgit.png"><img class="size-medium wp-image-92" title="qgit" src="http://programblings.com/wp-content/uploads/2008/09/qgit.png" alt="Screenshot of the main qgit screen" width="300" height="212" /></a><p class="wp-caption-text">Screenshot of the main qgit screen</p></div>
<p>Install qgit from source on Leopard with <a href="http://rails.wincent.com/wiki/Installing_QGit_2.0rc1_on_Mac_OS_X_Tiger">these instructions</a>.</p>
<p>Warning: installing the Qt 4.3 prerequisite takes an eternity or two (instructions for that are included as well).</p>
<p>Also note that you should make sure to use the newest versions of the downloads: the instructions point to an old 2.0rc1 release of qgit.</p>
]]></content:encoded>
			<wfw:commentRss>http://programblings.com/2008/09/19/discovering-great-tools-qgit/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Time to git collaborating with git_remote_branch</title>
		<link>http://programblings.com/2008/08/06/time-to-git-collaborating-with-git_remote_branch/</link>
		<comments>http://programblings.com/2008/08/06/time-to-git-collaborating-with-git_remote_branch/#comments</comments>
		<pubDate>Wed, 06 Aug 2008 19:28:35 +0000</pubDate>
		<dc:creator>Mathieu Martin</dc:creator>
				<category><![CDATA[blogging]]></category>
		<category><![CDATA[garbage in]]></category>
		<category><![CDATA[garbage out]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[git_remote_branch]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://programblings.com/2008/08/06/time-to-git-collaborating-with-git_remote_branch/</guid>
		<description><![CDATA[git_remote_branch 0.2.6 is out!
I&#8217;ve just released a new and improved version of git_remote_branch. Code named 0.2.6!
Ok, I admit. I haven&#8217;t really begun using code names.
I&#8217;m promoting the project from a pre-alpha to an alpha release. There&#8217;s still a lot to do, but the stability and &#8220;testedness&#8221; have improved greatly. Following are both sides of the <a href='http://programblings.com/2008/08/06/time-to-git-collaborating-with-git_remote_branch/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<h2>git_remote_branch 0.2.6 is out!</h2>
<p>I&#8217;ve just released a new and improved version of git_remote_branch. Code named 0.2.6!</p>
<p>Ok, I admit. I haven&#8217;t really begun using code names.</p>
<p>I&#8217;m promoting the project from a pre-alpha to an alpha release. There&#8217;s still a lot to do, but the stability and &#8220;testedness&#8221; have improved greatly. Following are both sides of the maturity story.</p>
<h3>The project is maturing</h3>
<ul>
<li>grb got its first contributor, <a href="http://github.com/kch">Caio Chassot</a></li>
<li>I added a lot of tests, both unit and functional
<ul>
<li> there might even be <a href="http://github.com/webmat/git_remote_branch/tree/master/test/helpers/shoulda_functional_helpers.rb#L40">interesting</a> <a href="http://github.com/webmat/git_remote_branch/tree/master/vendor/capture_fu.rb">stuff</a> to see in there for those who need to test command-line tools</li>
</ul>
</li>
<li> the gem can now be installed directly from RubyForge</li>
<li> git_remote_branch now has a <a href="http://groups.google.com/group/git_remote_branch">Google Group</a></li>
</ul>
<h3>The project is still immature</h3>
<ul>
<li>it swears a lot</li>
<li>no rubyforge page, despite the project being on rubyforge (at <a href="http://rubyforge.org/projects/grb/">rubyforge.org/projects/grb</a>)</li>
<li>no real documentation other than running grb help</li>
<li>very little in code documentation. On the other hand the code is spectacularly clean and readable, so that&#8217;s completely unnecessary. Just kidding.</li>
</ul>
<h3>What&#8217;s new in 0.2.6?</h3>
<p>Three new actual features</p>
<ul>
<li>the &#8216;rename&#8217; command, contributed by Caio Chassot</li>
<li>the &#8216;publish&#8217; command</li>
<li>the −−silent option to completely mute grb output as well as every git command run by grb on your behalf</li>
</ul>
<p>And other stuff</p>
<ul>
<li>the grb bin file now works when symlinked (also thanks to Caio Chassot)</li>
<li>lots of unit and functional tests</li>
<li>bug fixes</li>
<li>more flexibility for running grb outside of a git repository (e.g. for &#8216;explain&#8217; or &#8216;help&#8217;)</li>
<li>now officially under the MIT license</li>
<li>refactored a bunch of rake tasks</li>
</ul>
<h2>Git the new version</h2>
<p>To install the newest version of the gem, simply run</p>
<pre><strong>sudo gem install git_remote_branch</strong></pre>
<p>If you really want to be on the bleeding edge you can also get it on GitHub. Note however that in &#8216;bleeding edge&#8217; the word &#8216;bleeding&#8217; is still the most important one at that point.</p>
<pre><strong>git clone git://github.com/webmat/git_remote_branch.git
cd git_remote_branch
rake install</strong></pre>
<p>The &#8216;install&#8217; task will run the tests before installing so you&#8217;ll need Shoulda, mocha, redgreen and ruby-debug for that approach.</p>
<h2>Not familiar with git_remote_branch?</h2>
<h3>What it is</h3>
<p>The basic idea for git_remote_branch is to trivialize the interaction with remote branches. The first goal is to make the commands for the simple situations easy.</p>
<p>The secondary goal, is to help you learn the commands by seeing them displayed in a beautiful shade of red each time you use grb, along with git&#8217;s output.</p>
<p>git_remote_branch lets you</p>
<ul>
<li><strong>create</strong> local-remote branche pairs, and tracks the remote branch automatically (for automatic merges when you git pull)</li>
<li><strong>publish</strong> a local branch as a remote branch, very similar to create</li>
<li><strong>delete</strong> local-remote branch pairs</li>
<li><strong>track</strong> a remote-only branch</li>
<li><strong>rename</strong> a local-remote branch pair</li>
<li><strong>explain</strong> by simply spitting out the necessary commands to do any of the above</li>
</ul>
<h3>How to use it</h3>
<h4>explain</h4>
<p>If you simply want to use grb as a cheatsheet (and run nothing on your behalf), you can use the explain command:</p>
<pre><strong>$ grb explain create
git_remote_branch version 0.2.6

List of operations to do to create a new remote branch and track it locally:

<span style="color: #ff0000;">git push origin current_branch:refs/heads/branch_to_create
git fetch origin
git branch −−track branch_to_create origin/branch_to_create
git checkout branch_to_create</span></strong></pre>
<p>or</p>
<pre><strong>$ grb explain create my_branch my_origin
git_remote_branch version 0.2.6

List of operations to do to create a new remote branch and track it locally:

<span style="color: #ff0000;">git push my_origin current_branch:refs/heads/my_branch
git fetch my_origin
git branch −−track my_branch my_origin/my_branch
git checkout my_branch</span></strong></pre>
<p>Notice that you can specify any normally expected parameter you&#8217;d normally include and &#8216;explain&#8217; will use them in the list of commands it suggests.</p>
<p>Even better, if you&#8217;re in your repository, the current branch is going to be taken into account:</p>
<pre><strong>(master) $ grb explain create my_branch my_origin
git_remote_branch version 0.2.6

List of operations to do to create a new remote branch and track it locally:

<span style="color: #ff0000;">git push my_origin master:refs/heads/my_branch
git fetch my_origin
git branch −−track my_branch my_origin/my_branch
git checkout my_branch</span></strong></pre>
<p>Of course, &#8216;explain&#8217; works for all commands: create, publish, delete, track and rename.</p>
<h4>The main commands</h4>
<p>I&#8217;m not going to painstakingly give an example for each command. I&#8217;ll only give two, to show how git&#8217;s responses are displayed when running grb without &#8216;explain&#8217;:</p>
<pre><strong>(master)$ grb create test_branch
git_remote_branch version 0.2.6

<span style="color: #ff0000;">git push origin master:refs/heads/test_branch</span>
Total 0 (delta 0), reused 0 (delta 0)
To git@github.com:webmat/git_remote_branch.git
 * [new branch]      master -&gt; test_branch

<span style="color: #ff0000;">git fetch origin</span>

<span style="color: #ff0000;">git branch −−track test_branch origin/test_branch</span>

<span style="color: #ff0000;">git checkout test_branch</span>
Switched to branch "test_branch"

(test_branch)$ grb delete test_branch
git_remote_branch version 0.2.6

<span style="color: #ff0000;">git push origin :refs/heads/test_branch</span>
To git@github.com:webmat/git_remote_branch.git
 - [deleted]         test_branch

<span style="color: #ff0000;">git checkout master</span>
Switched to branch "master"

<span style="color: #ff0000;">git branch -d test_branch</span>

(master) $ </strong></pre>
<p>Yes my friends, I have just boldly used grb on my real repository for your viewing pleasure.</p>
<p>But worry not, no repository was hurt during the writing of this article.</p>
<h2>Feedback</h2>
<p>For any feedback you&#8217;re of course welcome to</p>
<ul>
<li>comment on this article</li>
<li>post in <a href="http://groups.google.com/group/git_remote_branch">the google group</a></li>
</ul>
<h2>Thanks</h2>
<ul>
<li>To Caio Chassot for the code contribution</li>
<li> To the Thin team for a good inspiration on how to help manage gem creation and deployment with rake;</li>
<li> Feedback from <a href="http://jamesgolick.com">James Golick</a> in day to day collaboration as well as all the people that commented on the <a href="http://programblings.com/2008/06/23/git-remote-branches/">initial announcement of git_remote_branch</a>;</li>
<li> To Chris Wanstrath (defunkt) from the GitHub team for <a href="http://github.com/blog/98-git-remote-branch">pimping of the initial announcement</a> of grb on the GitHub blog.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://programblings.com/2008/08/06/time-to-git-collaborating-with-git_remote_branch/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Setting up a long term fork with Git</title>
		<link>http://programblings.com/2008/07/21/setting-up-a-long-term-fork-with-git/</link>
		<comments>http://programblings.com/2008/07/21/setting-up-a-long-term-fork-with-git/#comments</comments>
		<pubDate>Mon, 21 Jul 2008 11:51:34 +0000</pubDate>
		<dc:creator>Mathieu Martin</dc:creator>
				<category><![CDATA[garbage out]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://programblings.com/2008/07/21/maintaining-long-term-forks-with-git/</guid>
		<description><![CDATA[The context
Recently at GiraffeSoft we started a new project, based on another existing project we already had going. We could call this a long term fork. Let me give you a little bit more context on the situation.

These projects will both keep being actively developed in the future;
They will have some fundamental differences that will <a href='http://programblings.com/2008/07/21/setting-up-a-long-term-fork-with-git/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<h2>The context</h2>
<p>Recently at GiraffeSoft we started a new project, based on another existing project we already had going. We could call this a long term fork. Let me give you a little bit more context on the situation.</p>
<ul>
<li>These projects will both keep being actively developed in the future;</li>
<li>They will have some fundamental differences that will not be reconciled;</li>
<li>They will however keep many similarities and we expect that they will benefit from the exchange of some specific patches, as development on both moves forward.</li>
</ul>
<p>In days past, this problem could have been solved reasonably well by cloning the central repository and then exchanging patches and applying them manually.</p>
<p>As you&#8217;ve guessed already, we&#8217;ve decided to try using Git to help manage this long term relationship.</p>
<p>I must warn you however. It&#8217;s the first time we attempt keeping a long term fork like that. We&#8217;re not sure whether it&#8217;s going to be worth the trouble and whether the diverging of the two projects will eventually prevent us from efficiently benefiting from using Git to manage the exchange of patches. We&#8217;re not sure whether this is the best way to accomplish this either.</p>
<p>On one hand, all this trouble may or may not be worth the effort. On the other hand, all of this sounds like ultra elite Git-fu. Hence our decision to explore this approach.</p>
<p>Another less technical reasons was also at play in our decision. We wanted to have one wiki per project on GitHub :-)</p>
<h2>What we&#8217;re going to do</h2>
<p>So at first, we have a remote repository for the initial project. There are of course an arbitrary number of client side clones of the repository (what Subversion calls working directories). None of them will be affected in any way.</p>
<p>The first thing I will do is clone the initial project to a new client side repository. I&#8217;ll set this up in such a way that it won&#8217;t use the initial project as its default origin. On the other hand I&#8217;ll make sure it has one branch that interacts with the initial project for future patch exchanges.</p>
<p>Then from that client-side repository, I&#8217;ll initialize a new remote repository, which will serve as the default remote repository for the new project.</p>
<p>What we&#8217;ll end up with is 2 remote repositories which will have a lot in common but won&#8217;t be linked to one another in any way. It won&#8217;t be a GitHub fork, for instance.</p>
<p>There will be exactly one client side repository that knows about the two central repos and that can exchange commits between them. All other new client-side clones of the new project will be plain old regular Git clones.</p>
<p>It would be easy to set up more client side repositories to be aware of both repositories, but to me it doesn&#8217;t really seem necessary.</p>
<h3>Article too long?</h3>
<p>As with my previous articles about Git, I&#8217;ll provide detailed instructions for you to follow along on dummy repositories (if you&#8217;re interested). When you return to this article to attempt something similar, you may want to skip to the <a href="#executive-summary">executive summary</a> section, where I list strictly the important operations without all the rambling.</p>
<h2>The instructions with the rambling</h2>
<h3>Setting up a dummy initial project</h3>
<p>Find yourself a comfortable directory and run these few commands to initiate a dummy client-side repository and its corresponding dummy remote:</p>
<pre><strong>mkdir test; cd $_
mkdir initial_project initial_wd
GIT_DIR=initial_project/ git init

# Creating a dummy repo
cd initial_wd
git init
echo foo &gt; file.txt
git add .
git commit -a -m "initial commit"
echo bar &gt;&gt; file.txt
git commit -a -m "modification"

# Setting up what's gonna be the central repo for our initial app
git remote add origin ../initial_project/
git push origin master

git config branch.master.remote origin
git config branch.master.merge refs/heads/master</strong></pre>
<p>The last 2 config commands configure your master branch to automatically track remote master when issuing the command &#8216;git pull&#8217;. In other words, it&#8217;s equivalent to running the command &#8216;git branch −−track master origin/master&#8217;, with the only difference being that &#8216;branch −−track&#8217; is primarily intended to create a new local branch, whereas here we already have our local branch.</p>
<p>We can now check for the expected behavior:</p>
<pre><strong>#   mat@mm initial_wd (master)$ git pull
#   Already up-to-date.</strong></pre>
<p>Note also that here I simplify the instructions for following along by creating a dummy remote repository that&#8217;s in fact only in another local directory. If for example you wanted to use GitHub, your Git remote command would simply look like:</p>
<pre><strong>git remote add origin git@github.com:username/initial_project.git</strong></pre>
<h3>The actual fork</h3>
<pre><strong># Create a directory to host the new remote repository
cd ..
mkdir project2
GIT_DIR=project2/ git init</strong></pre>
<p>Now we will use Git clone with the -o option. This lets us give the initial project another name than the default &#8216;origin&#8217;. We&#8217;ll want to use the name &#8216;origin&#8217; for the new repository we&#8217;ll create to actually track the new project. I decided to name it the initial project&#8217;s origin &#8216;ip_origin&#8217;.</p>
<pre><strong># Specify origin name, then the path to the shared repo
# and finally a directory name for the local working directory.
git clone -o ip_origin initial_project wd</strong></pre>
<h4>Setting up the relationship with the initial repository</h4>
<p>We first create a branch specifically to track the initial project&#8217;s master branch. Then we set it up to track the initial project.</p>
<pre><strong>cd wd
git branch ip_master
git config branch.ip_master.remote ip_origin
git config branch.ip_master.merge refs/heads/master</strong></pre>
<h4>Setting up the relationship with the new project&#8217;s repository</h4>
<pre><strong>git remote add origin ../project2
git push origin master

git config branch.master.remote origin
git config branch.master.merge refs/heads/master</strong></pre>
<h4>Let&#8217;s pretend some new development happened</h4>
<pre><strong>echo 'shareable modification' &gt; shareable_file.txt
git add shareable_file.txt
git commit -m "shareable modification"

echo "specific to new project" &gt; not_shareable.txt
git add not_shareable.txt
git commit -m "specific to new project"</strong></pre>
<p>So I have now begun working on the new project and I already have one commit that could benefit the initial project as well. The progress looks a little like this:</p>
<p><img src="http://programblings.com/wp-content/uploads/2008/07/ltf-gitk-new-development.png" alt="A look at gitk’s representation of the new development" height="61" width="468" /></p>
<p>So I switch to the branch that manages the relationship with the initial project and I pick the commit before the last one in master.</p>
<pre><strong>git checkout ip_master
git cherry-pick master^</strong></pre>
<p><img src="http://programblings.com/wp-content/uploads/2008/07/ltf-gitk-common-modification-now-in-ip_master.png" alt="Gitk, after cherry-picking one commit" height="71" width="396" /></p>
<p>Everything&#8217;s dandy so far, except for the subtle fact that I have brought us all to the edge of a cliff.</p>
<p>If I tried to push to the initial repository right now, I&#8217;d be in for a nasty surprise:</p>
<pre><strong>#   mat@mm wd (ip_master)$ git push
#   Counting objects: 7, done.
#   Compressing objects: 100% (4/4), done.
#   Writing objects: 100% (6/6), 564 bytes, done.
#   Total 6 (delta 1), reused 0 (delta 0)
#   Unpacking objects: 100% (6/6), done.
#   To /Users/mat/blog/long-term-fork/test/initial_project
#      7178a89..3ca0240  <font color="#ff0000">master</font> <font color="#0000ff">-&gt; master</font></strong></pre>
<p>Oops! By default, &#8216;git push&#8217; syncs up all branches of the same name with the current branch&#8217;s origin. So that would push the <em>new project</em>&#8217;s master branch on our <em>initial</em> project&#8217;s shared master.</p>
<p>This is obviously not what we want. We only want ip_master to be pushed to the initial project&#8217;s master.</p>
<p>Trying to remember to always explicitly run &#8216;git push ip_origin ip_master:master&#8217; wouldn&#8217;t do it for me. To keep the analogy, that would be akin to doing a cartwheel on the edge of said cliff: a lot of fun until you make a mistake. So obviously we&#8217;d like a simple &#8216;git push&#8217; to do the right thing.</p>
<p>So here&#8217;s how we configure it:</p>
<pre><strong>git config remote.ip_origin.push refs/heads/ip_master:master</strong></pre>
<p>Now we can safely issue the &#8216;git push&#8217; command from ip_master and have Git push ip_master to ip_origin/master.</p>
<pre><strong>git push
#   Counting objects: 4, done.
#   Compressing objects: 100% (2/2), done.
#   Writing objects: 100% (3/3), 310 bytes, done.
#   Total 3 (delta 0), reused 0 (delta 0)
#   Unpacking objects: 100% (3/3), done.
#   To /Users/mat/blog/long-term-fork/test/initial_project
#      027a48f..9db6c3f  <font color="#0000ff">ip_master -&gt; master</font></strong></pre>
<p>There&#8217;s now only one remaining annoyance we&#8217;re not yet protected against. If new branches are created in the initial project&#8217;s central repository, a &#8216;git pull&#8217; when standing in the ip_master branch would pull them all in our new project&#8217;s working directory. I consider this one only an annoyance, since I could just decide not to pay attention to them. On the other hand they will be distracting and may also clash with the branches I create for the development on my new project. So we want to avoid that behavior as well.</p>
<p>To better understand the current Git configuration, let&#8217;s have a look at .git/config:</p>
<pre><strong>  ...
  [remote "ip_origin"]
    url = /Users/mat/blog/long-term-fork/test/initial_project
    <font color="#0000ff">fetch = +refs/heads/*:refs/remotes/ip_origin/*</font>
  [branch "master"]
    remote = origin
    merge = refs/heads/master
  [branch "ip_master"]
    remote = ip_origin
    merge = refs/heads/master
  [remote "origin"]
    url = ../project2
    <font color="#0000ff">fetch = +refs/heads/*:refs/remotes/origin/*</font></strong></pre>
<p>So in both &#8216;remote&#8217; sections I can see that fetch is configured to bring everything locally (the * wildcards).</p>
<p>So here&#8217;s how I limit what gets pulled when I pull from the initial project&#8217;s repository.</p>
<pre><strong>git config remote.ip_origin.fetch +refs/heads/master:refs/remotes/ip_origin/master</strong></pre>
<p>The part before the colon is the name of the interesting branch on the remote server. The part after the colon is your local Git repo&#8217;s internal branch, used to track the remote branch (not to be confused with our user branch ip_master).</p>
<p>Setting up remote branches on both projects, pulling, pushing and exchanging more commits is left as an exercise to the reader.</p>
<h2>Conclusion</h2>
<p>So that&#8217;s the gist of it, my friends. I am basically set up to work on my new project like I would in a more typical situation. I also have a special branch set up to interact with the initial project. With this branch I&#8217;ll be able to do two things:</p>
<ul>
<li>Pull new developments from the initial project and then cherry-pick only the shareable commits into the new project&#8217;s other branches.</li>
<li>Cherry-pick in the other direction to bring certain commits from the new project into this branch and then push them up to the initial project.</li>
</ul>
<p>For this approach to be useful however, we&#8217;ll have to make sure we create as concise commits as possible. Gone are the days of committing a whole afternoon in one meaningless commit containing 12 different modifications.</p>
<p>Of course coding sprees of a couple hours are not out of the question. Features like &#8216;git add −−patch&#8217; are a great help when comes time to extract meaningful commits out of the result of a few hours of intense coding. For a good introduction to −−patch (and a few other powerful features), be sure to read Ryan Tomayko&#8217;s <a href="http://tomayko.com/writings/the-thing-about-git">The Thing about Git</a>.</p>
<h2 id="executive-summary">The executive summary</h2>
<p>So let&#8217;s reiterate strictly the interesting bits necessary to set up a long term fork when starting a new project from an existing one.</p>
<p>We already have:</p>
<ul>
<li>the initial project&#8217;s repository at url git@github.com:username/initial_project.git</li>
<li>the new project&#8217;s empty repository, also created at git@github.com:username/new_project.git</li>
</ul>
<pre><strong># Create new local clone for the new project
git clone -o ip_origin git@github.com:username/initial_project.git new_project
cd new_project

# Set up a standard track between initial master and local ip_master
git config branch.ip_master.remote ip_origin
git config branch.ip_master.merge refs/heads/master

# Automatically push the right branch
<font color="#0000ff">git config remote.ip_origin.push refs/heads/ip_master:master</font>
# Don't bring in the other shared branches from initial project
<font color="#0000ff">git config remote.ip_origin.fetch +refs/heads/master:refs/remotes/ip_origin/master</font>

# Push new local repo it to new shared repo
git remote add origin git@github.com:username/new_project.git
git push origin master

# Configure standard track of master with new local repo
git config branch.master.remote origin
git config branch.master.merge refs/heads/master</strong></pre>
<p>That&#8217;s it! We now only have to cherry-pick like there&#8217;s no tomorrow.</p>
]]></content:encoded>
			<wfw:commentRss>http://programblings.com/2008/07/21/setting-up-a-long-term-fork-with-git/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>How to load gems only when your tests are not run from TextMate</title>
		<link>http://programblings.com/2008/07/10/how-to-load-gems-only-when-your-tests-are-not-run-from-textmate/</link>
		<comments>http://programblings.com/2008/07/10/how-to-load-gems-only-when-your-tests-are-not-run-from-textmate/#comments</comments>
		<pubDate>Thu, 10 Jul 2008 15:12:09 +0000</pubDate>
		<dc:creator>Mathieu Martin</dc:creator>
				<category><![CDATA[garbage out]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[textmate]]></category>

		<guid isPermaLink="false">http://programblings.com/2008/07/10/how-to-load-gems-only-when-your-tests-are-not-run-from-textmate/</guid>
		<description><![CDATA[Working with new people often influences the way you work. The influences can range from picking up simple tricks to seeing fundamental facts about your craft in a new light.This week when I began working with James I saw him run his tests directly from TextMate. Of course I knew it was possible to run <a href='http://programblings.com/2008/07/10/how-to-load-gems-only-when-your-tests-are-not-run-from-textmate/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>Working with new people often influences the way you work. The influences can range from picking up simple tricks to seeing fundamental facts about your craft in a new light.This week when <a href="http://jamesgolick.com/2008/7/7/mat-martin-joins-giraffesoft">I began working with James</a> I saw him run his tests directly from TextMate. Of course I knew it was possible to run Ruby from TM, including tests.For some inexplicable reason however I had never bothered to try it. This trick is very convenient for two reasons: TextMate cleans up the backtraces and resolves each level of the trace to a clickable link to your code file. So I decided to include this trick in my workflow.I encountered two problems with this however. Two gems I usually use in my tests don&#8217;t play well with running tests from TextMate.</p>
<h2>redgreen</h2>
<p>The redgreen gem highlights the <font color="#008000"><strong>.</strong></font> <strong><font color="#ff0000">F</font></strong> and <font color="#ff9900"><strong>E</strong></font> (among other bits) in your test runs with green, red and yellow. When running my whole test suite it&#8217;s something I want to have. It&#8217;s not only visually pleasing, but it also lets me see at a glance whether any problems were encountered.When run from TextMate, tests using redgreen are displayed without having the console coloring stripped out, which gives something like this:</p>
<p>
<img src="http://programblings.com/wp-content/uploads/2008/07/tests_with_redgreen_in_tm.png" alt="The result of running tests from TextMate, when using redgreen" height="223" width="564" />
</p>
<p>Riiiight.For the record, here&#8217;s the nice result when run at the console:</p>
<p><img src="http://programblings.com/wp-content/uploads/2008/07/tests_with_redgreen_in_console.png" alt="Running tests with redgreen, from the console" height="208" width="409" /></p>
<h2>quietbacktrace</h2>
<p>The other gem I can&#8217;t do without is James Golick and Dan Croak&#8217;s <a href="http://jamesgolick.com/2007/12/3/noisy-backtraces-got-you-down">quietbacktrace</a>. This gem lets you specify filters and silencers to clean up those huuuuuge Rails or Merb backtraces.Filters let you remove useless parts of a given line in the backtrace, such as the path leading to your gems. Silencers let you completely remove some lines from the backtrace, such as all the lines referring to what happened inside Rails, leading to your error. The most popular filters and silencers are already provided with quietbacktrace, as you&#8217;ll see below.So the result, of course is that messing with backtraces breaks TextMate&#8217;s ability to link a backtrace line with the corresponding file.</p>
<h2>A simple snippet to fix this</h2>
<p>Since I didn&#8217;t really want to do away with these tools, I included a bit of a hacky snippet in my test_helper.rb file to detect whether a test run was happening in TextMate or at the console.If you find yourself in the same fix as me, feel free to use the following.Among your requires:</p>
<pre><strong>IN_TM = !ENV['TM_DIRECTORY'].nil?
unless IN_TM
  require 'redgreen'
  require 'quietbacktrace'end</strong></pre>
<p>And then:</p>
<pre><strong>class Test::Unit::TestCase
  unless IN_TM
    self.backtrace_silencers &lt;&lt; :rails_vendor
    self.backtrace_filters   &lt;&lt; :rails_root
  end
  #...
end</strong></pre>
<p>Now I can have my testing niceties when running my tests from the console and they don&#8217;t break the TextMate integration :-)</p>
<h2> Trying this out for the first time?</h2>
<p>If like me you just decided to try this out for the first time, the shortcuts are easy to remember. Command-R runs any Ruby file (in this case, the whole test file) and Command-Shift-R runs the single test the cursor is in.There&#8217;s a little hiccup in sight, however. If you&#8217;re using Rails 2+, you have to apply a very small fix to TextMate before you&#8217;ll be able to run your tests. Read more about the fix on <a href="http://macournoyer.wordpress.com/2007/12/15/getting-textmate-ready-for-rails-20/">Marc-André Cournoyer&#8217;s blog</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://programblings.com/2008/07/10/how-to-load-gems-only-when-your-tests-are-not-run-from-textmate/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GiraffeSoft.push( Karabunga.pop( self ))</title>
		<link>http://programblings.com/2008/07/07/giraffesoft-push-karabunga-pop-self/</link>
		<comments>http://programblings.com/2008/07/07/giraffesoft-push-karabunga-pop-self/#comments</comments>
		<pubDate>Mon, 07 Jul 2008 14:09:38 +0000</pubDate>
		<dc:creator>Mathieu Martin</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://programblings.com/2008/07/07/giraffesoft-push-karabunga-pop-self/</guid>
		<description><![CDATA[A wise man once suggested that one of the steps in teaching yourself programming involved working with people better than you. (See Teach Yourself Programming in Ten Years)
Even though I feel I&#8217;m a pretty competent software developer, I&#8217;m very excited to join another developer for which I have a truly profound respect. I&#8217;ve only recently <a href='http://programblings.com/2008/07/07/giraffesoft-push-karabunga-pop-self/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>A wise man once suggested that one of the steps in teaching yourself programming involved working with people better than you. (See <a href="http://norvig.com/21-days.html">Teach Yourself Programming in Ten Years</a>)</p>
<p>Even though I feel I&#8217;m a pretty competent software developer, I&#8217;m very excited to join another developer for which I have a truly profound respect. I&#8217;ve only recently made the career move of working on the web full time, and this is a great opportunity for me to kickstart this phase of my career by working with a Rails /  REST / jQuery guru.</p>
<p>Starting today, I&#8217;m working for <a href="http://giraffesoft.ca/">GiraffeSoft</a>, with <a href="http://jamesgolick.com/">James Golick</a>. We&#8217;ve wanted to work together for a while, and the stars have finally aligned to <a href="http://jamesgolick.com/2008/7/7/mat-martin-joins-giraffesoft">make this possible</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://programblings.com/2008/07/07/giraffesoft-push-karabunga-pop-self/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Git remote branches</title>
		<link>http://programblings.com/2008/06/23/git-remote-branches/</link>
		<comments>http://programblings.com/2008/06/23/git-remote-branches/#comments</comments>
		<pubDate>Mon, 23 Jun 2008 17:16:42 +0000</pubDate>
		<dc:creator>Mathieu Martin</dc:creator>
				<category><![CDATA[garbage out]]></category>
		<category><![CDATA[git_remote_branch]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://programblings.com/2008/06/23/git-remote-branches/</guid>
		<description><![CDATA[I&#8217;m ready to bet that setting up and deleting remote branches is something you do rarely enough that you always find yourself looking up the documentation. Or maybe it&#8217;s just me.
Due to its roots, Git supports a wide array of usage scenarios for interacting with remote repositories, and we love it that way. It&#8217;s a <a href='http://programblings.com/2008/06/23/git-remote-branches/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m ready to bet that setting up and deleting remote branches is something you do rarely enough that you always find yourself looking up the documentation. Or maybe it&#8217;s just me.</p>
<p>Due to its roots, Git supports a wide array of usage scenarios for interacting with remote repositories, and we love it that way. It&#8217;s a big factor in the flexibility and power of the tool.</p>
<p>However in simple scenarios, there&#8217;s still a bunch of commands you must run to accomplish simple tasks. I believe the commands for the simple scenario can be simpler.</p>
<p>Last January, <a href="http://blog.carlmercier.com/2008/01/25/no-nonsense-git-part-1-git-remote-branch/">Carl Mercier created git-remote-branch</a>. I&#8217;ve found this script very useful and, with his permission, I&#8217;ve decided to keep moving it forward and add a few features to it.</p>
<h2>git_remote_branch</h2>
<p>The first purpose of git_remote_branch is to encapsulate all the commands that need to be run to interact with remote branches in simple scenarios.</p>
<p>Its second purpose is to be a learning tool. git_remote_branch does two things to help you learn these commands:</p>
<ul>
<li> It clearly displays the commands it runs on your behalf, in a beautiful shade of red;</li>
<li> It has an &#8216;explain&#8217; meta-command that will simply display the list of commands instead of running them for you.</li>
</ul>
<h3>Examples</h3>
<h4>Help</h4>
<p>Let&#8217;s start with the simplest of all:</p>
<pre><strong>$ grb</strong></pre>
<p>or</p>
<pre><strong>$ grb help
git_remote_branch version 0.2.2

  Usage:

  grb create branch_name [origin_server]

  grb delete branch_name [origin_server]

  grb track branch_name [origin_server]

  If origin_server is not specified, the name 'origin' is assumed (git's default)

  The explain meta-command: you can also prepend any command with the keyword 'explain'.
  Instead of executing the command, git_remote_branch will simply output the list of commands
  you need to run to accomplish that goal.
  Example:
    grb explain create
    grb explain create my_branch github

  All commands also have aliases:
  create: create, new
  delete: delete, destroy, kill, remove
  track: track, follow, grab, fetch</strong></pre>
<p>As you can see, the syntax for all commands is very regular: action, branch_name and optionally, origin_server.</p>
<p>To facilitate learning even more, aliases are also provided. So to take an example,</p>
<pre><strong>$ grb track his_branch</strong></pre>
<p>and</p>
<pre><strong>$ grb fetch his_branch</strong></pre>
<p>are perfectly equivalent.</p>
<h4>create</h4>
<p>Create lets you create a new branch both remotely and locally. Note that it&#8217;s not made to share an existing branch (that feature&#8217;s coming).</p>
<p>So what it does is to push your current branch as a new remote branch, then create it locally and track it, for easier pulling afterwards.</p>
<pre><strong>$ grb create some_branch
git_remote_branch version 0.2.2

<span style="color: #ff0000;">git push origin master:refs/heads/some_branch</span>
Total 0 (delta 0), reused 0 (delta 0)
To /path/to/repo/
* [new branch]      master -&gt; some_branch

<span style="color: #ff0000;">git fetch origin</span>

<span style="color: #ff0000;">git branch −−track some_branch origin/some_branch</span>

<span style="color: #ff0000;">git checkout some_branch</span>
Switched to branch "some_branch"</strong></pre>
<h4>delete</h4>
<p>Presenting features with names that are too self-evident is boring. Let&#8217;s get to the point, already.</p>
<pre><strong>$ grb delete some_branch
git_remote_branch version 0.2.2

<span style="color: #ff0000;">git push origin :refs/heads/some_branch</span>
To /path/to/repo/
- [deleted]         some_branch

<span style="color: #ff0000;">git checkout master</span>
Switched to branch "master"

<span style="color: #ff0000;">git branch -d some_branch</span></strong></pre>
<h4>track</h4>
<p>Track lets you easily track the changes that are made to an existing remote branch you&#8217;re not tracking already. Each time you pull from the remote repository, the local branch will be automatically merged with the remote branch.</p>
<pre><strong>$ grb track his_branch
git_remote_branch version 0.2.2

<span style="color: #ff0000;">git fetch origin</span>
From /path/to/repo/
* [new branch]      his_branch -&gt; origin/his_branch

<span style="color: #ff0000;">git branch −−track his_branch origin/his_branch</span></strong></pre>
<h4>explain</h4>
<p>Explain will spew out all commands necessary to accomplish one of the previous actions. There are two ways of using it. The simplest will give you dummy commands:</p>
<pre><strong>$ grb explain create
git_remote_branch version 0.2.2

List of operations to do to create a new remote branch and track it locally:

<span style="color: #ff0000;">git push origin master:refs/heads/branch_to_create
git fetch origin
git branch −−track branch_to_create origin/branch_to_create
git checkout branch_to_create</span></strong></pre>
<p>Or you can have steps that are tailor-made for what you want to accomplish.</p>
<pre><strong>$ grb explain create my_branch github_origin
git_remote_branch version 0.2.2

List of operations to do to create a new remote branch and track it locally:

<span style="color: #ff0000;">git push github_origin master:refs/heads/my_branch
git fetch github_origin
git branch −−track my_branch github_origin/my_branch
git checkout my_branch</span></strong></pre>
<h3>get git_remote_branch</h3>
<p>(Hey, this title has a nice ring to it)</p>
<pre><strong>sudo gem install webmat-git_remote_branch −−source=http://gems.github.com</strong></pre>
<p>Now with rubygems 1.2.0 out (don&#8217;t do it with a prior version), you can also add GitHub as a permanent source for your gems:</p>
<pre><strong>sudo gem sources -a </strong><strong>http://gems.github.com</strong></pre>
<p>Now and ever after, you will be able to get anything from GitHub with a simple</p>
<pre><strong>sudo gem install webmat-git_remote_branch</strong></pre>
<p>If in your eagerness you&#8217;ve added github as a source before running</p>
<pre><strong>sudo gem update −−system</strong></pre>
<p>Please refer to <a href="http://chalain.livejournal.com/71260.html">What to do when gems.github.com breaks gems FOREVAR</a></p>
<h3>Look ma, no tests!</h3>
<p>Uhhhh, yeah, I know&#8230;</p>
<p>This tool is still extremely early in its life and &#8211; dare I say it &#8211; it&#8217;s only hand-tested for now. I&#8217;ve been using it personally for a while and it&#8217;s working very well for me, if that means anything :-)</p>
<p>So this is still a quick script, only now it has lipstick.</p>
<p><a title="Works on my machine logo" href="http://www.codinghorror.com/blog/archives/000818.html"><img src="http://programblings.com/wp-content/uploads/2008/06/works-on-my-machine.png" alt="Works on my machine logo" /></a></p>
<p>This software should be considered an early version of a pre-alpha. You&#8217;ve been warned!</p>
<p>If this makes you queasy, there&#8217;s always the &#8216;explain&#8217; command that can act as your cheat sheet without actually having grb run the commands on your behalf.</p>
<p>For the extra queasy, well you can find the commands very easily without running grb. Just point your favorite editor to lib/git_remote_branch.rb. All commands are there, at the beginning of the file.</p>
<p>For the brave, try it out and tell me what you think. Improvements, bug reports and contributions are all welcome.</p>
<p>And remember, in case of an emergency, you can always refer to my <a href="http://programblings.com/2008/06/07/the-illustrated-guide-to-recovering-lost-commits-with-git/">illustrated guide to recovering lost commits with Git</a> ;-)</p>
<p>Here&#8217;s what&#8217;s to come:</p>
<ul>
<li>lots of tests</li>
<li>a &#8216;remotize&#8217; functionality (for existing local branches)</li>
<li>a much better resilience to use in faulty situations (e.g. deleting something that&#8217;s not present locally or remotely)</li>
<li>the possibility to specify different branch names locally vs remotely</li>
<li>slap an open source licence on it all</li>
<li>and so much more!</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://programblings.com/2008/06/23/git-remote-branches/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>I somehow feel I&#8217;m going to love what this guy writes&#8230;</title>
		<link>http://programblings.com/2008/06/20/i-somehow-feel-im-going-to-love-what-this-guy-writes/</link>
		<comments>http://programblings.com/2008/06/20/i-somehow-feel-im-going-to-love-what-this-guy-writes/#comments</comments>
		<pubDate>Sat, 21 Jun 2008 01:26:30 +0000</pubDate>
		<dc:creator>Mathieu Martin</dc:creator>
				<category><![CDATA[blogging]]></category>

		<guid isPermaLink="false">http://programblings.com/2008/06/20/i-somehow-feel-im-going-to-love-what-this-guy-writes/</guid>
		<description><![CDATA[I&#8217;m kind of jealous. This guy put out 2 freaking good blog posts in 3 days. These are apparently his first 2 blog posts ever, too :-)
You&#8217;ll never find a group who wears their ignorance of technology more proudly than the average business person. “I&#8217;m not a computer guy,” they&#8217;ll say with a big smile <a href='http://programblings.com/2008/06/20/i-somehow-feel-im-going-to-love-what-this-guy-writes/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m kind of jealous. This guy put out 2 freaking good blog posts in 3 days. These are apparently his first 2 blog posts ever, too :-)</p>
<blockquote><p>You&#8217;ll never find a group who wears their ignorance of technology more proudly than the average business person. “I&#8217;m not a computer guy,” they&#8217;ll say with a big smile on their face. Well gee, the personal computer is only the most significant invention to come along in the past 100 years.</p></blockquote>
<p>By <a href="http://tales-of-an-it-director.blogspot.com/2008/06/modsocialskills-modrationality.html">Tales of an IT Director</a></p>
]]></content:encoded>
			<wfw:commentRss>http://programblings.com/2008/06/20/i-somehow-feel-im-going-to-love-what-this-guy-writes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The illustrated guide to recovering lost commits with Git</title>
		<link>http://programblings.com/2008/06/07/the-illustrated-guide-to-recovering-lost-commits-with-git/</link>
		<comments>http://programblings.com/2008/06/07/the-illustrated-guide-to-recovering-lost-commits-with-git/#comments</comments>
		<pubDate>Sun, 08 Jun 2008 03:33:03 +0000</pubDate>
		<dc:creator>Mathieu Martin</dc:creator>
				<category><![CDATA[garbage out]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[commit]]></category>
		<category><![CDATA[emergency]]></category>
		<category><![CDATA[recovery]]></category>

		<guid isPermaLink="false">http://programblings.com/2008/06/07/the-illustrated-guide-to-recovering-lost-commits-with-git/</guid>
		<description><![CDATA[ Git is one hell of a powertool.
Like with any such tool, as soon as you get to know it enough, you start pushing the boundaries. Git gives you a lot of control over your repository:

trivial branching and merging (even with long lived branches);
rebasing as a cleaner alternative to merging;
stashing aside your changes for a <a href='http://programblings.com/2008/06/07/the-illustrated-guide-to-recovering-lost-commits-with-git/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p> Git is one hell of a powertool.</p>
<p>Like with any such tool, as soon as you get to know it enough, you start pushing the boundaries. Git gives you a lot of control over your repository:</p>
<ul>
<li>trivial branching and merging (even with long lived branches);</li>
<li>rebasing as a cleaner alternative to merging;</li>
<li>stashing aside your changes for a quick fix elsewhere;</li>
<li><a href="http://tomayko.com/writings/the-thing-about-git">extracting logical, distinct commits from a multi-hours coding spree</a>;</li>
</ul>
<p>The list goes on&#8230;</p>
<p>More traditional version control systems don&#8217;t give you as much power as Git by any stretch of the mind. They are like taking a walk in the woods with your parents, at age 14.</p>
<p>You&#8217;re probably gonna see and do neat stuff, but you sure ain&#8217;t gonna get lost or anything.</p>
<p>Using Git on the other hand is more akin to being handed a cool motocross to go play alone in the woods&#8230; Also at age 14.</p>
<p><a href="http://programblings.com/wp-content/uploads/2008/06/insane_motocross_shit.jpg" title="Insane motocross shit"><img src="http://programblings.com/wp-content/uploads/2008/06/insane_motocross_shit.jpg" alt="Insane motocross shit" height="336" width="426" /></a></p>
<p>We all know what&#8217;s bound to happen, right?</p>
<p>You&#8217;ll smash into a tree.</p>
<p>The source control equivalent to slamming into a tree is losing commits. Getting all of Git&#8217;s power and flexibility at once can be somewhat dangerous.  You&#8217;ll find it so easy and helpful to branch and merge that you&#8217;ll start doing it way more often. On the other hand &#8212; especially in the beginning &#8212; you&#8217;ll misunderstand or plainly miss some important warnings, and make errors. Or you may just end up in weird merging situations you never thought of, and don&#8217;t necessarily understand. These situations can often result in losing commits or whole branches.</p>
<p>My goal with this article is to make sure you understand the situation you&#8217;re really in: you have <em>temporarily</em> lost commits or branches.</p>
<h3>Disclaimer</h3>
<p>This article assumes a basic knowledge of how git works, e.g. committing, branching and merging.</p>
<h3>My first time</h3>
<p>The first time I lost a commit was a good while ago. I can&#8217;t remember the details, but basically I got bit by the fact that under the covers, Git uses hard links liberally. Which means that copy / pasting your code directory as a recovery solution isn&#8217;t going to save your ass <img src="http://programblings.com/wp-content/uploads/2008/06/ass.jpg" style="vertical-align: middle" alt="A nice poney" /> when you attempt a potentially damaging operation you don&#8217;t fully understand.</p>
<p>Note that compressing your code directory will, though.</p>
<p>So there I was, after attempting an operation I didn&#8217;t really understand. I knew I had failed what I attempted and I knew I had lost my last commit. Ironically, I still had Gitk open, displaying that very commit. As long as I didn&#8217;t refresh the Gitk view with F5 I could see the lost commit.</p>
<p>Here&#8217;s a fun fact: under OSX (not sure about Linux) you cannot select and copy text from Gitk&#8217;s interface, except for the SHA1 field [1]. I knew Git probably had a way to recover from that&#8230; But you know, I just wanted to get back to work and NOT search documentation and blog posts endlessly.</p>
<p>So I took screenshots, passed them real quick through <a href="http://jocr.sourceforge.net/">GOCR</a>, just to see how far it would get.</p>
<p>The result: GOCR doesn&#8217;t like the font Monaco :-)</p>
<h2>How to (really) recover lost commits with Git</h2>
<p>Recently I lost a commit again. This time however, Gitk was not up to date. I knew I&#8217;d just lost something I wouldn&#8217;t necessarily remember in its entirety. It was a commit an hour old, touching many files. And I have a crappy memory.</p>
<p>This time I had to do it the right way. I found out it&#8217;s really easy (once you figure it out), but I found no really clear explanation anywhere. So here goes.</p>
<h3>Initial setup</h3>
<p>If you wanna follow along &#8212; and I strongly recommend it &#8212; here&#8217;s the boring few steps to create a dummy repo and bring it up to speed with for the rest of this article. We&#8217;re going to beat the hell out of this repo and it&#8217;s going to be fun.</p>
<p>So just paste the following into a console:</p>
<pre><strong>mkdir recovery;cd recovery
git init
touch file
git add file
git commit -m "First commit"
echo "Hello World" &gt; file
git add .
git commit -m "Greetings"git branch cool_branch
git checkout cool_branch
echo "What up world?" &gt; cool_file
git add .
git commit -m "Now that was cool"
git checkout master
echo "What does that mean?" &gt;&gt; file</strong></pre>
<p>Ok, let&#8217;s look at where we&#8217;re at:</p>
<pre><strong>gitk ––all &amp;</strong></pre>
<p>The ––all option lets you see all branches at the same time, as well as your stashes.</p>
<p>Click here to enlarge your picture!!1</p>
<p><a href="http://programblings.com/wp-content/uploads/2008/06/initial_setup.png" title="Initial setup - Recovering git commits"><img src="http://programblings.com/wp-content/uploads/2008/06/initial_setup.png" alt="Initial setup - Recovering git commits" height="272" width="353" /></a></p>
<p>We can see the cool_branch as well as some yet uncommitted changes over the master branch.</p>
<pre><strong>mathieu@ml recovery (master)$ <font color="#0000ff">ls -l</font>
total 16
-rw-r--r--  1 mathieu  staff    15B  7 Jun 18:19 cool_file
-rw-r--r--  1 mathieu  staff    33B  7 Jun 18:19 file</strong></pre>
<p>Got my 2 files, I&#8217;m good to go.</p>
<h3>Let&#8217;s make a mistake</h3>
<p>Let&#8217;s say I decide I want to bring in these cool changes in master. I&#8217;ll do it with a rebase. I know there&#8217;s no big risk of conflicts so that&#8217;s a no-brainer.</p>
<table width="100%">
<tr>
<td width="50%">
<pre><strong>mathieu@ml recovery (master)$ <font color="#0000ff">git rebase cool_branch</font>
file: needs update</strong></pre>
</td>
<td width="50%">
<p class="center" style="margin: 0pt"><img src="http://programblings.com/wp-content/uploads/2008/06/my_ugly_mug.jpg" alt="My ugly mug" height="41" width="41" /></p>
</td>
</tr>
</table>
<p>Now if you look carefully you&#8217;ll notice I wasn&#8217;t paying attention when Git gave me a feeble complaint about &#8216;file&#8217;.</p>
<p>Everything&#8217;s well, so I think &#8220;Ok, I don&#8217;t need cool_branch anymore&#8221;.</p>
<pre><strong>mathieu@ml recovery (master)$ <font color="#0000ff">git branch -d cool_branch</font>
error: The branch 'cool_branch' is not an ancestor of your current HEAD.
If you are sure you want to delete it, run 'git branch -D cool_branch'.</strong></pre>
<p>Huh? Whatever you say, Linus. Let&#8217;s get on with it.</p>
<pre><strong>mathieu@ml recovery (master)$ <font color="#0000ff">git branch -D cool_branch</font>
Deleted branch cool_branch.</strong></pre>
<p>Ahh, it feels good to be a Git ninja. Now let&#8217;s see where we&#8217;re at and refresh Gitk with F5.</p>
<p><a href="http://programblings.com/wp-content/uploads/2008/06/gitk_oh_shit.png" title="Gitk - oh shit moment"><img src="http://programblings.com/wp-content/uploads/2008/06/gitk_oh_shit.png" alt="Gitk - oh shit moment" height="271" width="353" /></a></p>
<p>Oops, my cool commit is gone! That thing can&#8217;t be right. Let&#8217;s panic:</p>
<pre><strong>mathieu@ml recovery (master)$ <font color="#0000ff">ls</font>
file

mathieu@ml recovery (master)$ <font color="#0000ff">git status</font>
# On branch master
# Changed but not updated:
#   (use "git add &lt;file&gt;..." to update what will be committed)
#
#    modified:   file
#
no changes added to commit (use "git add" and/or "git commit -a")

mathieu@ml recovery (master)$ <font color="#0000ff">git diff</font>
diff --git a/file b/file
index 557db03..f2a8bf3 100644
--- a/file
+++ b/file
@@ -1 +1,2 @@
 Hello World
<font color="#008000">+What does that mean?</font></strong></pre>
<p><img src="http://programblings.com/wp-content/uploads/2008/06/oh_shit.jpg" alt="Oh shit face" height="83" width="61" /><br />
Oh sh!t</p>
<p>So the &#8216;file: needs update&#8217; message back there meant that the rebase didn&#8217;t happen, because I had pending changes.</p>
<p>Helpful.</p>
<h2>Recovering a lost commit</h2>
<p>Since I don&#8217;t think my uncommitted work is complete, I&#8217;ll just stash it instead of committing it. Then I&#8217;ll hunt down my lost work.</p>
<pre><strong>mathieu@ml recovery (master)$ <font color="#0000ff">git stash save "Questioning the universe"</font>
Saved working directory and index state "On master: Questioning the universe" HEAD is now at 6da726f... Greetings</strong></pre>
<p>In the name of paranoïa, let&#8217;s make sure this got in right:</p>
<p><a href="http://programblings.com/wp-content/uploads/2008/06/gitk_check_out_that_stash.png" title="In a paranoïa moment, we make sure the stash is saved correctly"><img src="http://programblings.com/wp-content/uploads/2008/06/gitk_check_out_that_stash.png" alt="In a paranoïa moment, we make sure the stash is saved correctly" height="285" width="364" /></a></p>
<p>Ok, let&#8217;s get on with our rescue mission:</p>
<pre><strong>mathieu@ml recovery (master)$ <font color="#0000ff">git fsck −−lost-found</font>
dangling commit 93b0c51cfea8c731aa385109b8e99d19b38a55be</strong></pre>
<p>That sounds right, exactly one commit in the lost and found.</p>
<p>Let&#8217;s just make sure:</p>
<pre><strong>mathieu@ml recovery (master)$ </strong><font color="#0000ff"><strong>git show 93b0c51cfea8c731aa385109b8e99d19b38a55be | mate</strong></font></pre>
<p><a href="http://programblings.com/wp-content/uploads/2008/06/show_lost_found.png" title="We see in textmate that this is our lost commit"><img src="http://programblings.com/wp-content/uploads/2008/06/show_lost_found.png" alt="We see in textmate that this is our lost commit" height="168" width="266" /></a></p>
<p>Bingo!</p>
<h3>Different ways to recover the commit</h3>
<p>There are a few different ways to recover that commit. Obviously we can just copy and paste that snippet, but in the case of a bigger commit, that approach will just amount to a lot of error-prone busywork.</p>
<p>I&#8217;ll reclaim my Git ninja status and try it a few different ways.</p>
<h4>Recover it with rebase</h4>
<p>Let&#8217;s just replay this change on top of master:</p>
<pre><strong>mathieu@ml recovery (master)$ <font color="#0000ff">git rebase 93b0c51cfea8c731aa385109b8e99d19b38a55be</font>
First, rewinding head to replay your work on top of it...
HEAD is now at 93b0c51... Now that was cool
Fast-forwarded master to 93b0c51cfea8c731aa385109b8e99d19b38a55be.</strong></pre>
<p><img src="http://programblings.com/wp-content/uploads/2008/06/gitk_recovered_with_rebase.png" alt="Commit recovered with rebase" /></p>
<p>Neat! Now I feel like a ninja worthy of the title again.</p>
<p>So let&#8217;s rewind one commit and try it another way.</p>
<pre><strong>mathieu@ml recovery (master)$ <font color="#0000ff">git reset --hard head^</font>
HEAD is now at 6da726f... Greetings</strong></pre>
<p><img src="http://programblings.com/wp-content/uploads/2008/06/gitk_rewinding_to_lost_commit.png" alt="Rewinding to a state where we’ve lost our commit" /></p>
<p>Ok, the commit&#8217;s gone.</p>
<p>(Don&#8217;t tell anyone but my inner ninja is feeling queasy again.)</p>
<h4>Recover it with merge</h4>
<p>There are cases where rebase is not powerful enough. For example when you expect to face a lot of conflicts. In this case merge is a better solution:</p>
<pre><strong>mathieu@ml recovery (master)$ <font color="#0000ff">git merge 93b0c51cfea8c731aa385109b8e99d19b38a55be</font>
Updating 6da726f..93b0c51
Fast forward
 cool_file |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 cool_file</strong></pre>
<p><img src="http://programblings.com/wp-content/uploads/2008/06/gitk_recovered_with_merge.png" alt="Commit recovered with merge" /></p>
<p>Too easy&#8230; Rewind!</p>
<pre><strong>mathieu@ml recovery (master)$ <font color="#0000ff">git reset --hard head^</font>
HEAD is now at 6da726f... Greetings</strong></pre>
<h4>Recover it with cherry-pick</h4>
<p>If  instead you had a few commits one after another but you just want to pick the last one, rebase and merge won&#8217;t do. They would bring the whole branch back in master. That&#8217;s a situation for cherry-pick.</p>
<pre><strong>mathieu@ml recovery (master)$ <font color="#0000ff">git cherry-pick 93b0c51cfea8c731aa385109b8e99d19b38a55be</font>
Finished one cherry-pick.
Created commit f443703: Now that was cool
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 cool_file</strong></pre>
<p><img src="http://programblings.com/wp-content/uploads/2008/06/gitk_recovered_with_cherry_pick.png" alt="Commit recovered with cherry-pick" /></p>
<p>Insane!</p>
<p>This only leaves one open question: WHO&#8217;S YOUR DADDY NOW, GIT?</p>
<p>Now that we&#8217;ve established the answer to that question, let&#8217;s get back to work!</p>
<h3>Let&#8217;s make a second mistake</h3>
<pre><strong>mathieu@ml recovery (master)$ <font color="#0000ff">git stash clear</font></strong></pre>
<p>Or was it Git stash apply?</p>
<p><img src="http://programblings.com/wp-content/uploads/2008/06/gitk_accidental_stash_clear.png" alt="Oops! Accidentally lost the stash" /></p>
<p>Oh jeez, there we go again&#8230;</p>
<pre><strong>mathieu@ml recovery (master)$ <font color="#0000ff">git fsck −−lost-found</font>
dangling commit 24e3752f7a73ae98b361ce1c260e1f285d653447
dangling commit 93b0c51cfea8c731aa385109b8e99d19b38a55be</strong></pre>
<p>Ok, we still see the one we lost earlier, 93b0c51&#8230; Let&#8217;s look at the other one.</p>
<pre><strong>mathieu@ml recovery (master)$ <font color="#0000ff">git show 24e3752f7a73ae98b361ce1c260e1f285d653447</font>
commit 24e3752f7a73ae98b361ce1c260e1f285d653447
Merge: 6da726f... c90f079...
Author: Mathieu Martin &lt;webmat@gmail.com&gt;
Date:   Sat Jun 7 16:02:57 2008 -0400

On master: Questioning the universe

diff --cc file
index 557db03,557db03..f2a8bf3
--- a/file
+++ b/file
@@@ -1,1 -1,1 +1,2 @@@
Hello World
<font color="#008000">++What does that mean?</font></strong></pre>
<p>Spot on. Let&#8217;s try something wild, while we&#8217;re here.</p>
<pre><strong>mathieu@ml recovery (master)$ <font color="#0000ff">git checkout 24e3752f7a73ae98b361ce1c260e1f285d653447</font>
Note: moving to "24e3752f7a73ae98b361ce1c260e1f285d653447" which isn't a local branch
If you want to create a new branch from this checkout, you may do so
(now or later) by using -b with the checkout command again. Example:
  git checkout -b &lt;new_branch_name&gt;
HEAD is now at 24e3752... On master: Questioning the universe

mathieu@ml recovery (24e3752...)$</strong></pre>
<p>As you may have noticed, my console always indicates which branch I&#8217;m in, so far [2]. But now I seem to be in some kind of twilight zone, which Gitk confirms.</p>
<p><img src="http://programblings.com/wp-content/uploads/2008/06/gitk_accidental_stash_clear.png" alt="Oops! Accidentally lost the stash" /></p>
<p>Let&#8217;s follow Git&#8217;s suggestion and make that a branch.</p>
<pre><strong>mathieu@ml recovery (24e3752...)$ <font color="#0000ff">git checkout -b recovery</font>
Switched to a new branch "recovery"

mathieu@ml recovery (recovery)$</strong></pre>
<p><img src="http://programblings.com/wp-content/uploads/2008/06/gitk_stash_recovered_as_a_branch.png" alt="Stash recovered as a branch" /></p>
<p>Looks weird, like stashed items always do, but at least we have our commit.</p>
<p>After fiddling around with what&#8217;s been recovered from the stash, I recommend NOT keeping it as a commit.</p>
<p>If you try to replay the change in the recovery branch over master&#8217;s most recent commit, you lose the &#8220;Questioning the universe&#8221; commit. Probably because a stash is a weird kind of commit, or maybe because of a bug. I don&#8217;t know.</p>
<p><font color="#ff0000">(Don&#8217;t follow this one in your console) </font></p>
<pre><strong>mathieu@ml recovery (recovery)$ <font color="#000000">git rebase master  #I said don't do this one</font>
First, rewinding head to replay your work on top of it...
HEAD is now at 93b0c51... Now that was cool
Nothing to do.</strong></pre>
<p><img src="http://programblings.com/wp-content/uploads/2008/06/gitk_rebasing_over_master_doesnt_work.png" alt="Rebasing the recovered stash over master doesn’t work" /></p>
<p>If instead I checkout master and then rebase its last change over the &#8216;recovery&#8217; branch it seems to work.</p>
<p><img src="http://programblings.com/wp-content/uploads/2008/06/gitk_recovered_stash_back_in_master.png" alt="Recovered stash back in master" /></p>
<p>However since I just saw a commit disappear when rebasing the other way around, I get the feeling that this isn&#8217;t a normal commit and it may come back to haunt me later.</p>
<h4>Recover it by applying a diff</h4>
<p>Let&#8217;s just apply the diff to master. I&#8217;ll do as if it actually was a substantial commit, involving lots of modifications on lots of files, and apply it automatically with &#8216;git apply&#8217;.</p>
<p>First let&#8217;s visualize where we&#8217;re at, again:</p>
<p><img src="http://programblings.com/wp-content/uploads/2008/06/gitk_stash_recovered_as_a_branch.png" alt="Stash recovered as a branch" /></p>
<p>A diff against master is not what we want since master includes a new (very cool) commit.</p>
<p>Instead we just want to see the changes introduced by the current commit. To do this we can compare it with the common ancestor between the master and recovery branches. So let&#8217;s start by finding it&#8217;s ID.</p>
<p><img src="http://programblings.com/wp-content/uploads/2008/06/gik_find_common_ancestor.png" alt="Finding the ID of the common ancestor" /></p>
<pre><strong>mathieu@ml recovery (recovery)$ <font color="#0000ff">git diff 6da726f37683c83947d54314cd32ca1ee9d490e0</font>
diff --git a/file b/file
index 557db03..f2a8bf3 100644
--- a/file
+++ b/file
@@ -1 +1,2 @@
Hello World
<font color="#008000">+What does that mean?</font></strong></pre>
<p>Looks good. Now we throw that diff upstairs.</p>
<pre><font color="#0000ff"><strong>git diff 6da726f37683c83947d54314cd32ca1ee9d490e0 &gt; ../recovery.diff</strong></font></pre>
<p>Then get apply it to our master branch.</p>
<pre><strong>mathieu@ml recovery (recovery)$ <font color="#0000ff">git checkout master</font>
Switched to branch "master"

mathieu@ml recovery (master)$ <font color="#0000ff">git apply ../recovery.diff</font></strong></pre>
<p>And we finally confirm that everything&#8217;s under control.</p>
<pre><strong>mathieu@ml recovery (master)$ <font color="#0000ff">git status</font>
# On branch master
# Changed but not updated:
#   (use "git add &lt;file&gt;..." to update what will be committed)
#
#    modified:   file
#
no changes added to commit (use "git add" and/or "git commit -a")

mathieu@ml recovery (master)$ <font color="#0000ff">git diff</font>
diff --git a/file b/file
index 557db03..f2a8bf3 100644
--- a/file
+++ b/file
@@ -1 +1,2 @@
Hello World
<font color="#008000">+What does that mean?</font></strong></pre>
<p>This change was first stashed rather than committed because I felt it was not complete. Applying it with Git apply only introduces it as an unstaged change, which works perfectly for this situation. Now I can keep banging at the code until I feel this actually deserves to be committed.</p>
<pre><strong>mathieu@ml recovery (master)$ <font color="#0000ff">echo "I don't know" &gt;&gt; file</font>

mathieu@ml recovery (master)$ <font color="#0000ff">git commit -a -m "Conversation of staggering depth"</font>
Created commit 65a4794: Conversation of staggering depth
 1 files changed, 2 insertions(+), 0 deletions(-)</strong></pre>
<h3>Cleaning up the crud</h3>
<p>Ok, so now I still have this weird looking recovery branch.</p>
<p><img src="http://programblings.com/wp-content/uploads/2008/06/gitk_useless_recovery_branch.png" alt="Now we want to get rid of this weird recovery branch" /></p>
<p>Since it&#8217;s now useless we can get rid of it.</p>
<pre><strong>mathieu@ml recovery (master)$ <font color="#0000ff">git branch -d recovery</font>
error: The branch 'recovery' is not an ancestor of your current HEAD.
If you are sure you want to delete it, run 'git branch -D recovery'.</strong></pre>
<p>Aha! This time everything&#8217;s committed correctly, so I know I can delete it for real. Git is complaining because that commit was not included through its normal merge or rebase commands. So it warns me that I may be about to lose something. However I know I got everything through the diff I made and re-applied.</p>
<pre><strong>mathieu@ml recovery (master)$ <font color="#0000ff">git branch -D recovery</font>
Deleted branch recovery.</strong></pre>
<p>Now that I&#8217;m aware that commits are reachable even if they&#8217;re not in a branch anymore, I wonder about my repo&#8217;s size.</p>
<p><img src="http://programblings.com/wp-content/uploads/2008/06/repo_size_fat.png" alt="Repository size with a few dangling commits: 224kb" /></p>
<pre><strong>mathieu@ml recovery (master)$ <font color="#0000ff">git gc</font>
Counting objects: 22, done.
Compressing objects: 100% (14/14), done.
Writing objects: 100% (22/22), done.
Total 22 (delta 7), reused 0 (delta 0)

mathieu@ml recovery (master)$ <font color="#0000ff">git prune</font></strong></pre>
<p><img src="http://programblings.com/wp-content/uploads/2008/06/repo_size_slim.png" alt="Repo size after cleaning up the crud: 152kb" /></p>
<p>Fair enough. I would expect the unused commits to now be unreachable, but strangely enough:</p>
<pre><strong>mathieu@ml recovery (master)$ <font color="#0000ff">git fsck −−lost-found</font>
dangling commit 49ed65cdea22443af3f1fd400754fe1517421b24
dangling commit 4b1bf4792cba929e88114379d7d5e86a2dc9990f
dangling commit 6cdf88318109dede7bd3c1a75be76c7255708ded
dangling commit 715a6b2cfe797383216d0f9b04fe8f50e90e779f
dangling commit f443703e5060d9f3b4d97504bda5f97e5a0b31e8</strong></pre>
<p>If anyone finds out what that&#8217;s all about, please let me know!</p>
<p>Maybe Git&#8217;s just refusing to do any work unless it&#8217;s going to actually save a considerable amount of space? I have no idea.</p>
<h2>Conclusion</h2>
<p>Once you know how to recover from bad mistakes, you&#8217;ll find that Git is not only a very powerful tool, but also a very forgiving one. As opposed to a motocross.</p>
<p>The following commands will help you figure you way out of most bad situations:</p>
<ul>
<li>git show</li>
<li>git fsck −−lost-found</li>
<li>git diff</li>
</ul>
<p>And these ones will actually get out of these bad situations:</p>
<ul>
<li>git rebase</li>
<li>git cherry-pick</li>
<li>git merge</li>
<li>git apply</li>
</ul>
<p>As I think I demonstrated, Git gives you the ability to recover from most bad mistakes. The fact that any single commit can be cherry-picked, checked out, rebased or merged makes it really easy to recover from hairy situations.</p>
<p>The only case where you might actually lose information is when something has not been committed or stashed yet, which I think is perfectly reasonable.</p>
<p>So if you take only one thing away from this article, let it be this. Git is much safer than a motocross.</p>
<h3>Footnotes</h3>
<p>[1] At the time I didn&#8217;t know that just having the SHA1 id was enough to save me.</p>
<p>[2] See how to configure your console in the same manner and also get auto-completion for Git <a href="http://jfcouture.com/2007/12/18/various-tips-for-setting-up-git-improve-gitk-look-and-get-bash-completion/" title="Various Tips For Setting Up Git: Improve Gitk Look And Get Bash Completion">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://programblings.com/2008/06/07/the-illustrated-guide-to-recovering-lost-commits-with-git/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Git is a dangerous tool to use</title>
		<link>http://programblings.com/2008/05/14/git-is-a-dangerous-tool-to-use/</link>
		<comments>http://programblings.com/2008/05/14/git-is-a-dangerous-tool-to-use/#comments</comments>
		<pubDate>Wed, 14 May 2008 22:34:34 +0000</pubDate>
		<dc:creator>Mathieu Martin</dc:creator>
				<category><![CDATA[garbage out]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://programblings.com/2008/05/14/git-is-a-dangerous-tool-to-use/</guid>
		<description><![CDATA[Quote from the Git documentation:
&#60;branch&#62;
When this parameter names a non-branch (but still a valid commit object), your HEAD becomes detached.
Junio C. Hamano &#8212; the checkout documentation
Git &#8212; the only SCM that beheads its users.
]]></description>
			<content:encoded><![CDATA[<p>Quote from the Git documentation:</p>
<blockquote><p>&lt;<em>branch</em>&gt;</p>
<p>When this parameter names a non-branch (but still a valid commit object), your HEAD becomes <em>detached</em>.<br />
Junio C. Hamano &#8212; <a href="http://www.kernel.org/pub/software/scm/git/docs/v1.5.4.3/git-checkout.html">the checkout documentation</a></p></blockquote>
<p>Git &#8212; the only SCM that beheads its users.</p>
]]></content:encoded>
			<wfw:commentRss>http://programblings.com/2008/05/14/git-is-a-dangerous-tool-to-use/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Rubinius for the Layman, Part 2: How Rubinius is Friendly</title>
		<link>http://programblings.com/2008/04/15/rubinius-for-the-layman-part-2-how-rubinius-is-friendly/</link>
		<comments>http://programblings.com/2008/04/15/rubinius-for-the-layman-part-2-how-rubinius-is-friendly/#comments</comments>
		<pubDate>Tue, 15 Apr 2008 11:54:28 +0000</pubDate>
		<dc:creator>Mathieu Martin</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[rubinius]]></category>

		<guid isPermaLink="false">http://programblings.com/2008/04/15/rubinius-for-the-layman-part-2-how-rubinius-is-friendly/</guid>
		<description><![CDATA[This is part two of an ongoing series about Rubinius:

 Rubinius for the Layman, Part 1: Rubies All the Way Down
Rubinius for the Layman, Part 2: How Rubinius is Friendly

In this shorter second installment, I&#8217;ll present the ways in which Rubinius will be friendly to your multiple personalities:

 you, the programmer;
you, the (potential) contributor.

Rubinius is <a href='http://programblings.com/2008/04/15/rubinius-for-the-layman-part-2-how-rubinius-is-friendly/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>This is part two of an ongoing series about Rubinius:</p>
<ul>
<li><a href="http://programblings.com/2008/04/01/rubinius-for-the-layman-part-1-rubies-all-the-way-down/"> Rubinius for the Layman, Part 1: Rubies All the Way Down</a></li>
<li>Rubinius for the Layman, Part 2: How Rubinius is Friendly</li>
</ul>
<p>In this shorter second installment, I&#8217;ll present the ways in which Rubinius will be friendly to your multiple personalities:</p>
<ul>
<li> you, the programmer;</li>
<li>you, the (potential) contributor.</li>
</ul>
<h2>Rubinius is programmer-friendly</h2>
<h3>Backtraces</h3>
<p>The first reason why I consider Rubinius more programmer-friendly is the better backtraces. I&#8217;ll show some examples run from each interpreter&#8217;s interactive console.</p>
<p>Take the following piece of buggy code. Notice the nil at the end of the array.</p>
<pre>ary=['bob', 'mom', nil].inject([]) {|result, element| result &lt;&lt; element.to_sym}</pre>
<p>With MRI you get the following:</p>
<pre>NoMethodError: undefined method `to_sym' for nil:NilClass
        from (irb):5
        from (irb):5:in `inject'
        from (irb):5:in `each'
        from (irb):5:in `inject'
        from (irb):5</pre>
<p>Ok, we have basic information on all the method calls that led to the NoMethodError.</p>
<p>Rubinius goes a step further, however:</p>
<pre>NoMethodError: No method 'to_sym' on an instance of NilClass.
   from Kernel(NilClass)#to_sym (method_missing_cv) at kernel/core/kernel.rb:606
   from Object#irb_binding {} at (irb):4
   from <strong><font color="#ff6600">Enumerable(Array)</font></strong>#inject {} at kernel/core/enumerable.rb:375
   from Array#each at kernel/core/array.rb:573
   from Enumerable(Array)#inject at kernel/core/enumerable.rb:371
   from Object#irb_binding {} at (irb):4</pre>
<p>The backtrace tells me in which <strong><em>module</em></strong> each method on the stack was defined!</p>
<p>Q: How awesome is that?</p>
<p>A: Very!</p>
<p>I&#8217;m almost looking forward to debugging buggy mixins or method chains. Aren&#8217;t you?</p>
<p>These backtraces will definitely come in handy when debugging in situations where a lot of magic is happening behind the scenes.</p>
<h3>Bring back the horse!</h3>
<p>There&#8217;s another interesting detail about the backtraces. Remember what language Rubinius is written in? Heh. The backtraces Rubinius generates go deeper.</p>
<p>Say we have another piece of buggy code:</p>
<pre>s = 'ahh'
s[1] = nil</pre>
<p>MRI:</p>
<pre>TypeError: can't convert nil into String
 from (irb):5:in `[]='
 from (irb):5</pre>
<p>Rubinius:</p>
<pre>TypeError: Coercion error: nil.to_str =&gt; String failed:
(undefined local variable or method `to_str' for nil)
   from Type.coerce_to at kernel/core/kernel.rb:19
   from Kernel(String)#StringValue at kernel/core/kernel.rb:80
<strong><font color="#ff6600">   from String#splice! at kernel/core/string.rb:2192
   from String#[]= at kernel/core/string.rb:360
</font></strong>   from Object#irb_binding {} at (irb):8</pre>
<p>Not only is the message more descriptive, but as you can see, we can see deeper into the interpreter&#8217;s inner workings.</p>
<p>The argument could be made that this could lead to noisier backtraces. On one hand it&#8217;s true that adding 5 lines to a 30+ lines backtrace generated in a Rails unit test will rarely help. On the other hand, all this additional information may sometimes help finding subtle bugs (in user code or in Rubinius) or figure out that our use of a feature is not quite correct.</p>
<p>I say the additional information is very welcome. And to help keep the information overload in check, let&#8217;s get off our <a href="http://en.wikipedia.org/wiki/Ass_%28animal%29">asses</a> and use the <a href="http://jamesgolick.com/2007/12/3/noisy-backtraces-got-you-down">quiet_backtrace</a> gem by James Golick and Dan Croak.</p>
<h3>The real Rubinius backtraces</h3>
<p>It gets even better. The previous examples were only run in irb. So the additionnal information was getting squeezed in IRB&#8217;s exception formatting. Say I save both pieces of buggy code to 1.rb and 2.rb. You&#8217;ll notice too that I split program 2 in 2.rb and /lib/2.rb (I plan on making it a gem).</p>
<p>Here&#8217;s in full colored glory the insults Rubinius will throw back at me:</p>
<pre>mat@laptop rubinius $ rbx 1.rb
An exception has occurred:
    No method 'to_sym' on an instance of NilClass. (NoMethodError)Backtrace:
<font color="#ff0000">    Kernel(NilClass)#to_sym (method_missing_cv) at kernel/core/kernel.rb:612
</font>                        Object#__script__ {} at 1.rb:1
<font color="#0000ff">                 Enumerable(Array)#inject {} at kernel/core/enumerable.rb:375
                                  Array#each at kernel/core/array.rb:573
                    Enumerable(Array)#inject at kernel/core/enumerable.rb:371
</font>                           Object#__script__ at 1.rb:1
<font color="#0000ff">                    CompiledMethod#as_script at kernel/core/compiled_method.rb:326
                         Compile.single_load at kernel/core/compile.rb:238
                 Compile.load_from_extension at kernel/core/compile.rb:310
                           Object#__script__ at kernel/loader.rb:190
</font>
mat@laptop rubinius $ rbx 2.rb
An exception has occurred:
    Coercion error: nil.to_str =&gt; String failed:
(undefined local variable or method `to_str' for nil) (TypeError)
Backtrace:
                 <font color="#ff0000">Type.coerce_to at kernel/core/kernel.rb:19</font>
     <font color="#0000ff">Kernel(String)#StringValue at kernel/core/kernel.rb:80
                 String#splice! at kernel/core/string.rb:2192
                     String#[]= at kernel/core/string.rb:360</font>
              Object#__script__ at ./lib/2.rb:2
       <font color="#0000ff">CompiledMethod#as_script at kernel/core/compiled_method.rb:326
            Compile.single_load at kernel/core/compile.rb:238
        Compile.unified_load {} at kernel/core/compile.rb:149
                     Array#each at kernel/core/array.rb:573
           Compile.unified_load at kernel/core/compile.rb:120
         Kernel(Object)#require at kernel/core/compile.rb:450</font>
              Object#__script__ at 2.rb:1
       <font color="#0000ff">CompiledMethod#as_script at kernel/core/compiled_method.rb:326
            Compile.single_load at kernel/core/compile.rb:233
    Compile.load_from_extension at kernel/core/compile.rb:310
              Object#__script__ at kernel/loader.rb:190</font></pre>
<p>Holy f****** sh** Batman! How centering the lines makes a difference!</p>
<p>To the left is the logical location: the class/module and the method name. To the right is just the necessary information about the physical location. Notice the paths. They only contain what you need i.e. the relative path to execution &#8212; relative to the VM for Rubinius code, and relative to the execution root of my glorious code.</p>
<p>Don&#8217;t tell anyone, but I think I&#8217;ll intentionally put in bugs at work. Just to see these in the logs! Too bad our logs don&#8217;t support coloring.</p>
<h2>Rubinius is contributor-friendly</h2>
<h3>Commit access</h3>
<p>The Rubinius project is friendly for the programmer who uses it. But the project itself is also friendly to potential contributors. They currently have a policy called the free-flowing commit bit. This policy says the following:</p>
<p>Anyone who submits a patch which is accepted is granted commit access.</p>
<p>In case you missed it, here it is again:</p>
<p><font color="#ff0000"><em>Anyone who submits a patch which is accepted is granted commit access.</em></font></p>
<p>This is not crazy talk. The patch can be as simple as you want. A correction to documentation or a spec for the behavior of a Ruby class not behaving properly under Rubinius.  Any form of submission is admissible: a <a href="http://pastie.caboo.se/">pastie</a>, a ticket prepended with [PATCH] <a href="http://rubinius.lighthouseapp.com/projects/5089/howto-write-a-ticket">on lighthouse</a>, or any other traditional way (emails, ransom notes etc.) Of course these methods are only temporary, since you&#8217;re going to get commit access afterwards.</p>
<p>The idea in being so liberal with commit access is to put the barrier to contribution as low as possible. This way, when your commit bit is set, you&#8217;re going to be tempted to help more. And your next contribution is going to be so much easier to submit.</p>
<p>A masterful adaptation of the timeless &#8216;gateway drug&#8217; style of recruiting, really. Get them hooked with as little friction as possible. Then let them, uhhh, flourish in the wonderful world they just discovered.</p>
<p>How&#8217;s that for being contributor-friendly? This may not last forever, I guess. So hurry up and submit a patch! ;-)</p>
<p>The naysayers might once again intervene to remind us that this isn&#8217;t going to scale. Well it&#8217;s every open source project&#8217;s dream to have too many contributors. The community and the team will adapt in time. The fact that Rubinius is hosted with Git also gives the team much more flexibility to try different committing strategies, or simply gives more power to recover from mistakes from newcomers.</p>
<p>To really have a better understanding of Evan&#8217;s vision of the Rubinius community, I highly recommend watching the video of <a href="http://mwrc2008.confreaks.com/01phoenix.html">his presentation at MountainWest RubyConf</a>. The presentation&#8217;s content is really not the same as <a href="http://rubyconf2007.confreaks.com/d2t1p3_rubinius.html">the other presentation</a> mentioned in my first article. Both are really worth it.</p>
<h2>Conclusion</h2>
<p>That&#8217;s it for now, folks. This is how much Rubinius will be friendly to you. Delicious stacktraces and a very welcoming project. A project ready to give you commit access if you submit anything good: a spec, some doc, or just a plain ol&#8217; bug fix.</p>
<p><a href="http://feeds.feedburner.com/Programblings">Stay tuned</a> for the next installment, in which I&#8217;ll start covering a few mildly technical bits of Rubinius. Unless I change my mind and decide to tackle another aspect of Rubinius.</p>
<p>A few references:</p>
<ul>
<li>The links for the videos are 3 paragraphs up, you lazy reader. No wait, I&#8217;m the one being lazy here.</li>
<li><a href="http://rubinius.lighthouseapp.com/projects/5089/howto-write-a-ticket">How to write a ticket</a> for the Rubinius project.</li>
<li>Let&#8217;s bug James Golick and Dan Croak so they make sure <a href="http://quietbacktrace.rubyforge.org/">quiet_backtrace</a> is ready for these deep Rubinius stack traces. Ha! Sorry <a href="http://jamesgolick.com">James</a> :-)</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://programblings.com/2008/04/15/rubinius-for-the-layman-part-2-how-rubinius-is-friendly/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>irbrc for the runtime tramp</title>
		<link>http://programblings.com/2008/04/11/irbrc-for-the-runtime-tramp/</link>
		<comments>http://programblings.com/2008/04/11/irbrc-for-the-runtime-tramp/#comments</comments>
		<pubDate>Sat, 12 Apr 2008 04:11:46 +0000</pubDate>
		<dc:creator>Mathieu Martin</dc:creator>
				<category><![CDATA[garbage out]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[irbrc]]></category>

		<guid isPermaLink="false">http://programblings.com/2008/04/11/irbrc-for-the-runtime-tramp/</guid>
		<description><![CDATA[I&#8217;m taking a break from the Rubinius for the Layman series. I don&#8217;t know why my posts always spiral into multi-thousand words essays :-) Even worse, when I try to write about Rubinius it&#8217;s so easy to get into ratholes and start fiddling, poking at and exploring this wonderful beast. All of that instead of <a href='http://programblings.com/2008/04/11/irbrc-for-the-runtime-tramp/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m taking a break from the <a HREF="http://programblings.com/2008/04/01/rubinius-for-the-layman-part-1-rubies-all-the-way-down/">Rubinius for the Layman</a> series. I don&#8217;t know why my posts always spiral into multi-thousand words essays :-) Even worse, when I try to write about Rubinius it&#8217;s so easy to get into ratholes and start fiddling, poking at and exploring this wonderful beast. All of that instead of writing, of course.</p>
<p>Tonight&#8217;s fiddling led me to playing around with my .irbrc file. I guess we&#8217;ve all searched for examples of config files for IRB at one time or another. When you spend a lot of time into your interactive console, you naturally end up wanting to tweak it to your liking.</p>
<p>However you&#8217;ll start having problems as soon as you start fooling around with the different runtimes. Or when you share your irbrc between different machines. Maybe even on different OSes. Either some gems are unsupported or you haven&#8217;t installed them yet (and don&#8217;t necessarily care).</p>
<p>So tonight I tried to fix that problem. My solution is only a small method that I define in my irbrc, so I&#8217;m not sure it&#8217;s worth putting it on github yet :-) Let me know what you think.</p>
<h2>Presenting tramp_require</h2>
<h3>Usage</h3>
<p>When my irbrc requires something just so I don&#8217;t need to do it manually:</p>
<pre>tramp_require 'pp' #=&gt; true/false (same return value as a normal require)</pre>
<p>Outcome if the gem is not installed:</p>
<pre>** Unable to require 'wirble'
--&gt; LoadError: Did not find file to load: wirble</pre>
<p>And you IRB loads without a problem (just without the gem pre-loaded).</p>
<p>When I require something I actually use in my .irbrc:</p>
<pre>tramp_require('wirble') do
  Wirble.init(:skip_prompt=&gt;true)
  Wirble.colorize
end</pre>
<p>If the gem is loaded successfully, the block is executed.</p>
<p>If the gem isn&#8217;t loaded successfully, the block&#8217;s not executed and the same warning message is shown.</p>
<p>Note that the user code passed in the block is not being rescued: if it your code fails, it&#8217;s your problem :-)</p>
<h3>Implementation</h3>
<p>Here I&#8217;ll paste 2 equivalent implementations. The first one is a clean and understandable version (<a HREF="http://pastie.caboo.se/179531">also on pastie</a>):</p>
<pre>def tramp_require(what, &amp;block)
  loaded, require_result = false, nil 

  begin
    require_result = require what
    loaded = true 

  rescue Exception =&gt; ex
    puts "** Unable to require '#{what}'"
    puts "--&gt; #{ex.class}: #{ex.message}"
  end 

  yield if loaded and block_given? 

  require_result
end</pre>
<p>This second version is the one I actually use, if I set the debug variable to false the result is the same as the previous implementation. If I set it to true, I get much more information, including the full backtrace of the exception (also <a HREF="http://pastie.caboo.se/179532">on pastie</a>):</p>
<pre>$debug_irbrc=false 

def tramp_require(what, &amp;block)
  loaded, require_result = false, nil 

  begin
    puts('', "requiring #{what}") if $debug_irbrc
    require_result = require what
    loaded = true
    puts "successfully required #{what}" if $debug_irbrc 

  rescue Exception =&gt; ex
    puts "** Unable to require '#{what}'"
    exception_details = "#{ex.class}: #{ex.message}"
    if $debug_irbrc
      ex.backtrace.reverse.each{|l| exception_details &lt; &lt; "\n   #{l}"}
    else
      exception_details.insert(0, "--&gt; ")
    end
    puts exception_details
  end 

  if loaded and block_given?
    puts "executing block for #{what}" if $debug_irbrc
    yield
  end 

  require_result
end</pre>
<p>Feel free to use these snippets as you see fit :-)</p>
<p>The obligatory full paste of my irbrc is <a HREF="http://pastie.caboo.se/179529">available on pastie</a>, for the curious.</p>
<p>One word of warning, however. I&#8217;m guessing some of you will rename tramp_require to something more boring. Just don&#8217;t rename it to irb_require. IRB already defines a method named this way.</p>
]]></content:encoded>
			<wfw:commentRss>http://programblings.com/2008/04/11/irbrc-for-the-runtime-tramp/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Rubinius for the Layman, Part 1: Rubies All the Way Down</title>
		<link>http://programblings.com/2008/04/01/rubinius-for-the-layman-part-1-rubies-all-the-way-down/</link>
		<comments>http://programblings.com/2008/04/01/rubinius-for-the-layman-part-1-rubies-all-the-way-down/#comments</comments>
		<pubDate>Tue, 01 Apr 2008 12:29:05 +0000</pubDate>
		<dc:creator>Mathieu Martin</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[rubinius]]></category>

		<guid isPermaLink="false">http://programblings.com/2008/04/01/rubinius-for-the-layman-part-1-rubies-all-the-way-down/</guid>
		<description><![CDATA[This is part one of an ongoing series about Rubinius:

 Rubinius for the Layman, Part 1: Rubies All the Way Down
Rubinius for the Layman, Part 2: How Rubinius is Friendly

In January, Antonio Cangiano wrote an article titled Why Engine Yard, Rubinius and Merb matter. In his article he discussed the financing of Engine Yard. More <a href='http://programblings.com/2008/04/01/rubinius-for-the-layman-part-1-rubies-all-the-way-down/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>This is part one of an ongoing series about Rubinius:</p>
<ul>
<li> Rubinius for the Layman, Part 1: Rubies All the Way Down</li>
<li><a href="http://programblings.com/2008/04/15/rubinius-for-the-layman-part-2-how-rubinius-is-friendly/">Rubinius for the Layman, Part 2: How Rubinius is Friendly</a></li>
</ul>
<p>In January, Antonio Cangiano wrote an article titled <a href="http://antoniocangiano.com/2008/01/15/why-engine-yard-rubinius-and-merb-matter/">Why Engine Yard, Rubinius and Merb matter</a>. In his article he discussed the financing of Engine Yard. More specifically, he discussed why EY was not just another irrelevant startup being funded by starry-eyed investors. <em>Au contraire!</em> Engine Yard is already recognized as a solid hosting service provider for Ruby on Rails, and has a customer base. He then went on to discuss how they are going to use the money to fund the development of Merb and Rubinius by hiring the main contributors and paying them to work on these projects.</p>
<p>These two projects are very important for the future of the Ruby ecosystem. <a href="http://rubini.us/">Rubinius</a> is an attempt at a very powerful Ruby VM while <a href="http://merbivore.com/">Merb</a> is an attempt at a solid alternative to Rails, with its own distinct advantages. It&#8217;s great to hear that EY has taken it upon themselves to basically put both projects on steroids.</p>
<p>Being interested in the different Ruby interpreters / VMs, I was glad to get this overview of the event. On the other hand, I was hoping to get more juicy bits on the technology side of Rubinius. Since I&#8217;m already familiar with the project (from afar), I thought  maybe I could come up with another more technical view on Rubinius. Well, let&#8217;s say a layman&#8217;s technical view on Rubinius.</p>
<p>I&#8217;ve been putting off this series of articles for a couple of weeks because I took the opportunity to talk about Rubinius at the last <a href="http://www.montrealonrails.com/2008/02/25/mor-8-march-18/">Montreal on Rails</a>. I didn&#8217;t want to steal my own punch lines on my blog before the presentation.</p>
<p>In this series of articles I&#8217;ll try to present the Rubinius project from a technical point of view. A 10 000 ft technical view, that is. Some of what I say here is in part based on Evan Phoenix&#8217; presentation at RubyConf 2007, so some of it could sound familiar to those who attended or <a href="http://rubyconf2007.confreaks.com/d2t1p3_rubinius.html">watched the video</a> (highly recommended).</p>
<h2>Q: What is Rubinius?</h2>
<p>A: A Ruby VM and Runtime written as much as possible in Ruby, and as little as possible in C. The goal is eventually to completely eliminate the C code.</p>
<p>Of course, the first question that comes to mind is: <strong>WTF</strong>? It&#8217;s a perfectly understandable reaction. So in this first article I&#8217;ll mostly address the 3 letter question. The next articles will address all the other aspects of this fascinating project.</p>
<h2>It&#8217;s not a bad idea</h2>
<p>It&#8217;s a traditional milestone for any language: the ultimate level of dogfooding. Implementing a VM or a runtime for a language with this very language means a lot in terms of the language&#8217;s maturity and power.</p>
<p>And this is valid for many other technologies, too. It&#8217;s been a very important milestone for Subversion as well some years back, for example. <a href="http://subversion.tigris.org/svn-dav-securityspace-survey.html">Their exponential growth</a> really took off when they started using their own Subversion server to host their repository.</p>
<p>Some Ruby skeptics might say that Ruby is not fast and mature enough to implement a VM.</p>
<p>Let&#8217;s first address the assertion that &#8216;Ruby is slow&#8217;. It&#8217;s a sentence that doesn&#8217;t really make sense, when you think about it: Ruby is a language. Apart from being dynamic, very little of the language&#8217;s characteristics fundamentally limit the performance it can get. Its current performance problems rather come from its default interpreter, MRI.</p>
<p>As for the maturity of the language, I agree that some of its features may not be such great ideas. Current work on alternative implementations has brought some of them to light, and from here they mostly look like features that are not in the right place. If a project depends on ObjectSpace, well maybe a better design could circumvent that need. And tainting might not be the most sound security model. Whatever. The parts that don&#8217;t work are as of now slowly being weeded out by the different Ruby implementers, including by Matz himself who works on YARV.</p>
<p>So Ruby is maturing right now. The ultimate level of dogfooding to help that process is to use it to implement itself.</p>
<h2>It&#8217;s actually a great idea</h2>
<h3>Who wants to program in Ruby?</h3>
<p>If you&#8217;re interested in working on VM technology and you love the Ruby language, here are your options*:</p>
<table id="wptable-5" class="wptable rowstyle-alt" border="0" cellspacing="1">
<thead>
<tr>
<th class="sortable" style="width: 150px;" align="center">Interpreter</th>
<th class="sortable" style="width: 150px;" align="center">LOC (non Ruby)</th>
<th class="sortable" style="width: 150px;" align="center">LOC (Ruby)</th>
</tr>
</thead>
<tbody>
<tr>
<td style="width: 150px;" align="center">MRI (Ruby 1.8)</td>
<td style="width: 150px;" align="center">85 000, C</td>
<td style="width: 150px;" align="center">0</td>
</tr>
<tr class="alt">
<td style="width: 150px;" align="center">YARV (Ruby 1.9)</td>
<td style="width: 150px;" align="center">129 000, C</td>
<td style="width: 150px;" align="center">0</td>
</tr>
<tr>
<td style="width: 150px;" align="center">JRuby</td>
<td style="width: 150px;" align="center">115 000, Java</td>
<td style="width: 150px;" align="center">~ 1 000</td>
</tr>
<tr class="alt">
<td style="width: 150px;" align="center">IronRuby</td>
<td style="width: 150px;" align="center">48 000, C#</td>
<td style="width: 150px;" align="center">0</td>
</tr>
<tr>
<td style="width: 150px;" align="center">Rubinius</td>
<td style="width: 150px;" align="center">25 000, C</td>
<td style="width: 150px;" align="center">14 000</td>
</tr>
</tbody>
</table>
<p>I finally have a day job writing Ruby (thanks <a href="http://blog.carlmercier.com/">Carl</a>). I&#8217;m sorry to tell you that I&#8217;m not interested in going back to Java or C# in my spare time if I can help it.</p>
<p>Actually, the case is probably even stronger for my fellow programmers who work with Java or C# during the day, dreaming of coming back to their Ruby-red passionate lover at night. Very few of them will come home and fire up Visual Studio / Eclipse / Netbeans, methinks.</p>
<p>* Actually this is an overstatement: some of these projects are very open to contribution, while others are pretty much closed to outside contribution. More on that later.</p>
<p>** These number are those from Evan&#8217;s presentation at the end of 2007, so they&#8217;re probably quite outdated. My other option was running <a href="http://www.dwheeler.com/sloccount/">sloccount</a> on 5 projects I don&#8217;t know closely enough and getting all the numbers wrong :-)</p>
<h3>Getting feature-complete with how many lines of code?</h3>
<p>Another side effect of using Ruby to implement Rubinius seems to be often overlooked. Rubinius is getting close to feature-complete with under 50 000 LOC. Ruby&#8217;s a very expressive language, remember?</p>
<h3>The Ruby part is reusable</h3>
<p>Here&#8217;s what I expect from a feature-complete Ruby interpreter:</p>
<p><img src="http://programblings.com/wp-content/uploads/2008/04/ruby_interpreter_expectations.png" alt="ruby_interpreter_expectations.png" width="280" height="82" /></p>
<p>Actually, if we look underneath, we see MRI and YARV are implemented that way:</p>
<p><img src="http://programblings.com/wp-content/uploads/2008/04/ruby_interpreter_mri.png" alt="ruby_interpreter_mri.png" width="280" height="82" /></p>
<p>When we look at Rubinius, as mentioned already, we see it&#8217;s implemented like that:</p>
<p><img src="http://programblings.com/wp-content/uploads/2008/04/ruby_interpreter_rubinius.png" alt="ruby_interpreter_rubinius.png" width="280" height="82" /></p>
<p>So if I want to implement my own revolutionary Ruby interpreter with <a href="http://lolcode.com/">LOLCODE</a>, I now have the option to implement a core VM and use as much as possible from Rubinius for the rest:</p>
<p><img src="http://programblings.com/wp-content/uploads/2008/04/ruby_interpreter_lolcode.png" alt="ruby_interpreter_lolcode.png" width="280" height="82" /></p>
<p>So by reusing Rubinius&#8217; Ruby runtime, 1.0 is gonna come much faster now. If some parts are too slow and for some reason can&#8217;t be sped up enough with this approach, I can always get back to the bare metal LOLCODE when comes time to optimize performance. Neat, isn&#8217;t it?</p>
<h2>But&#8230; how is that possible?</h2>
<p>Enough about why it&#8217;s a great idea. Is it even possible to implement Ruby in Ruby (and end up with something decent)? Actually, yes. It&#8217;s been done before for languages with similar characteristics.</p>
<p>Ruby&#8217;s a dynamic language. Dynamic languages have the reputation of being slow, right? I can concede that there&#8217;s probably an upper bound to how fast a dynamic language can get. And this upper bound is probably lower than that of a statically typed language.</p>
<p>But let&#8217;s not forget that Smalltalk and Lisp are dynamic languages as well. There are very fast implementations of both languages. Word on the street is that Smalltalk has been seen running at about half the speed of C. Unfortunately, I have no actual precise reference on that. You should therefore assume that it&#8217;s a lie. Just pay attention when you hear the name <a href="http://strongtalk.org/">Strongtalk</a>.</p>
<p>A lot of research has been made in the Smalltalk community in the past 30 years. The Rubinius team is drawing on this research as well as other recent virtual machine research. The VM is loosely based on the Smalltalk-80 architecture as described in the Blue Book.</p>
<h3>Still don&#8217;t believe me?</h3>
<p>Here&#8217;s how a recent build of Rubinius compares to MRI.</p>
<h4>An overview</h4>
<table id="wptable-4" class="wptable rowstyle-alt" border="0" cellspacing="1">
<thead>
<tr>
<th class="sortable" style="width: 100px;" align="center">Comparison</th>
<th class="sortable" style="width: 60px;" align="center">MRI</th>
<th class="sortable" style="width: 60px;" align="center">Rubinius</th>
<th class="sortable" style="width: 250px;" align="left">Blah blah blah</th>
</tr>
</thead>
<tbody>
<tr>
<td style="width: 100px;" align="center">Performance winner</td>
<td style="width: 60px;" align="center">12 / 41</td>
<td style="width: 60px;" align="center">28 / 41</td>
<td style="width: 250px;" align="left">Big improvement over the numbers shown by Evans at RubyConf 2007</td>
</tr>
<tr class="alt">
<td style="width: 100px;" align="center">Errors</td>
<td style="width: 60px;" align="center">2</td>
<td style="width: 60px;" align="center">0</td>
<td style="width: 250px;"></td>
</tr>
<tr>
<td style="width: 100px;" align="center">Timeouts</td>
<td style="width: 60px;" align="center">2</td>
<td style="width: 60px;" align="center">2</td>
<td style="width: 250px;" align="left">It&#8217;s a tie!</td>
</tr>
</tbody>
</table>
<h4>The details</h4>
<p>These following measurements are in seconds, so lower is better.</p>
<table id="wptable-2" class="wptable rowstyle-alt" border="0" cellspacing="1">
<thead>
<tr>
<th class="sortable" style="width: 250px;" align="left">Benchmark</th>
<th class="sortable" style="width: 100px;" align="right">MRI</th>
<th class="sortable" style="width: 100px;" align="right">Rubinius</th>
</tr>
</thead>
<tbody>
<tr>
<td style="width: 250px;" align="left">bm_app_answer.rb</td>
<td style="width: 100px;" align="right">0.526643</td>
<td style="width: 100px;" align="right">0.687349</td>
</tr>
<tr class="alt">
<td style="width: 250px;" align="left">bm_app_factorial.rb</td>
<td style="width: 100px;" align="right">Error</td>
<td style="width: 100px;" align="right">0.859864</td>
</tr>
<tr>
<td style="width: 250px;" align="left">bm_app_fib.rb</td>
<td style="width: 100px;" align="right">6.112832</td>
<td style="width: 100px;" align="right">2.934078</td>
</tr>
<tr class="alt">
<td style="width: 250px;" align="left">bm_app_mandelbrot.rb</td>
<td style="width: 100px;" align="right">2.185676</td>
<td style="width: 100px;" align="right">8.210969</td>
</tr>
<tr>
<td style="width: 250px;" align="left">bm_app_pentomino.rb</td>
<td style="width: 100px;" align="right">Timeout</td>
<td style="width: 100px;" align="right">Timeout</td>
</tr>
<tr class="alt">
<td style="width: 250px;" align="left">bm_app_raise.rb</td>
<td style="width: 100px;" align="right">2.362519</td>
<td style="width: 100px;" align="right">1.898819</td>
</tr>
<tr>
<td style="width: 250px;" align="left">bm_app_strconcat.rb</td>
<td style="width: 100px;" align="right">1.523553</td>
<td style="width: 100px;" align="right">2.042877</td>
</tr>
<tr class="alt">
<td style="width: 250px;" align="left">bm_app_tak.rb</td>
<td style="width: 100px;" align="right">8.835661</td>
<td style="width: 100px;" align="right">4.003406</td>
</tr>
<tr>
<td style="width: 250px;" align="left">bm_app_tarai.rb</td>
<td style="width: 100px;" align="right">7.101123</td>
<td style="width: 100px;" align="right">3.922363</td>
</tr>
<tr class="alt">
<td style="width: 250px;" align="left">bm_loop_times.rb</td>
<td style="width: 100px;" align="right">4.696043</td>
<td style="width: 100px;" align="right">6.964689</td>
</tr>
<tr>
<td style="width: 250px;" align="left">bm_loop_whileloop.rb</td>
<td style="width: 100px;" align="right">8.90748</td>
<td style="width: 100px;" align="right">1.929943</td>
</tr>
<tr class="alt">
<td style="width: 250px;" align="left">bm_loop_whileloop2.rb</td>
<td style="width: 100px;" align="right">17.83614</td>
<td style="width: 100px;" align="right">3.37839</td>
</tr>
<tr>
<td style="width: 250px;" align="left">bm_so_ackermann.rb</td>
<td style="width: 100px;" align="right">Error</td>
<td style="width: 100px;" align="right">3.073072</td>
</tr>
<tr class="alt">
<td style="width: 250px;" align="left">bm_so_array.rb</td>
<td style="width: 100px;" align="right">6.388754</td>
<td style="width: 100px;" align="right">5.85562</td>
</tr>
<tr>
<td style="width: 250px;" align="left">bm_so_concatenate.rb</td>
<td style="width: 100px;" align="right">1.791939</td>
<td style="width: 100px;" align="right">10.598892</td>
</tr>
<tr class="alt">
<td style="width: 250px;" align="left">bm_so_count_words.rb</td>
<td style="width: 100px;" align="right">0.067646</td>
<td style="width: 100px;" align="right">1.985533</td>
</tr>
<tr>
<td style="width: 250px;" align="left">bm_so_exception.rb</td>
<td style="width: 100px;" align="right">3.754216</td>
<td style="width: 100px;" align="right">2.642568</td>
</tr>
<tr class="alt">
<td style="width: 250px;" align="left">bm_so_lists.rb</td>
<td style="width: 100px;" align="right">10.856124</td>
<td style="width: 100px;" align="right">Timeout</td>
</tr>
<tr>
<td style="width: 250px;" align="left">bm_so_matrix.rb</td>
<td style="width: 100px;" align="right">3.135463</td>
<td style="width: 100px;" align="right">3.997002</td>
</tr>
<tr class="alt">
<td style="width: 250px;" align="left">bm_so_nested_loop.rb</td>
<td style="width: 100px;" align="right">7.52997</td>
<td style="width: 100px;" align="right">9.081536</td>
</tr>
<tr>
<td style="width: 250px;" align="left">bm_so_object.rb</td>
<td style="width: 100px;" align="right">6.33225</td>
<td style="width: 100px;" align="right">4.37211</td>
</tr>
<tr class="alt">
<td style="width: 250px;" align="left">bm_so_random.rb</td>
<td style="width: 100px;" align="right">1.939179</td>
<td style="width: 100px;" align="right">5.510661</td>
</tr>
<tr>
<td style="width: 250px;" align="left">bm_so_sieve.rb</td>
<td style="width: 100px;" align="right">Timeout</td>
<td style="width: 100px;" align="right">16.840808</td>
</tr>
<tr class="alt">
<td style="width: 250px;" align="left">bm_vm1_block.rb</td>
<td style="width: 100px;" align="right">21.596147</td>
<td style="width: 100px;" align="right">20.841016</td>
</tr>
<tr>
<td style="width: 250px;" align="left">bm_vm1_const.rb</td>
<td style="width: 100px;" align="right">15.186479</td>
<td style="width: 100px;" align="right">5.147345</td>
</tr>
<tr class="alt">
<td style="width: 250px;" align="left">bm_vm1_ensure.rb</td>
<td style="width: 100px;" align="right">14.523337</td>
<td style="width: 100px;" align="right">2.636796</td>
</tr>
<tr>
<td style="width: 250px;" align="left">bm_vm1_length.rb</td>
<td style="width: 100px;" align="right">18.094924</td>
<td style="width: 100px;" align="right">5.00994</td>
</tr>
<tr class="alt">
<td style="width: 250px;" align="left">bm_vm1_rescue.rb</td>
<td style="width: 100px;" align="right">11.291826</td>
<td style="width: 100px;" align="right">2.02582</td>
</tr>
<tr>
<td style="width: 250px;" align="left">bm_vm1_simplereturn.rb</td>
<td style="width: 100px;" align="right">21.030805</td>
<td style="width: 100px;" align="right">5.55093</td>
</tr>
<tr class="alt">
<td style="width: 250px;" align="left">bm_vm1_swap.rb</td>
<td style="width: 100px;" align="right">20.567411</td>
<td style="width: 100px;" align="right">2.703651</td>
</tr>
<tr>
<td style="width: 250px;" align="left">bm_vm2_array.rb</td>
<td style="width: 100px;" align="right">5.013982</td>
<td style="width: 100px;" align="right">3.841375</td>
</tr>
<tr class="alt">
<td style="width: 250px;" align="left">bm_vm2_method.rb</td>
<td style="width: 100px;" align="right">11.07794</td>
<td style="width: 100px;" align="right">2.796914</td>
</tr>
<tr>
<td style="width: 250px;" align="left">bm_vm2_poly_method.rb</td>
<td style="width: 100px;" align="right">15.352027</td>
<td style="width: 100px;" align="right">5.173005</td>
</tr>
<tr class="alt">
<td style="width: 250px;" align="left">bm_vm2_poly_method_ov.rb</td>
<td style="width: 100px;" align="right">3.980024</td>
<td style="width: 100px;" align="right">1.352886</td>
</tr>
<tr>
<td style="width: 250px;" align="left">bm_vm2_proc.rb</td>
<td style="width: 100px;" align="right">5.927936</td>
<td style="width: 100px;" align="right">4.371145</td>
</tr>
<tr class="alt">
<td style="width: 250px;" align="left">bm_vm2_regexp.rb</td>
<td style="width: 100px;" align="right">3.763075</td>
<td style="width: 100px;" align="right">28.006719</td>
</tr>
<tr>
<td style="width: 250px;" align="left">bm_vm2_send.rb</td>
<td style="width: 100px;" align="right">3.868001</td>
<td style="width: 100px;" align="right">1.462143</td>
</tr>
<tr class="alt">
<td style="width: 250px;" align="left">bm_vm2_super.rb</td>
<td style="width: 100px;" align="right">4.582815</td>
<td style="width: 100px;" align="right">1.632422</td>
</tr>
<tr>
<td style="width: 250px;" align="left">bm_vm2_unif1.rb</td>
<td style="width: 100px;" align="right">3.475184</td>
<td style="width: 100px;" align="right">2.325038</td>
</tr>
<tr class="alt">
<td style="width: 250px;" align="left">bm_vm2_zsuper.rb</td>
<td style="width: 100px;" align="right">5.033829</td>
<td style="width: 100px;" align="right">2.503812</td>
</tr>
<tr>
<td style="width: 250px;" align="left">bm_vm3_thread_create_join.rb</td>
<td style="width: 100px;" align="right">0.021605</td>
<td style="width: 100px;" align="right">2.625211</td>
</tr>
</tbody>
</table>
<h4>For the more visual among us</h4>
<p>(click for full size)</p>
<p><a title="YARV microbenchmarks - Rubinius vs MRI" href="http://programblings.com/wp-content/uploads/2008/03/2004_04_01_rubinius_vs_mri.jpg"><img src="http://programblings.com/wp-content/uploads/2008/03/2004_04_01_rubinius_vs_mri.jpg" alt="YARV microbenchmarks - Rubinius vs MRI" width="533" height="331" /></a></p>
<p>So there&#8217;s clearly something there, considering the fact that right now the focus is not really on performance, but rather on implementing features and on correctness.</p>
<p>Of course keep in mind that each one of these benchmark is merely a (contrived) measurement of the performance of a very specific operation, executed a bunch of times. Every real life application will have it&#8217;s own performance characteristics. So do not read too much in the following numbers.</p>
<h1>Leave that horse alone</h1>
<p>I&#8217;ll stop beating this dead horse, now. Once you get past the &#8216;Ruby in Ruby&#8217; part, there&#8217;s still a lot of very interesting aspects to the Rubinius project, both technical and non-technical.</p>
<p><a href="feed://http//programblings.com/feed/">Stay tuned</a> for the next installments, in which I&#8217;ll cover some of these other aspects: specs for Ruby, in what ways Rubinius is friendly, enabling new use cases for Ruby, threading, replacing C and how Rubinius might eventually help Rails deployment.</p>
<p><a href="feed://http//programblings.com/feed/"></a>Until then, here are few of the ways you can get more information about Rubinius:</p>
<ul>
<li><a href="http://mwrc2008.confreaks.com/01phoenix.html">The most recent Rubinius presentation</a> of Rubinius at Mountain West RubyConf, which I haven&#8217;t even checked yet.</li>
<li><a href="http://rubyconf2007.confreaks.com/d2t1p3_rubinius.html">The previous presentation</a>, at RubyConf 2007, one of the sources of information for this post.</li>
<li><a href="http://blog.fallingsnow.net/">Evan&#8217;s blog</a>, Rubinius&#8217; original creator and project leader.</li>
<li><a href="http://betterruby.wordpress.com/">Adam Gardiner&#8217;s blog</a>, one of the committers to Rubinius, who recently started explaining the internals of Rubinius (way more technical than this article).</li>
<li>The <a href="http://rubini.us/">Rubinius website</a>, of course.</li>
<li>To keep the pulse of the project, you can of course hang out on #rubinius on irc.freenode.net. If however you want to catch up on what you may have missed, <a href="http://www.donttreadonme.co.uk/rubinius-irc/">the conversations are archived online</a>.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://programblings.com/2008/04/01/rubinius-for-the-layman-part-1-rubies-all-the-way-down/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>A new home for Programblings</title>
		<link>http://programblings.com/2008/03/01/a-new-home-for-programblings/</link>
		<comments>http://programblings.com/2008/03/01/a-new-home-for-programblings/#comments</comments>
		<pubDate>Sun, 02 Mar 2008 01:41:47 +0000</pubDate>
		<dc:creator>Mathieu Martin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://programblings.com/2008/03/01/a-new-home-for-programblings/</guid>
		<description><![CDATA[For a while now I have wanted a bit more control than wordpress.com could offer me. Now has come the time to make the move.
Be sure to subscribe to the new feed.
The main reason why I make the move now is of course to begin the dogfooding process with Defensio.
I&#8217;m not going to bore you <a href='http://programblings.com/2008/03/01/a-new-home-for-programblings/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>For a while now I have wanted a bit more control than wordpress.com could offer me. Now has come the time to make the move.</p>
<p>Be sure to subscribe to <a href="http://feeds.feedburner.com/Programblings">the new feed</a>.</p>
<p>The main reason why I make the move now is of course to begin the dogfooding process with <a href="http://defensio.com/">Defensio</a>.</p>
<p>I&#8217;m not going to bore you with a long post about moving a blog. Sorry for the inconvenience :-)</p>
]]></content:encoded>
			<wfw:commentRss>http://programblings.com/2008/03/01/a-new-home-for-programblings/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Do not learn Ruby</title>
		<link>http://programblings.com/2008/02/20/do-not-learn-ruby/</link>
		<comments>http://programblings.com/2008/02/20/do-not-learn-ruby/#comments</comments>
		<pubDate>Thu, 21 Feb 2008 02:44:26 +0000</pubDate>
		<dc:creator>Mathieu Martin</dc:creator>
				<category><![CDATA[garbage out]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://programblings.com/?p=19</guid>
		<description><![CDATA[Ruby will get under your skin. You will miss its features and quirks when you&#8217;re not using it. You might even find other languages insufferable, once you get comfortable with Ruby.
After you&#8217;ve started using Ruby, there&#8217;s a significant chance you&#8217;ll start loathing whatever code base you currently have to work on. Especially if it&#8217;s a <a href='http://programblings.com/2008/02/20/do-not-learn-ruby/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>Ruby will get under your skin. You will miss its features and quirks when you&#8217;re not using it. You might even find other languages insufferable, once you get comfortable with Ruby.</p>
<p>After you&#8217;ve started using Ruby, there&#8217;s a significant chance you&#8217;ll start loathing whatever code base you currently have to work on. Especially if it&#8217;s a statically compiled language. A code base you used to think was ok, except for its <a href="http://en.wikipedia.org/wiki/Euphemism">few</a> quirks.</p>
<p>After a while of perusing the different Ruby-related blogs, you&#8217;ll have heard other Rubyists speak of their work with words like <em>beauty</em>, <em>productivity</em>, <em>expressiveness</em>, <em>conciseness</em>, <em>fun</em> and you&#8217;ll realize just how far your current language is taking you from all of these words.</p>
<p><strong>Y</strong>ou&#8217;ll see</p>
<pre>Dictionary&lt;string, string&gt; someDic = new Dictionary&lt;string, string&gt;();</pre>
<p>And dream of</p>
<pre>some_dic = {}</pre>
<p><strong>Y</strong>ou&#8217;ll see multiple declarations for the same method, trying to emulate optional parameters and think of Ruby&#8217;s symbols and options hashes, where such a simple method as:</p>
<pre>
def method_with_options(options = {})
  encoding = options[:encoding] || 'utf-8'
  puts('Other option detected') if options[:other_option]
  #...
end</pre>
<p>Enables all of the following uses</p>
<pre>method_with_options :encoding =&gt; 'utf-16', :other_option =&gt; true
method_with_options :encoding =&gt; 'utf-16'
method_with_options :other_option =&gt; true
method_with_options</pre>
<p><strong>Y</strong>ou&#8217;ll hear about metaprogramming and the complex syntax or frameworks that can bend Java, C# or C++ to allow a programmer to achieve what he seeks.</p>
<p>In the back of your head, you&#8217;ll think of the insane flexibility allowed by</p>
<p>- simple Ruby syntax for method chaining or redefinition;</p>
<p>- dynamic class definition, that lets you add methods to any existing class, even Ruby&#8217;s core classes;</p>
<p>- duck typing, where objects of any type can be passed to a method, as long as it responds to the expected method calls in a reasonable fashion;</p>
<p>and oh so many other Ruby niceties.</p>
<p><strong>Y</strong>ou&#8217;ll encounter twisted method definitions such as</p>
<p><code>bool SomeMethod(int param1, ref SomeClass someClass, out SomeEnum resultType, out string result)</code></p>
<p>and think of Ruby&#8217;s multiple returns that allows you to clearly define what&#8217;s a return value and what&#8217;s a parameter:</p>
<p><code>success, resultType, result = some_method(param1, someClass)</code></p>
<p><strong>Y</strong>ou&#8217;ll delve into huge, puzzling class hierarchies that struggle just to use the right abstraction level for class names&#8230; You&#8217;ll eventually realize that the whole hierarchy was simply there to share a few methods among loosely similar classes.</p>
<p>Then you&#8217;ll really get irritated at all the <a href="http://weblog.raganwald.com/2006/12/economizing-can-be-penny-wise-and.html">accidental complexity</a> that could have been avoided by simply using mixins, where you define a common method and then include it in any appropriate class. And all of this without ever puzzling over strange abstract names for classes that happen to sit between 2 clear-cut levels of abstraction.</p>
<p><strong>Y</strong>ou&#8217;ll want to explore a new part of the .Net API by playing with it. You&#8217;ll create a dummy project in some random directory, find a name for it, include the proper parts of the API in the generic main class created by default and finally start playing with the construct of interest.</p>
<p>All this time you&#8217;ll be thinking of IRB, the Ruby interactive console. It not only allows you to play with an existing API with absolutely no fuss, but thanks to Ruby&#8217;s flexibility, you can even define classes in the console and then play with them!</p>
<p>But then you&#8217;ll think &#8220;Oh yeah, IRB is in fact so flexible that I can use if <a href="http://tryruby.hobix.com/">from a frickin&#8217; web page</a> (with a tutorial)!&#8221; And you&#8217;ll go play there for a couple minutes (when no one&#8217;s looking), just to keep you sane for a couple more hours. Until the C++ / C# / Java drudgery is over for the day.</p>
<p>You&#8217;ve been warned. If you learn Ruby, you&#8217;ll start thinking it&#8217;s impossible for you to keep using the technology you&#8217;re currently using at work. If you&#8217;re patient you&#8217;ll try to introduce it there gently (and most likely get frustrated at the time it takes). If you&#8217;re not so patient, you&#8217;ll just end up changing job.</p>
<p>Next monday I&#8217;m joining the great team at <a href="http://karabunga.com/">Karabunga</a> to work on <a href="http://defensio.com/">Defensio</a>. I&#8217;ll be doing Ruby and a bit of Rails. Liberation is coming :-)</p>
]]></content:encoded>
			<wfw:commentRss>http://programblings.com/2008/02/20/do-not-learn-ruby/feed/</wfw:commentRss>
		<slash:comments>53</slash:comments>
		</item>
		<item>
		<title>An easy way to make your code more testable</title>
		<link>http://programblings.com/2007/12/13/an-easy-way-to-make-your-code-more-testable/</link>
		<comments>http://programblings.com/2007/12/13/an-easy-way-to-make-your-code-more-testable/#comments</comments>
		<pubDate>Thu, 13 Dec 2007 12:39:48 +0000</pubDate>
		<dc:creator>Mathieu Martin</dc:creator>
				<category><![CDATA[garbage out]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[24]]></category>

		<guid isPermaLink="false">http://programblings.com/?p=30</guid>
		<description><![CDATA[James Golick wrote a very good article about testing a while ago. In it he dissects (and refutes) the too often heard arguments where people say they don&#8217;t write automated tests because they don&#8217;t have the time.
In the comments, some people concluded that yes, they should try to write more tests, but didn&#8217;t know where <a href='http://programblings.com/2007/12/13/an-easy-way-to-make-your-code-more-testable/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>James Golick wrote a <a href="http://jamesgolick.com/2007/8/28/we-dont-write-tests-there-just-isnt-time-for-luxuries">very good article about testing</a> a while ago. In it he dissects (and refutes) the too often heard arguments where people say they don&#8217;t write automated tests because they don&#8217;t have the time.</p>
<p>In the comments, some people concluded that yes, they should try to write more tests, but didn&#8217;t know where to start. In this post I won&#8217;t suggest frameworks, or specific tutorials. I&#8217;d just like to give one very first step that will help you write code that is easier to test. You&#8217;ll benefit from it even if you don&#8217;t use a testing framework yet.</p>
<p>As the title suggests, what I&#8217;m suggesting is pretty simple. <em>Write side effects free methods/functions</em>. Simple isn&#8217;t it? The rest of this article is just about explaining my point. So if the light bulb went off already, you can stop reading now.</p>
<p>I&#8217;m kidding, of course! So let&#8217;s not take anything for granted, instead let&#8217;s make sure we&#8217;re on the same page and define &#8220;side effect free&#8221;. It means that a function (substitute with &#8220;method&#8221; if you like) receives parameters, spits out a result and has not touched anything outside of it. There are two key parts to this definition:</p>
<ol>
<li> The function does not depend on anything else than it&#8217;s parameters: it does not expect a variable to be set outside of it to work properly (at the object, class or global level).</li>
<li>It does not modify anything. Its result can be entirely observed either from the return value or from the exception thrown.</li>
</ol>
<p>Of course you often have to modify the state of the application as a result of a computation. What I&#8217;m suggesting is not a substitute for that. What I&#8217;m suggesting is simply to put the juicy bits of your computation in a side effect free function. This part will be trivial to test, but you&#8217;ll still have the code that uses this function. That other part, which modifies the state of the app will need unit tests or other higher level testing.</p>
<p>Trivial examples of side effect free functions can be found in any good math library supplied with a language. Of course no modern language expects you to set a global variable in order to compute a square root. Those who want to follow the Ruby examples can do so <a href="http://tryruby.hobix.com/">on Try Ruby</a> (fear not, you&#8217;ll be able to follow along even if you don&#8217;t know any Ruby).</p>
<pre>Math.sqrt(4)
  =&gt; 2.0</pre>
<p>And</p>
<pre>Math.sqrt(-1)
Errno::EDOM: Numerical argument out of domain - sqrt
  from (irb):6:in `sqrt'
  from (irb):6</pre>
<p>So there we have it. The result of squirt is observed either from the return value or from the exception thrown. We don&#8217;t expect any state to have been modified anywhere else in the application. I&#8217;ll present a less trivial example in a bit, but first let me just say that the direct consequence of writing this kind of code is that you can test it trivially, whatever your technique of choice.</p>
<ul>
<li>If you&#8217;re in your debugger or in your interactive console, you can call it as many times as you want, with different parameters and check out if its behavior is what you expect.</li>
<li>If you use unit tests, you can code the interesting scenarios and verify their expected outcome, only in a repeatable manner.</li>
</ul>
<p>Now since we all have a Math library of some sort in our language of choice, let&#8217;s look at another example: analyzing the parameters that will dictate the execution of your program. This is valid for configuration files with a bit more work, but let&#8217;s keep the example simple and just analyze command-line parameters.</p>
<p>Most languages provide us with some kind of array of parameters when entering our main function. The common way of dealing with them is to slap a big if or switch statement somewhere at the beginning of your program, which sets the state of the application accordingly, before actually starting to work on the application&#8217;s main task.</p>
<p>A side effect free approach would be to split the process in two parts:</p>
<ol>
<li>parse the parameters</li>
<li>set the state / do some work</li>
</ol>
<p>For example we could define a function that accepts an array and returns a hash (a Dictionary for .Net folks, a Map for Java folks) of the execution parameters:</p>
<pre>{
  'arg1' =&gt; 'val1',
  'arg2' =&gt; 'val2'
}</pre>
<p>So let&#8217;s say we start with the following method to analyze our arguments :</p>
<pre>def analyze_args(arg_list)
  parsed_args = {}
  #We check that each argument is in the form 'arg=value'
  arg_list.each { |arg|
    key, value = arg.split '='
    if (key.nil? || value.nil?)
      raise "Some arguments are not in the 'arg=value' format"
    end
    parsed_args[key] = value
  }
  return parsed_args
end</pre>
<p>Now we can trivially test the parsing of the command-line params:</p>
<p><code>analyze_args(["mom"])</code></p>
<pre>RuntimeError: Some arguments are not in the 'arg=value' format
  from (irb):23:in `analyze_args'
  from (irb):20:in `each'
  from (irb):20:in `analyze_args'
  from (irb):29
  from :0</pre>
<pre>analyze_args(["mom=food"])
  =&gt; {"mom"=&gt;"food"}
analyze_args(["mom=food", "dad=car"])
  =&gt; {"mom"=&gt;"food", "dad"=&gt;"car"}</pre>
<p>Now that this part is taken care of, I can test it with whatever input I want, trivially.</p>
<p>To reiterate, in order to make your code easier to test, just extract the juicy bits of your program in side effect free functions and keep them apart from the rest of your program, which in turn makes sense of the result. At least the side effect free parts will be trivial to test.</p>
<p>This is just the beginning of the testability and automated tests journey, however. Of course you still have the rest of the program to test, preferably in an automated fashion.</p>
]]></content:encoded>
			<wfw:commentRss>http://programblings.com/2007/12/13/an-easy-way-to-make-your-code-more-testable/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>Culture shock</title>
		<link>http://programblings.com/2007/11/16/culture-shock/</link>
		<comments>http://programblings.com/2007/11/16/culture-shock/#comments</comments>
		<pubDate>Fri, 16 Nov 2007 05:32:15 +0000</pubDate>
		<dc:creator>Mathieu Martin</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://programblings.com/?p=29</guid>
		<description><![CDATA[I had a bit of a culture shock a couple of days ago. I saw a video of the visual designer for IronRuby, named SapphireSteel. The tool looks very nice and polished.
Something unsettled me, however, when I saw it. It has nothing to do with the team or what the narrator says. In the demo, <a href='http://programblings.com/2007/11/16/culture-shock/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>I had a bit of a culture shock a couple of days ago. I saw a video of <a href="http://www.sapphiresteel.com/IronRuby-Visual-Designer">the visual designer for IronRuby</a>, named SapphireSteel. The tool looks very nice and polished.</p>
<p>Something unsettled me, however, when I saw it. It has nothing to do with the team or what the narrator says. In the demo, he shows us a couple of features of the designer, and inevitably we end up seeing snippets of code. That&#8217;s when the culture shock, uhh, shocked me.</p>
<p>I&#8217;ve seen plenty of verbose code in my time. I even work in C# right now, which I find errs on the side of verbosity.  So I&#8217;m used to seeing verbose code, and I&#8217;m certainly used to see WinForms code.</p>
<p>But seeing this WinForms code in Ruby felt very weird.</p>
<p><a href="http://webmat.files.wordpress.com/2007/11/winformsinrubyisstillwinforms.png" title="WinForms in Ruby is Still WinForms"></a></p>
<p align="center"><img src="http://programblings.com/wp-content/uploads/2008/03/winformsinrubyisstillwinforms.png" alt="An example of WinForms code in Ruby" /><em>.</em></p>
<p>C# colleagues might tell me that this code just satisfies what the API wants to hear, in the way it wants to hear it. But I&#8217;m getting used really fast of the Ruby way of doing things. Which consists &#8220;sane defaults&#8221; for a start, and using DSLs to solve complex problems in a declarative manner rather than in an imperative manner.</p>
<p>WinForms development with Ruby screams for a Rubyish wrapper. Anybody up for that? If it can be done for Java&#8217;s Swing (<a href="http://ihate.rubyforge.org/profligacy/">with Profligacy, the Swing reducer</a>), it can certainly be done for WinForms.</p>
<p>For my part, however, I&#8217;d be much more interested in <a href="http://en.wikipedia.org/wiki/Xaml">exploring XAML</a> with Ruby, but that&#8217;s another story.</p>
]]></content:encoded>
			<wfw:commentRss>http://programblings.com/2007/11/16/culture-shock/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Follow-up on my presentation on JRuby</title>
		<link>http://programblings.com/2007/11/08/follow-up-on-my-presentation-on-jruby/</link>
		<comments>http://programblings.com/2007/11/08/follow-up-on-my-presentation-on-jruby/#comments</comments>
		<pubDate>Thu, 08 Nov 2007 13:27:52 +0000</pubDate>
		<dc:creator>Mathieu Martin</dc:creator>
				<category><![CDATA[garbage out]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://programblings.com/?p=27</guid>
		<description><![CDATA[ I&#8217;m very pleased! My presentation went very well, the audience was very receptive. We had some great questions and interactions during the talk. Great fun! Here we can see my neck-twisting setup and me, gesticulating vehemently.
So if you want to check the presentation again for some reason, here it is: JRuby &#8211; On and <a href='http://programblings.com/2007/11/08/follow-up-on-my-presentation-on-jruby/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://farm3.static.flickr.com/2006/1904896595_41912476da.jpg"><img src="http://farm3.static.flickr.com/2006/1904896595_41912476da.jpg?v=0" alt="Me, gesticulating vehemently" align="right" height="300" width="400" /></a> I&#8217;m very pleased! <a href="http://www.montrealonrails.com/2007/10/16/upcoming-mor4-tuesday-november-6th/">My presentation</a> went very well, the audience was very receptive. We had some great questions and interactions during the talk. Great fun! Here we can see my neck-twisting setup and me, gesticulating vehemently.</p>
<p>So if you want to check the presentation again for some reason, here it is: <a href="http://webmat.files.wordpress.com/2007/11/jroaor.pdf" title="JRuby - On and off Rails"></a><a href="http://programblings.com/wp-content/uploads/2008/03/jroaor.pdf" title="jroaor.pdf">JRuby &#8211; On and off Rails</a>.</p>
<p>Also available is <a href="http://spreadsheets.google.com/pub?key=ps7Wjwj1ZaG0mmOXH5bRtTA">my take</a> on <a href="http://blog.nicksieger.com/articles/2007/10/25/jruby-on-rails-fast-enough">Nick Sieger&#8217;s, Rails performance numbers</a>.</p>
<p>I suppose some of you might be interested in my other references, as well. So here&#8217;s a recap of the links I mentioned at the end of the presentation.</p>
<h3>The people</h3>
<p><a href="http://headius.blogspot.com">Charles Oliver Nutter</a> works for Sun, he&#8217;s the main driving force behind the compiler, among other things. If you&#8217;re interested to hear about easy bugs to fix in JRuby, he posts a list once in a while.</p>
<p><a href="http://ola-bini.blogspot.com">Ola Bini</a> works for Thoughtworks and he also works on JRuby full time. His recent feats include speeding up the regex implementation of JRuby.<a href="http://ola-bini.blogspot.com"><br />
</a></p>
<p><a href="http://blog.nicksieger.com/">Nick Sieger</a> also works for Sun, but his job is on the user end of JRuby. He contributes to JRuby as well, however. And by the way, <a href="http://blog.nicksieger.com/articles/2007/10/06/railsconf-europe-hydra">check out the follow-up</a> on the talk he and his team gave at RailsConf. The article discusses implementing some parts of the model of his application as RESTful services, thus giving them more flexibility for scaling. The WAR file deployment approach is mentioned as a tool that helps manage all those independent Rails instances.</p>
<p>Last but not least, <a href="http://www.bloglines.com/blog/ThomasEEnebo">Thomas Enebo</a>, also hired by Sun to work full time on JRuby. During the presentation I mentioned that his blog was less technical than the other guys. Turns out this feeling was largely based on the activity on his blog before summer. Recently he posted some <a href="http://www.bloglines.com/blog/ThomasEEnebo?id=40">very</a> <a href="http://www.bloglines.com/blog/ThomasEEnebo?id=38">interesting</a> <a href="http://www.bloglines.com/blog/ThomasEEnebo?id=34">posts</a> on JRuby and <a href="http://www.bloglines.com/blog/ThomasEEnebo?id=31">Ruby</a>. Looks like I have some catching up to do :-)</p>
<h3>The project</h3>
<p>The official JRuby site is <a href="http://jruby.codehaus.org">hosted on codehaus</a>. While <a href="http://headius.com/jrubywiki">the official wiki</a> is on Charles Nutter&#8217;s personal site for now.</p>
<h3>JRuby on Rails</h3>
<p>For 2 good tutorials that take you through the steps of trying out JRuby, go see on ADS&#8217; blog:</p>
<p><a href="http://rorblog.techcfl.com/2007/06/01/get-jruby-onto-the-rails-on-mac-os-x/">Getting JRuby and Rails running</a>. <a href="http://rorblog.techcfl.com/2007/06/10/deploy-your-first-jruby-on-rails-app-to-glassfish/">Deploying to Glassfish</a>. Theirs posts are pretty detailed, but since things are moving so fast in the JRuby world, some of the details are a bit out of date already :-) In it they use <a href="//rubyforge.org/var/svn/jruby-extras/trunk/rails-integration/plugins/goldspike">Goldspike</a> to generate their WAR archive, just like I did.<br />
As I mentioned however, <a href="http://blog.nicksieger.com/articles/2007/09/04/warbler-a-little-birdie-to-introduce-your-rails-app-to-java">a post by Nick Sieger</a> introduced me to warbler as another very promising replacement to Goldspike. In fact, as Nick describes warbler, I fully expect to try it and stick with it instead of Goldspike. Definitely worth a try.</p>
<p>Check out the <a href="http://weblogs.java.net/blog/arungupta/archive/2007/09/announcing_glas.html">Glassfish gem</a> for a better integration of Glassfish in your Rails workflow. I haven&#8217;t tried it yet, so I can&#8217;t elaborate on it.</p>
<p>The 2 Java web servers I used are:</p>
<p><a href="http://www.mortbay.org/">Jetty</a>, the small, unintrusive yet very scalable web server. I likened it to WEBrick in that it can be used to try out our WAR file with absolutely no fuss. Which is not to say that it can&#8217;t be used in a production setting.</p>
<p><a href="https://glassfish.dev.java.net/">Glassfish</a>, the full-featured server with the admin interface. This is the server that ended up being about as fast as the MRI/Mongrel combination, in the performance comparison.</p>
<p>If you&#8217;re interested in a JRuby/Mongrel setup, the one which ended up being the fastest in the comparison, check out <a href="http://jxh.bingodisk.com/bingo/public/Hackdays/JRuby/">this post*</a>, mentioned by Nick Sieger, and <a href="http://ola-bini.blogspot.com/2007/04/mongrel-in-jruby.html">this post by Ola Bini</a>.</p>
<h3>JRuby off Rails</h3>
<p>For those that were insterested in the non Rails bits as well, I talked about an unintrusive plugin that allows you to create Swing gui apps, I mentioned (and stumbled over the name of) <a href="http://ihate.rubyforge.org/profligacy">Profligacy</a>. It&#8217;s been created by <a href="http://www.zedshaw.com/blog/index.html">Zed Shaw</a>, the creator of Mongrel.</p>
<p>I also talked about using <a href="https://jna.dev.java.net/">JNA</a> to <a href="http://headius.blogspot.com/2007/09/java-native-access-jruby-true-posix.html">reuse existing C extensions</a> for Ruby, which do not have a JRuby equivalent yet.</p>
<h3>I have to stop and go to work now</h3>
<p>Hey, I wanted to make this a short post. Looks like I failed :-) If I forgot something of if you have questions, don&#8217;t hesitate to comment. I&#8217;ll get back to you and update this post, if necessary.</p>
<p>As for me, I might help <a href="http://blog.carlmercier.com/">Carl</a> by checking out whether JRuby could be a good fit for <a href="http://defensio.com/">Defensio</a>. I&#8217;m looking forward to that, I think it&#8217;s a great real world project to dive into JRuby head on. Of course I&#8217;ll report back and contribute, based on my findings.</p>
<p>*Sorry, the JRuby/Mongrel link seems dead as I&#8217;m posting this. I leave the link in case the problem is temporary.</p>
]]></content:encoded>
			<wfw:commentRss>http://programblings.com/2007/11/08/follow-up-on-my-presentation-on-jruby/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Mat mini</title>
		<link>http://programblings.com/2007/11/05/mat-mini/</link>
		<comments>http://programblings.com/2007/11/05/mat-mini/#comments</comments>
		<pubDate>Mon, 05 Nov 2007 12:35:09 +0000</pubDate>
		<dc:creator>Mathieu Martin</dc:creator>
				<category><![CDATA[ruby]]></category>
		<category><![CDATA[3]]></category>

		<guid isPermaLink="false">http://programblings.com/?p=25</guid>
		<description><![CDATA[Good news everyone*!
Tomorrow my presentation at Montreal on Rails is going to be made on my brand new Mac Mini!
In my last post I mentioned I was going to present on an ooooold Win XP laptop, but I decided to make the switch to the Mac world now. Well, one week ago. So fear not, <a href='http://programblings.com/2007/11/05/mat-mini/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>Good news everyone*!</p>
<p>Tomorrow my presentation at <a href="http://www.montrealonrails.com/">Montreal on Rails</a> is going to be made on my brand new Mac Mini!</p>
<p>In my last post I mentioned I was going to present on an ooooold Win XP laptop, but I decided to make the switch to the Mac world now. Well, one week ago. So fear not, I&#8217;m not going to subject our community to a 5 square meters XP/Powerpoint eye bleeding festival.</p>
<p>The Apple world had one little surprise for me, however. Immediately after I bought my Mini I started hearing about the Java 1.6 debacle on Leopard. What? I didn&#8217;t event know OS X didn&#8217;t come with the standard Java distribution! And here I am, about to make a presentation on JRuby on a Mac :-) Note to self: never switch to a completely new OS (to me) one week before a presentation again.</p>
<p>This won&#8217;t affect the presentation, however, since everything works perfectly fine on Java 1.5, preinstalled on Leopard. And isn&#8217;t it reasonable to <a href="http://stuffthathappens.com/blog/2007/10/28/os-x-java-definitive-timeline/">expect Apple to release Java 1.6 shortly anyway?</a> So for those I&#8217;ll convince to give JRuby a try, all hope is not lost. Moreover, for the Rails community I think the Java 1.6 story is pretty much a non-issue. Your test and production servers are running on Linux, right?</p>
<p>So with that out of the way, there&#8217;s only one bump left in the road. As our host <a href="http://siliconisland.ca/">Fred</a> pointed out to me, my mini has only one video out. Doh! I didn&#8217;t find any VGA or DVI splitter, so I&#8217;ll deal with it. This will be a bit of a pain in the neck, but hopefully just for me :-) Let&#8217;s see how the live coding part goes!</p>
<p>* In my best <a href="http://en.wikipedia.org/wiki/Hubert_J._Farnsworth">Professor Farnsworth</a> voice (from Futurama)</p>
]]></content:encoded>
			<wfw:commentRss>http://programblings.com/2007/11/05/mat-mini/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>JRuby, not in its setting (or configuring jirb under Windows)</title>
		<link>http://programblings.com/2007/10/18/jruby-not-in-its-setting/</link>
		<comments>http://programblings.com/2007/10/18/jruby-not-in-its-setting/#comments</comments>
		<pubDate>Thu, 18 Oct 2007 05:30:29 +0000</pubDate>
		<dc:creator>Mathieu Martin</dc:creator>
				<category><![CDATA[garbage out]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://programblings.com/?p=24</guid>
		<description><![CDATA[For a good while now, I&#8217;ve been using Ubuntu on my main home machine. Working with Ruby and JRuby on Linux is a charm.
Tonight, as I tried to set myself up to work with JRuby on Windows*, I bumped into an annoying problem. When I tried to configure jirb, the JRuby version of IRB, it <a href='http://programblings.com/2007/10/18/jruby-not-in-its-setting/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>For a good while now, I&#8217;ve been using Ubuntu on my main home machine. Working with Ruby and JRuby on Linux is a charm.</p>
<p>Tonight, as I tried to set myself up to work with JRuby on Windows*, I bumped into an annoying problem. When I tried to configure jirb, the JRuby version of IRB, it didn&#8217;t always seem to find the <code>.irbrc</code> config file in my home directory. I looked a bit on the &#8216;net and found nothing that helped me solve my problem. I&#8217;ve worked out a fix, you can follow along in this wonderful adventure.</p>
<p>So to configure irb, I create the <code>.irbrc</code> file in my home directory.</p>
<p><code>C:\Documents and Settings\Mat\.irbrc</code></p>
<p>Note: Windows will yell at you if you try to make a new file starting with a &#8220;.&#8221; in windows explorer. Just use <a href="http://www.flos-freeware.ch/notepad2.html">any</a> <a href="http://notepad-plus.sourceforge.net">good</a> <a href="http://www.textpad.com/">text</a> <a href="http://www.e-texteditor.com/">editor</a> to create it directly.</p>
<p>In it I put some configs for auto-completion and auto indent, as suggested on the <a href="http://wiki.rubyonrails.org/rails/pages/TipsAndTricks">Tips and Tricks</a> page on the Rails wiki:</p>
<p><code>IRB.conf[:AUTO_INDENT] = true<br />
IRB.conf[:USE_READLINE] = true<br />
require 'irb/completion'<br />
puts "Yay! Completion's loaded!" #Uhh, that's my special debugging code :-)<br />
</code></p>
<p>Now I fire up a console and start the interactive Ruby shell with</p>
<p><code>C:\Documents and Settings\Mat&gt;jirb<br />
Yay! Completion's loaded!<br />
irb(main):001:0&gt;</code></p>
<p>Hmmm, it works. What am I yelling about? :-) Let&#8217;s say we fire it up in an actual project directory instead.</p>
<p><code>C:\projects\an_actual_project&gt;jirb<br />
irb(main):001:0&gt;</code></p>
<p>Oops! My &#8220;special&#8221; debugging code isn&#8217;t executing now :-)</p>
<p>If you care to see what&#8217;s the code that hints at how to solve the problem, you can open</p>
<p>&#8230;\jruby-1.0.1\lib\ruby\1.8\irb\init.rb</p>
<p>Or check it out a snippet of IRB.rc_file_generators <a href="http://pastie.caboo.se/108382">online</a>.</p>
<p>As we can see, if the HOME environment variable is set, the method looks for .irbrc in the directory, otherwise it looks for it in the pwd (present working directory).</p>
<p>Nice! That explains why it works in my home and not elsewhere :-)</p>
<p>So now I just have to set a HOME variable and I&#8217;m all set:</p>
<p><img src="http://programblings.com/wp-content/uploads/2008/03/home.png" alt="home.png" /></p>
<p>Now after restarting my console (to have the updated environment variables):</p>
<p><code>C:\projects\an_actual_project&gt;jirb<br />
Yay! Completion's loaded!<br />
irb(main):001:0&gt;</code></p>
<p>Note that even though Windows variables are not case sensitive, <u>you must name your HOME variable in capital letters</u>. Ruby expects the ENV hash to contain the HOME variable in caps.</p>
<p>* Q: Why would I want to set this up on Windows, if I&#8217;ve got a perfectly good Linux setup at home?</p>
<p>A: I&#8217;ll be giving a talk about JRuby at <a href="http://www.montrealonrails.com/2007/10/16/upcoming-mor4-tuesday-november-6th/">the next Montreal on Rails</a>, and since I haven&#8217;t really needed a laptop in at least two years, well, I only have 3 years old laptop. This old geezer can run equally old versions of Linux, but I wouldn&#8217;t like my audience to have to suffer the visually challenged distro I currently have on there.</p>
]]></content:encoded>
			<wfw:commentRss>http://programblings.com/2007/10/18/jruby-not-in-its-setting/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Using Windows? Try Powershell!</title>
		<link>http://programblings.com/2007/10/16/using-windows-try-powershell/</link>
		<comments>http://programblings.com/2007/10/16/using-windows-try-powershell/#comments</comments>
		<pubDate>Tue, 16 Oct 2007 12:19:12 +0000</pubDate>
		<dc:creator>Mathieu Martin</dc:creator>
				<category><![CDATA[garbage out]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://programblings.com/?p=22</guid>
		<description><![CDATA[Recently, at work I&#8217;ve had to implement a couple of simple scripts. They were yet again not simple enough to be captured completely in a batch file. For example I needed to have an arbitrary precision and format date/time that I could use in a file name. date /t and time /t weren&#8217;t cutting it.
I <a href='http://programblings.com/2007/10/16/using-windows-try-powershell/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>Recently, at work I&#8217;ve had to implement a couple of simple scripts. They were yet again not simple enough to be captured completely in a batch file. For example I needed to have an arbitrary precision and format date/time that I could use in a file name. <code>date /t</code> and <code>time /t</code> weren&#8217;t cutting it.</p>
<p>I thought about implementing a small command-line tool just to give me the functionality I was missing, but it felt too patchy for my taste, this time. I had to use it on other test machines so I wanted to be able to just copy the script without having to update some executable utilities as well.</p>
<p>Sadly I could not use Ruby because my company doesn&#8217;t use it, and I don&#8217;t want to sneak it in the wrong way. And as I said it was to be used on another machine, so it was not like creating  a personal script on my own machine. In fact it even had to be documented in a manual testing procedure.</p>
<p>So I decided that it was time to try Powershell. I&#8217;ve been hearing about it for quite a while now, and I heard it&#8217;s pretty powerful. Since it&#8217;s the future of Windows console/scripting anyway, I figured nobody sane at a Windows shop would yell at me for introducing this particular technology.</p>
<p>Now that I&#8217;ve been dabbling with it for the past few weeks, my opinion is starting to form and it goes a little bit like this. If you&#8217;re a Windows power user (especially an admin or a developer) and you don&#8217;t know Powershell, you&#8217;re at a disadvantage :-) The &#8220;Power&#8221; in Powershell is very well deserved. If you&#8217;re still flopping along using batch files, you&#8217;re using a weak, error-prone tool where a new, very powerful tool is available. It&#8217;s free and it&#8217;s by Microsoft, so there&#8217;s no reason it wouldn&#8217;t be well received in most Windows shops :-)</p>
<p>I decided to capture my understanding of Powershell in an introductory article. In it I explain some of the basics of the language and introduce you to all that&#8217;s necessary to get started with Powershell. In the reference section at the end I also mention other good sources of information if you want to learn more. Depending on the amount of fiddling around you do while following along, I guess it&#8217;s a 30 minutes to 2h read tops.</p>
<p>So without further ado, <a href="http://webmat.wordpress.com/discover-powershell/">Discover Powershell</a> (it&#8217;s an order!)</p>
]]></content:encoded>
			<wfw:commentRss>http://programblings.com/2007/10/16/using-windows-try-powershell/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Quick idea to get used to blogging</title>
		<link>http://programblings.com/2007/10/06/quick-idea-to-get-used-to-blogging/</link>
		<comments>http://programblings.com/2007/10/06/quick-idea-to-get-used-to-blogging/#comments</comments>
		<pubDate>Sat, 06 Oct 2007 05:14:16 +0000</pubDate>
		<dc:creator>Mathieu Martin</dc:creator>
				<category><![CDATA[garbage out]]></category>
		<category><![CDATA[11]]></category>

		<guid isPermaLink="false">http://programblings.com/?p=18</guid>
		<description><![CDATA[I started this blog sometime in August. However, in order to get used to posting online, I already had a tumblr where I could post stupid stuff that occurs to me, come across, hear about or find at the grocery store, even. I think the absent pressure about content quality helped me get the ball <a href='http://programblings.com/2007/10/06/quick-idea-to-get-used-to-blogging/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>I started this blog sometime in August. However, in order to get used to posting online, I already had a tumblr where I could post <a href="http://webmat.tumblr.com/post/2803592">stupid stuff</a> that <a href="http://webmat.tumblr.com/post/163769">occurs to me</a>, <a href="http://webmat.tumblr.com/post/6075664">come across</a>, <a href="http://webmat.tumblr.com/post/5652795">hear about</a> or <a href="http://webmat.tumblr.com/post/6345668">find at the grocery store</a>, even. I think the absent pressure about <a href="http://webmat.tumblr.com/post/5339466">content quality</a> helped me get the ball rolling.</p>
<p>Tonight I was inspired and even went to the extent of <a href="http://webmat.tumblr.com/post/14423927">expressing myself in video</a> :-)</p>
]]></content:encoded>
			<wfw:commentRss>http://programblings.com/2007/10/06/quick-idea-to-get-used-to-blogging/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Free PDF Rails Book for beginner Rails developers!</title>
		<link>http://programblings.com/2007/10/03/free-pdf-rails-book-for-beginner-rails-developers/</link>
		<comments>http://programblings.com/2007/10/03/free-pdf-rails-book-for-beginner-rails-developers/#comments</comments>
		<pubDate>Wed, 03 Oct 2007 05:38:33 +0000</pubDate>
		<dc:creator>Mathieu Martin</dc:creator>
				<category><![CDATA[garbage in]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[20]]></category>

		<guid isPermaLink="false">http://programblings.com/?p=16</guid>
		<description><![CDATA[As seen on the Rails blog, sitepoint.com is giving away free PDF copies of Patrick Lenz&#8217;s book, Build Your Own RoR Web Apps. The offer is good for 60 days. Well, 59d15h at the time of posting :-)
It involves jumping through a couple of hoops, and the book contains a couple of pages containing ads <a href='http://programblings.com/2007/10/03/free-pdf-rails-book-for-beginner-rails-developers/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://weblog.rubyonrails.com/2007/10/2/free-rails-pdf-book">As seen on the Rails blog</a>, sitepoint.com is giving away free PDF copies of <a href="http://poocs.net">Patrick Lenz</a>&#8217;s book, <a href="http://rails.sitepoint.com">Build Your Own RoR Web Apps</a>. The offer is good for 60 days. Well, 59d15h at the time of posting :-)</p>
<p>It involves jumping through a couple of hoops, and the book contains a couple of pages containing ads about other Sitepoint books. But nothing too bad, at first sight. And it&#8217;s still a free PDF book! So if you know anybody who&#8217;s curious about Rails and might want to try it out, you have until the beginning of December to point him/her to <a href="http://rails.sitepoint.com">rails.sitepoint.com</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://programblings.com/2007/10/03/free-pdf-rails-book-for-beginner-rails-developers/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Montreal on Rails tonight</title>
		<link>http://programblings.com/2007/10/02/montreal-on-rails-tonight/</link>
		<comments>http://programblings.com/2007/10/02/montreal-on-rails-tonight/#comments</comments>
		<pubDate>Tue, 02 Oct 2007 11:08:47 +0000</pubDate>
		<dc:creator>Mathieu Martin</dc:creator>
				<category><![CDATA[garbage in]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[20]]></category>
		<category><![CDATA[21]]></category>

		<guid isPermaLink="false">http://programblings.com/?p=15</guid>
		<description><![CDATA[Tonight is Montreal on Rails #3! I can&#8217;t wait to attend: this will be a nice refreshment from my gruesome C++ tar pit at work, ugh! :-)
The first 2 were very interesting and filled with great people to meet. Tonight promises to be just as great, and as a bonus, we&#8217;re leaving behind the small <a href='http://programblings.com/2007/10/02/montreal-on-rails-tonight/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>Tonight is <a href="http://www.montrealonrails.com/2007/10/01/tomorrow-mor-at-soj/">Montreal on Rails #3</a>! I can&#8217;t wait to attend: this will be a nice refreshment from my gruesome <a href="http://steve-yegge.blogspot.com/2007/02/next-big-language.html">C++ tar pit</a> at work, ugh! :-)</p>
<p>The first 2 were very interesting and filled with great people to meet. Tonight promises to be just as great, and as a bonus, we&#8217;re leaving behind the small McGill University classroom to be welcome instead by <a href="http://siliconisland.ca">Fred</a> and <a href="http://instigatorblog.com">Ben</a> from <a href="http://www.standoutjobs.com/">Standoutjobs</a>. Can&#8217;t wait to see that either!</p>
<p>And great big thanks to <a href="http://www.web1979.com">Mat</a> and <a href="http://blog.carlmercier.com">Carl</a> for organizing this monthly meetup!</p>
]]></content:encoded>
			<wfw:commentRss>http://programblings.com/2007/10/02/montreal-on-rails-tonight/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Podcasts I listen to</title>
		<link>http://programblings.com/2007/09/29/podcasts/</link>
		<comments>http://programblings.com/2007/09/29/podcasts/#comments</comments>
		<pubDate>Sun, 30 Sep 2007 04:50:27 +0000</pubDate>
		<dc:creator>Mathieu Martin</dc:creator>
				<category><![CDATA[garbage in]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[18]]></category>
		<category><![CDATA[23]]></category>
		<category><![CDATA[6]]></category>

		<guid isPermaLink="false">http://programblings.com/?p=14</guid>
		<description><![CDATA[Here&#8217;s the deal. I have to beat writer&#8217;s block. I wrote a first post a while ago, then came the time for a little vacation and haven&#8217;t gotten down to write here again. Well, except for this quickie.
I thought I&#8217;d write a list of the podcasts I listen to. This way I can just point <a href='http://programblings.com/2007/09/29/podcasts/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s the deal. I have to <a href="http://www.instigatorblog.com/beat-writers-block-by-reading-and-commenting-more/2007/08/13/">beat writer&#8217;s block</a>. I wrote a first post a while ago, then came the time for a little vacation and haven&#8217;t gotten down to write here again. Well, except for <a href="http://webmat.wordpress.com/2007/09/25/on-using-c/">this quickie</a>.</p>
<p>I thought I&#8217;d write a list of the podcasts I listen to. This way I can just point people here when they&#8217;re curious. I&#8217;ll put this somewhere else soon, to update it when I discover new stuff, but now I&#8217;m just in brain-dump mode :-)</p>
<p>Those I listen to religiously</p>
<ul>
<li><a href="http://www.linuxactionshow.com">The Linux Action Show!</a> &#8211; Bryan and Chris entertain us with Linux news, the occasional interview, tips on development, system administration, desktop compositing, and So Much More!</li>
<li><a href="http://www.dotnetrocks.com">.Net Rocks</a> &#8211; Carl and Richard meet the cream of the crop in the .Net world. Great podcast to learn about tons of tools and practices related to .Net development and other MS technologies surrounding it. There&#8217;s even good stuff for non .Net developers.</li>
<li><a href="http://hanselminutes.com">Hanselminutes</a> &#8211; Scott Hanselman&#8217;s the ultimate geek. He seems to follow everything in the world of development. He often talks about .Net development, but has a very open mind and covers a broad range of other technologies, including a bit of Ruby on Rails once in a while. He also covers lots of other technology-related topics. He pretty much always manages to keep the podcasts around a no-fuss 30 minutes, hence the name Hanselminutes.</li>
<li><a href="http://www.twit.tv/sn">Security Now</a> &#8211; The ultimate security podcast, with host Leo Laporte and security expert Steve Gibson. All episodes are worth going back to, since the formula is about the theory behind concepts of security as well as security tools, rather than being a news-centric podcast.</li>
<li><a href="http://www.twit.tv/mbw">Macbreak Weekly</a> &#8211; Definitely a news-centric podcast, very entertaining crew that transmit their passion for the Mac (and the iPhone) very well. The discussion often revolves around digital media as well, with very interesting insights. Oh, and Merlin Mann is often one of the cohosts. Very funny guy :-)</li>
<li><a href="http://podcast.rubyonrails.org">The Ruby on Rails podcast</a> &#8211; The podcast extraordinaire if you&#8217;re interested in Ruby on Rails. Interviews with the big names in the Rails community. Lots of talk about different tools that can aid you in your quest to create the ultimate Rails app. The summer has unfortunately brought few new shows, but one came out recently. Let&#8217;s hope the pace picks up again, I miss the RoR podcast :-)</li>
<li><a href="http://www.twit.tv/FLOSS">FLOSS Weekly</a> &#8211; Very promising podcast about Free, Libre and Open Source Software (not about dental floss). Some very big names have been interviewed on the show (Guido van Rossum, &#8220;Maddog&#8221; Hall, Jeremy Allison, Randall Schwartz&#8230;) The first host, Chris, has a very busy schedule and the pace has really slowed down for a while. But there has been interest by Mr Shwartz and Allison to host the show once in a while as well. I can&#8217;t wait to see that happen (the most recent show is hosted by Schwartz, actually).</li>
<li><a href="http://www.yousuckatwebdesign.com">You Suck at Web Design</a> &#8211; Short, funny podcast by Matthew D. Jordan about being a freelance web designer (and the journey to get there). Twisted humor and cringe-inducing stories await you here.</li>
</ul>
<p>Those I listen to occasionally</p>
<ul>
<li><a href="http://www.twit.tv/natn">net@night</a> &#8211; <a href="http://ambermac.typepad.com">Ambermac</a>, the ultimate web geek speaks with Leo about what&#8217;s going on the internet. Interviews with web entrepreneurs. Shows recorded live on talkshoe.com (can be good or not).</li>
<li><a href="http://www.twit.tv/ww">Windows Weekly</a> &#8211; Paul Thurrot speaks with Leo about what&#8217;s going on in the world of Windows and Microsoft in general. The subject may seem dry, but the hosts definitely make up for it. A plus for anyone working in IT with lots of Windows machines. Thurrot knows the Windows world inside out, but is very balanced: he uses (and loves) his Mac and uses Ubuntu as well, so you can count on his opinion to always be fair.</li>
<li><a href="http://www.twit.tv/twit"> This Week in Tech</a> &#8211; News-centric podcast about the world of technology in general. Very interesting hosts, including once in a while Merlin Mann, as well as John Dvorak.org/blog (don&#8217;t ask :).</li>
<li><a href="http://www.penny-arcade.com">Penny Arcade Podcast</a> &#8211; Every once in a while, Gabe and Tycho take us through the creative process of creating the day&#8217;s comic strip.</li>
</ul>
<p>&lt;/braindump&gt;</p>
<p>Huh, well! I appear to be beating my writer&#8217;s block little by little :-)</p>
<p>Let me know if you&#8217;ve discovered something interesting here or if you&#8217;d like to share the podcasts you listen too once in a while.</p>
]]></content:encoded>
			<wfw:commentRss>http://programblings.com/2007/09/29/podcasts/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>On using C++</title>
		<link>http://programblings.com/2007/09/25/on-using-c/</link>
		<comments>http://programblings.com/2007/09/25/on-using-c/#comments</comments>
		<pubDate>Wed, 26 Sep 2007 04:10:58 +0000</pubDate>
		<dc:creator>Mathieu Martin</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[12]]></category>
		<category><![CDATA[14]]></category>
		<category><![CDATA[6]]></category>

		<guid isPermaLink="false">http://programblings.com/?p=13</guid>
		<description><![CDATA[Sorry for this content-free post, but this is just too good:
When your hammer is C++, everything begins to look like a thumb.
This especially strikes a chord, since I&#8217;m currently working on something in C++ at work. Ugh!
]]></description>
			<content:encoded><![CDATA[<p>Sorry for this content-free post, but this is just too good:</p>
<blockquote><p><a href="http://groups.google.com/group/comp.lang.lisp/msg/5bb9a3a5f81532eb"><font face="Courier, Monospaced">When your hammer is C++, everything begins to look like a thumb.</font></a></p></blockquote>
<p>This especially strikes a chord, since I&#8217;m currently working on something in C++ at work. Ugh!</p>
]]></content:encoded>
			<wfw:commentRss>http://programblings.com/2007/09/25/on-using-c/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>An epiphany about Functional Programming and Lazy Evaluation</title>
		<link>http://programblings.com/2007/08/12/an-epiphany-about-functional-programming-and-lazy-evaluation/</link>
		<comments>http://programblings.com/2007/08/12/an-epiphany-about-functional-programming-and-lazy-evaluation/#comments</comments>
		<pubDate>Sun, 12 Aug 2007 22:00:29 +0000</pubDate>
		<dc:creator>Mathieu Martin</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[13]]></category>
		<category><![CDATA[17]]></category>

		<guid isPermaLink="false">http://programblings.com/?p=12</guid>
		<description><![CDATA[(Update: be sure to read the comments, as the language used in my article was not entirely exact, in functional programming legalese ;-) Many readers helped to clarify things a bit.)
I had a mini-epiphany recently. Altough I haven&#8217;t had the chance yet to program with a functional programming language, it&#8217;s a subject I&#8217;ve had my <a href='http://programblings.com/2007/08/12/an-epiphany-about-functional-programming-and-lazy-evaluation/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>(Update: be sure to read the comments, as the language used in my article was not entirely exact, in functional programming legalese ;-) Many readers helped to clarify things a bit.)</p>
<p>I had a mini-epiphany recently. Altough I haven&#8217;t had the chance yet to program with a functional programming language, it&#8217;s a subject I&#8217;ve had my eye on for a while. My ear perks up when I hear about Erlang, Haskell, F# or Scala, 4 functional programming languages.</p>
<p>Recently I&#8217;ve been dipping in the intricacies of memory management, at work,  in .Net. This was in the context of the Dispose pattern (I have a post in the making about the subject).  Both subjects are not directly related, but I found a parallel that might help to explain lazy evaluation to programmers used to more traditional programming languages.</p>
<p>I won&#8217;t go in depth in the subject or define the concepts precisely here. I might however revisit what follows when I&#8217;ve had time to actually get more experience with an FP language. So here was my revelation:</p>
<blockquote><p>When specifying a computation in a programming language, lazy evaluation is to the detailed, manual sequencing of operations what garbage collection and automatic memory management is to the detailed, manual management of memory.</p></blockquote>
<p>In other words, with advanced virtual machines such as Java&#8217;s or .Net&#8217;s, by allowing the VM to manage the memory, we more or less get the advantage of having world-class computer scientists optimize the management of the memory we use. The programmer declares what he needs in term of memory, instead of specifying precisely how he needs it (stack vs heap, who&#8217;s responsible of freeing the memory, etc.) The amount of control over the precise performance is lessened to a certain extent, but the resulting performance gains can often be quite stunning. For example, I read recently that Java&#8217;s allocation of memory on the heap requires around 10 processor operations instead of 60 to 100, for the best C++ compilers. See <a href="http://www-128.ibm.com/developerworks/java/library/j-jtp09275.html?ca=dgr-jw22JavaUrbanLegends">Brian Goetz&#8217; excellent article on IBM&#8217;s website</a>.</p>
<p>In the same manner, with a functional programming language&#8217;s lazy evaluation, optimizations can be made without the programmer needing to state them explicitly. The interpreter can decide when to execute the code, namely if and when its outcome is needed, and not before that.</p>
<p>Since the precise order of execution is not guaranteed, the bits of computing specified by the programmer in an FP can be optimized in other ways, too. For example, if the VM sees that a given instructions in the code is not dependent on the outcome of the previous instruction, it can execute them both simultaneously, if there are more than one cores available. It&#8217;s managed automagically by the interpreter, no threading headache necessary. Conversely, the programmer can specify the ordering of instructions only when necessary (e.g. when interacting with an outside system).</p>
<p>This is why FPs are often mentioned in the current debate surrounding the looming concurrency challenge. This kind of optimization is also being done by Java and .Net&#8217;s VMs, but to a much lesser extent, because of deep differences between imperative (Java, C++, C#) and functional programming languages.</p>
]]></content:encoded>
			<wfw:commentRss>http://programblings.com/2007/08/12/an-epiphany-about-functional-programming-and-lazy-evaluation/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
	</channel>
</rss>
