Nick Sieger: Tag rubyconf2007 http://blog.nicksieger.com/articles/tag/rubyconf2007?tag=rubyconf2007 en-us 40 RubyConf Day 1: Morning Sessions <h2>Marcel Molina: What Makes Code Beautiful?</h2> <p>What is beauty? Marcel explores this topic, starting with posing the question to the audience. &#8220;My wife!&#8221; Marcel: Why is she beautiful? &#8220;Longer answer than you want!&#8221;</p> <p>Marcel comes from a literature/linguistic background, and is interested in how meaning is conveyed, but even beyond the basic words themselves, but the context and expressivity as well.</p> <p><em>Note: Marcel has <a href="http://talklikeaduck.denhaven2.com/articles/2007/08/20/aspects-of-beauty-proportion-integrity-clarity-and-monkey-patching">given this talk before</a>.</em></p> <h3>History of beauty</h3> <p>Pythagoras: was out in the street, heard the blacksmith&#8217;s clanging hammer, and was drawn to the noise. He recognized, through closer inspection, that the different sounds that came from the different hammers had relationships, and eventually saw similar relationships in other parts of nature, architecture, and so on.</p> <p>Thomas Aquinas: Three things that define beauty: 1. Proportion. The economy of size and ratio of parts. The smallest thing that works. 2. Integrity. Well-suited for the purpose. 3. Clarity. Clear and simple.</p> <p>Each of the qualities are necessary, but none are sufficent. For example proportion (economy) will often clash with clarity. This is especially true in code.</p> <h3>Applied to software</h3> <p>Case study: coercion. Converting XML strings into rich Ruby equivalents. Marcel&#8217;s initial solution was a <code>CoercibleString &lt; String</code>, which used a generator to iteratively try to coerce XML attributes to a number of types, and return the results. ~20 lines of code to convert to 4 types. His second version was a simple class method on String with a case statement.</p> <p>Kent Beck, in his book <em>Smalltalk: Best Practice Patterns</em>, writes a book about writing good software, but in Marcel&#8217;s opinion, arrives at a definition of beauty by describing aspects of code that reflect proportion, integrity, and clarity.</p> <p>Niels Bohr: &#8220;An expert is a person who has made all the mistakes that can be made in a very narrow field.&#8221; Marcel calls his CoercibleString a mistake, but one that helped him learn more about coding.</p> <p>Luckily for us, Ruby is optimized for beauty.</p> <h2>Jim Weirich: Advanced Ruby Class Design</h2> <p>Emphasizing &#8220;Ruby&#8221; more so than &#8220;Advanced&#8221;, through three examples that illustrate techniques not commonly found in statically-typed OO languages (Java/C++/Eiffel).</p> <h3><code>Rake::FileList</code></h3> <div class="typocode"><pre><code class="typocode_ruby "><span class="constant">FileList</span><span class="punct">['</span><span class="string">lib/**/*.rb</span><span class="punct">']</span></code></pre></div> <p>FileList sports globbing, a specialized <code>to_s</code>, and lazy evaluation. First version: <code>class FileList &lt; Array; end</code>. Good idea, right? Well, with lazy evaluation, resolution of filenames happens only when the list is accessed, not created, so a lot of methods need to be overloaded:</p> <div class="typocode"><pre><code class="typocode_ruby "><span class="keyword">def </span><span class="method">[]</span><span class="punct">(</span><span class="ident">index</span><span class="punct">)</span> <span class="ident">resolve</span> <span class="keyword">unless</span> <span class="attribute">@resolved</span> <span class="keyword">super</span> <span class="keyword">end</span></code></pre></div> <p>The problem becomes that FileList too closely mimics Array, and cannot distinguish itself in the case that matters. So it was changed to delegate to array rather than inherit.</p> <p>Moral: when you want to mimic built-in classes, it might be better to implement <code>#to_ary</code> or <code>#to_str</code> rather than inherit.</p> <h3>Builder::XmlMarkup</h3> <p>What&#8217;s the problem here?</p> <div class="typocode"><pre><code class="typocode_ruby "> <span class="ident">b</span> <span class="punct">=</span> <span class="constant">Builder</span><span class="punct">::</span><span class="constant">XmlMarkup</span><span class="punct">.</span><span class="ident">new</span> <span class="ident">b</span><span class="punct">.</span><span class="ident">student</span> <span class="keyword">do</span> <span class="ident">b</span><span class="punct">.</span><span class="ident">name</span> <span class="punct">&quot;</span><span class="string">Jim</span><span class="punct">&quot;</span> <span class="ident">b</span><span class="punct">.</span><span class="ident">phone_number</span> <span class="punct">&quot;</span><span class="string">555-1234</span><span class="punct">&quot;</span> <span class="ident">b</span><span class="punct">.</span><span class="keyword">class </span><span class="class">&quot;Intro</span> <span class="ident">to</span> <span class="constant">Ruby</span><span class="punct">&quot;</span><span class="string"> end end</span></code></pre></div> <p><code>class</code> is already a method on Object. This begat <a href="http://builder.rubyforge.org/classes/Builder/BlankSlate.html">BlankSlate</a>, which removes unnecessary methods from <code>Object</code>. Several techniques were applied to eventually arrive at the latest version:</p> <ul> <li>Use <code>undef_method</code> to hide methods that we don&#8217;t want. Except, leave methods beginning with double-underscore alone (<code>__id__</code> and <code>__send__</code>).</li> <li>Catch new methods added via a <code>method_added</code> hook on Kernel, and an <code>append_features</code> hook on Object, to deal with methods defined and modules included after BlankSlate was created</li> </ul> <h3>TableNode</h3> <p>Problem: magic conversion of Rails conditions to SQL. An example: <code>User.find(:all).select{|u| u.name == "jim"}</code>. We don&#8217;t really want to load the entire database to do this, but we don&#8217;t like writing SQL either.</p> <p>Solution: Record the actions in the select block by yielding a special TableNode object that captures the method calls and translates to SQL on the fly. Now we can write <code>User.select {|u| u.name == "Jim"}</code> and have it still execute SQL</p> <ul> <li>Capture methods called and wrap in a MethodNode to convert to SQL column references</li> <li>Capture operators and wrap in a BinaryOpNode to handle <code>==</code>, <code>&lt;</code>, etc.</li> </ul> <p>Clever! Will this work? Here are some issues:</p> <ul> <li>Small issue &#8211; ordering: <code>User.select {|u| "Jim" == u.name}</code> will not work without messing with <code>String#==</code>.</li> <li>Bigger issues: <code>&amp;&amp;</code> and <code>||</code> are not override-able in Ruby. What&#8217;s worse, <code>!</code> has pre-defined semantics (in the parser) and cannot be captured.</li> </ul> <h3>Lessons learned</h3> <ul> <li>Don&#8217;t be afraid to think beyond prior experiences to come up with new ways of solving problems in code.</li> </ul> Fri, 02 Nov 2007 15:35:00 +0000 urn:uuid:ea073446-81d9-4a20-be61-db4c2bf2c771 Nick Sieger http://blog.nicksieger.com/articles/2007/11/02/rubyconf-day-1-morning-sessions rubyconf rubyconf2007 http://blog.nicksieger.com/articles/trackback/338 RubyConf Day 2: Morning Sessions <h2>John Lam: IronRuby</h2> <p>Why IronRuby? John started with RubyCLR, which was a bridge between two languages/environments (.NET CLR and Ruby). Last year he didn&#8217;t know he&#8217;d be uprooting his family from Toronto and moving to Seattle. Now he finds himself in Microsoft trying to make sense of his new position. He describes a number of higher level goals for himself and IronRuby at Microsoft.</p> <p><em>Change or die.</em> Involvement in open source can only go up, right? The challenge is that the company is already doing well, so it&#8217;s hard to convince middle management that anything should change.</p> <p><em>Open source</em>. To their credit, the IronRuby team appears to be on the leading edge of open source at Microsoft (c.f Microsoft Public License). They also had planned all along to take external contributions, and have in fact started to receive them</p> <p><em>Rails.</em> One of the key goals is to be true to the language, and that includes being able to Run Rails.</p> <p><em>Performance.</em> Use IronRuby as a testbed for DLR performance testing.</p> <p>John is showing the REPL now (running under Mono actually), pointing out that &#8220;integer math is now supported&#8221; (apparently early on someone pointed out that subtraction didn&#8217;t work) and that CLR list types automatically appear like Ruby arrays.</p> <p>Heavy DLR pitch ahead. Performance history, how the CLR used to be slow for dynamic languages, and how it&#8217;s better now.</p> <p>John is running the Rubinius specs now, and showing only 373 out of 1030 failing. (It looked like he was running the core specs only.) Praise for the Rubinius team!</p> <p>It&#8217;s possible to bind C# types to Ruby using annotations. Lots of C# code being shown, including a mess of generated code.</p> <p>John also showed a XAML/Silverlight demo that was scripted by Ruby.</p> <h2>Charles Nutter and Thomas Enebo: JRuby</h2> <p>JRuby: &#8220;Not Just&#8221; JRuby for the JVM. I found it hard to take notes for this talk since I&#8217;m so close to it. Fortunately, their slides were pretty verbose and comprehensive, and hopefully will be posted shortly.</p> <h2>Evan Phoenix: Rubinius</h2> <p>Rubinius talk in roller derby mode. Ask questions early and often.</p> <p>What is the end game of Rubinius (or JRuby, or IronRuby)? Total. World. Domination. <strong>For Ruby!</strong></p> <p>Rubinius is 3 things: form, function, and elbow grease. <code>Ruby::Syntax, Ruby::Behavior, and Google.search("crazy cs papers")</code>.</p> <p><em>Rapid fire CS Nerd attack mode coming</em>. Generational collection, bytecode execution, stackless, bytecode represenation, .rba archives.</p> <p>Who would rather program C than Ruby? Java? C#? (Only one guy raised his hand that he&#8217;d rather code C.)</p> <p><em>Hard-hitting portion of the talk.</em> The kernel, broken down.</p> <ul> <li><p>1.8</p> <ul> <li>84,516 lines of C</li> <li>0 lines of Ruby</li> </ul></li> <li><p>1.9</p> <ul> <li>128,786 lines of C</li> <li>0 lines of Ruby</li> </ul></li> <li><p>IronRuby</p> <ul> <li>48,282 lines of C#</li> <li>0 lines of Ruby</li> </ul></li> <li><p>JRuby</p> <ul> <li>114,507 lines of Java</li> <li>0 lines of Ruby*</li> </ul></li> </ul> <p>(*Even though I got heckled for saying it, JRuby does actually have some code written in Ruby that&#8217;s not the standard library.)</p> <ul> <li>Rubinius <ul> <li>25,398 lines of C</li> <li>13,946 lines of Ruby</li> </ul></li> </ul> <p>1.8 and 1.9 are really Ruby for C programmers. JRuby is Ruby for Java programmers. IronRuby is Ruby for C# programmers. But Rubinius is <em>Ruby for Ruby programmers</em>.</p> <p>Dogfooding. Gives feedback, which enables tighter loops, improves the kernel, makes life better for everyone on the platform.</p> <p>Road, rubber, all that jazz. Evan mentions that Rubinius runs 24 of 31 benchmarks faster than Ruby 1.8, but the numbers are shifting rapidly. Evan wanted a 1.0 for RubyConf, but he has come to realize that several things are more important than a milestone. Design, and the technical challenges, certainly. But more importantly, the community.</p> <p>Taking a cue from the Perl 6 community, <code>-Ofun</code>. The free-flowing commit bit, where patch sumbitters whose patches are accepted are immediately entitled commit rights, has given rise to 57 committers. 17 of these have changed more than 400 lines of code.</p> Sun, 04 Nov 2007 02:12:00 +0000 urn:uuid:26c1ed61-3411-4a33-9275-5014a5bc581e Nick Sieger http://blog.nicksieger.com/articles/2007/11/04/rubyconf-morning-day-2 rubyconf rubyconf2007 http://blog.nicksieger.com/articles/trackback/339 RubyConf Day 3: Behaviour-Driven Development with RSpec <h2>David Chelimsky and Dave Astels: RSpec</h2> <div class="typocode"><pre><code class="typocode_ruby "><span class="ident">describe</span> <span class="constant">TestDriverDevelopment</span> <span class="keyword">do</span> <span class="ident">it</span> <span class="punct">&quot;</span><span class="string">is an incremental process</span><span class="punct">&quot;</span> <span class="ident">it</span> <span class="punct">&quot;</span><span class="string">drives the implementation</span><span class="punct">&quot;</span> <span class="ident">it</span> <span class="punct">&quot;</span><span class="string">results in an exhaustive test suite</span><span class="punct">&quot;</span> <span class="comment"># but also...</span> <span class="ident">it</span> <span class="punct">&quot;</span><span class="string">should focus on design</span><span class="punct">&quot;</span> <span class="ident">it</span> <span class="punct">&quot;</span><span class="string">should focus on documentation</span><span class="punct">&quot;</span> <span class="ident">it</span> <span class="punct">&quot;</span><span class="string">should focus on behaviour</span><span class="punct">&quot;</span> <span class="keyword">end</span> <span class="keyword">class </span><span class="class">BehaviourDrivenDevelopment</span> <span class="punct">&lt;</span> <span class="constant">TestDrivenDevelopment</span> <span class="ident">include</span> <span class="constant">FocusOnDesign</span> <span class="ident">include</span> <span class="constant">FocusOnDocumentation</span> <span class="ident">include</span> <span class="constant">FocusOnBehavior</span> <span class="keyword">end</span></code></pre></div> <p>When doing test-driven development:</p> <ul> <li>Write your intent first. The smallest test you can that fails.</li> <li>Next, write the implementation. The simplest thing that could possibly work.</li> <li>Even though you may be tempted to think about additional edge cases, multiple requirements, etc., you should try to be disciplined and focus only on the immediate tests. Only after you&#8217;ve made one test fail, then pass, can you continue on to other tests.</li> </ul> <h3>RSpec history</h3> <p>Initially BDD was just a discussion among Aslak Hellesoy and Dan North in the ThoughtWorks London office. Dave Astels joined the conversation with a blog post stating that he thought these ideas could be easily implemented in Smalltalk or Ruby. Steven Baker jumped in with an initial implementation, and released RSpec 0.1. Later in 2006, maintenance was handed over to David Chelimsky. RSpec has evolved through a dog-fooding phase up to the present 1.0 product.</p> <p>BDD is no longer just about &#8220;should instead of assert&#8221;, it&#8217;s evolving into a process. Emphasizing central concepts from extreme programming and domain-driven design, it&#8217;s moving toward focusing on customer stories and acceptance testing. It&#8217;s outside-in, starting at high levels of detail, rather than low-level like RSpec or Test::Unit.</p> <h3>Story Runner</h3> <p>Story Runner is a new feature intended for RSpec 1.1. Each story is supposed to capture a customer requirement in the following general template:</p> <pre><code>As a (role) ... I want to (some function) ... so that (some business value). </code></pre> <p>It uses a &#8220;Scenario &#8230; Given &#8230; When &#8230; Then &#8230;&#8221; format to express the high level stories. Scenarios are a series of given items, steps, and behaviour validations. Once the basic steps are established, they can be re-used. David even demonstrated a preview of an in-browser story runner that would allow the customer to play with the implementation and create new scenarios.</p> <h3>Pending</h3> <p><em>Pending</em> is a nice way to mark specs as &#8220;in-progress&#8221;. You can either omit a block for your spec, or use <code>pending</code> inside the block to leave a placeholder to come back to.</p> <div class="typocode"><pre><code class="typocode_ruby "><span class="ident">describe</span> <span class="constant">Pending</span> <span class="keyword">do</span> <span class="ident">it</span> <span class="punct">&quot;</span><span class="string">doesn't need a block to be pending</span><span class="punct">&quot;</span> <span class="ident">it</span> <span class="punct">&quot;</span><span class="string">could also be specified inside the block</span><span class="punct">&quot;</span> <span class="keyword">do</span> <span class="ident">pending</span><span class="punct">(&quot;</span><span class="string">TODO</span><span class="punct">&quot;)</span> <span class="ident">this</span><span class="punct">.</span><span class="ident">should_not</span> <span class="ident">be_a_failure</span> <span class="keyword">end</span> <span class="ident">it</span> <span class="punct">&quot;</span><span class="string">could also use a block with pending, and you will be notified when it starts to succeed</span><span class="punct">&quot;</span> <span class="keyword">do</span> <span class="ident">pending</span><span class="punct">(&quot;</span><span class="string">TODO</span><span class="punct">&quot;)</span> <span class="keyword">do</span> <span class="ident">this</span><span class="punct">.</span><span class="ident">should_not</span> <span class="ident">be_a_failure</span> <span class="keyword">end</span> <span class="keyword">end</span> <span class="keyword">end</span></code></pre></div> <p>Behaviour-Driven Development in Ruby with RSpec is a new book David and Aslak are working on, due out early next year.</p> <p><em>Update: <a href="http://blog.davidchelimsky.net/articles/2007/11/05/rubyconf-slides">David has posted his slides</a>.</em></p> Sun, 04 Nov 2007 16:26:00 +0000 urn:uuid:48613cce-c252-4be0-a12e-923eb239c87a Nick Sieger http://blog.nicksieger.com/articles/2007/11/04/rubyconf-day-3-behaviour-driven-development-with-rspec rubyconf rubyconf2007 rspec http://blog.nicksieger.com/articles/trackback/343 RubyConf: Parting Thoughts <p>RubyConf once again was thoroughly enjoyable. I highly recommend it to any Rubyist who is on the fence about attending to make it a priority to go next year. Here are some quick, random notes that didn&#8217;t quite fit into a full post.</p> <ul> <li>For those of you who stopped by expecting to see the blow-by-blow of every minute of the conference like <a href="http://blog.nicksieger.com/articles/tag/rubyconf2006">last year</a>, my apologies. I think I set the bar a little too high for myself. It takes a lot of energy to stay focused on the sessions for the whole day. Perhaps it&#8217;s appropriate to pass the baton on to <a href="http://dotavery.com/blog/archive/2007/11/01/149438.aspx">James Avery</a> or <a href="http://giantrobots.thoughtbot.com/2007/11/5/rubyconf-2007-day-3">Eric Mill</a> for their 2007 coverage.</li> <li>Venue (Omni Hotel Charlotte): Generally speaking, thumbs up. There were a couple of annoyances, though. 1. No non-emergency staircase to get to your room, causing huge lines for the elevators at the end of the afternoon. 2. Coffee was removed from the scene before 10 am, raising speculation that it was a conspiracy to drive business to the Starbucks in the mall below. 3. Toasters blew out the sound system on Sunday morning, forcing a PA system to be brought out and throwing a wrench in the rhythm of the morning talks.</li> <li>I have to give props to <a href="http://drnicwilliams.com/2007/11/05/rubigen-meets-the-a-team-live-in-charlotte/">Dr. Nic</a> for avoiding getting burnt by the toaster incident and handling it really well. To boot, he gave one of the most entertaining talks at the conference, as the <a href="http://www.youtube.com/watch?v=6PPTzdA94OQ">RubiGen video</a> is sure to become an instant conference classic much like <a href="http://youtube.com/watch?v=VH3omawiNiM">Adam Keys&#8217; one-man-one-act event</a> from last year.</li> <li>Werewolf: I played one game, miserably. I was a werewolf, and when cornered by another in the game, mustered up the quote &#8220;I&#8217;m not an aggressive player, I prefer to <em>feed</em> off of other people.&#8221; Wow, what a freudian slip. While I can sympathize with <a href="http://headius.blogspot.com/2007/11/is-werewolf-killing-conference-hackfest.html">Charlie&#8217;s comments</a> about the game (and I do really enjoy late-night hackfests), I also have to agree with Chad and the other commenters that the two are not mutually exclusive, and the Werewolf games are wonderfully inclusive of RubyConf newbies and veterans alike.</li> <li>The two-track approach in the afternoon this year seemed to go well, despite making it impossible to see all the talks. I would have liked to have seen <a href="http://www.code4lib.org/blog/209">Erik Hatcher&#8217;s</a> Solr talk, but instead decided to give moral support to <a href="http://www.kylemaxwell.com/" title="Kyle Maxwell, Ruby, etc">Kyle Maxwell&#8217;s</a> JRuby in the Wild talk. I also missed the Saturday afternoon tracks to hang out in Stu&#8217;s <a href="http://relevancellc.com/2007/11/2/rubyconf-slides">Refactotum</a> session.</li> <li>Lots of good quotables: check out <a href="http://ni.hili.st/">Nihilist</a> and <a href="http://twitter.com/rconf/">Twitter</a> for some of the back-channel chatter.</li> </ul> <p>See you next year!</p> Mon, 05 Nov 2007 17:57:34 +0000 urn:uuid:64f8dca9-7573-4e3e-bfdb-a82fa0af3779 Nick Sieger http://blog.nicksieger.com/articles/2007/11/05/rubyconf-parting-thoughts rubyconf rubyconf2007 http://blog.nicksieger.com/articles/trackback/344