<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <title>iBrasten - Blog</title>
  <id>tag:www.ibrasten.com,2012:mephisto/</id>
  <generator uri="http://mephistoblog.com" version="0.8.0">Mephisto Drax</generator>
  <link href="http://www.ibrasten.com/feed/atom.xml" rel="self" type="application/atom+xml"/>
  <link href="http://www.ibrasten.com/" rel="alternate" type="text/html"/>
  <updated>2010-11-19T01:46:20Z</updated>
  <entry xml:base="http://www.ibrasten.com/">
    <author>
      <name>brasten</name>
    </author>
    <id>tag:www.ibrasten.com,2010-11-19:9912</id>
    <published>2010-11-19T01:37:00Z</published>
    <updated>2010-11-19T01:46:20Z</updated>
    <category term="ruby"/>
    <category term="specs"/>
    <link href="http://www.ibrasten.com/articles/2010/11/19/autotest-w-scriptingcontainers" rel="alternate" type="text/html"/>
    <title>Autotest w/ ScriptingContainers</title>
<content type="html">
            &lt;p&gt;In my last blog post, I demonstrated a couple ways to improve JRuby startup performance by remove various startup steps (Bundler). In this post, I'll show you how to reduce your waiting time when running Autotest/RSpec in JRuby by instantiating ScriptingContainers and loading library code so it's ready to go when needed.&lt;/p&gt;

&lt;p&gt;There are a couple other libraries that do similar things (Spork, for example), but I have been unable to get any of them to work [well].&lt;/p&gt;

&lt;p&gt;A warning: whereas my last post showed The Way It Should Be (according to me), this post is a quick-n-dirty hack that just happens to work for me.  Benchmarks are far from scientific, but they shouldn't surprise anyone either.&lt;/p&gt;

&lt;h3&gt;The Project&lt;/h3&gt;

&lt;p&gt;Same little application as the last post.  There's only one actual spec, the rest are Pending.  We're focusing more on the time it takes to start executing the specs, not finish them.&lt;/p&gt;

&lt;p&gt;For both runs I'm including the initial execution of all specs, plus three individual executions triggered by modified spec files.&lt;/p&gt; 

&lt;h3&gt;Autotest / rspec_rails&lt;/h3&gt;

&lt;p&gt;First, running an almost-standard autotest setup.  The only thing different here is I hacked in the &quot;time &quot; prefix.&lt;/p&gt;

&lt;p&gt;
&lt;pre class=&quot;basicCode&quot;&gt;
&lt;b&gt;&amp;lt;u&gt;Initial run of all tests&amp;lt;/u&gt;&lt;/b&gt;
&lt;code&gt;
time bundle exec /Users/brasten/.rvm/rubies/jruby-1.5.5/bin/jruby -rrubygems -S /Users/brasten/.rvm/gems/jruby-1.5.5/gems/rspec-core-2.1.0/bin/rspec --autotest '/Users/brasten/Development/Projects/Scratch/warehouse/spec/controllers/customers_controller_spec.rb' '/Users/brasten/Development/Projects/Scratch/warehouse/spec/controllers/inventory_items_controller_spec.rb' '/Users/brasten/Development/Projects/Scratch/warehouse/spec/helpers/customers_helper_spec.rb' '/Users/brasten/Development/Projects/Scratch/warehouse/spec/helpers/inventory_items_helper_spec.rb' '/Users/brasten/Development/Projects/Scratch/warehouse/spec/models/inventory_item_spec.rb' '/Users/brasten/Development/Projects/Scratch/warehouse/spec/requests/customers_spec.rb'
*****.

Pending:
  CustomersController add some examples to (or delete) /Users/brasten/Development/Projects/Scratch/warehouse/spec/controllers/customers_controller_spec.rb
    # Not Yet Implemented
    # ./spec/controllers/customers_controller_spec.rb:4
  InventoryItemsController add some examples to (or delete) /Users/brasten/Development/Projects/Scratch/warehouse/spec/controllers/inventory_items_controller_spec.rb
    # Not Yet Implemented
    # ./spec/controllers/inventory_items_controller_spec.rb:4
  CustomersHelper add some examples to (or delete) /Users/brasten/Development/Projects/Scratch/warehouse/spec/helpers/customers_helper_spec.rb
    # Not Yet Implemented
    # ./spec/helpers/customers_helper_spec.rb:14
  InventoryItemsHelper add some examples to (or delete) /Users/brasten/Development/Projects/Scratch/warehouse/spec/helpers/inventory_items_helper_spec.rb
    # Not Yet Implemented
    # ./spec/helpers/inventory_items_helper_spec.rb:14
  InventoryItem add some examples to (or delete) /Users/brasten/Development/Projects/Scratch/warehouse/spec/models/inventory_item_spec.rb
    # Not Yet Implemented
    # ./spec/models/inventory_item_spec.rb:4

Finished in 0.208 seconds
6 examples, 0 failures, 5 pending

real     &lt;b&gt;0m15.324s&lt;/b&gt;
user     0m21.998s
sys     0m1.223s
&lt;/code&gt;

&lt;b&gt;&amp;lt;u&gt;Running modified specs&amp;lt;/u&gt;&lt;/b&gt;
&lt;code&gt;
time bundle exec /Users/brasten/.rvm/rubies/jruby-1.5.5/bin/jruby -rrubygems -S /Users/brasten/.rvm/gems/jruby-1.5.5/gems/rspec-core-2.1.0/bin/rspec --autotest '/Users/brasten/Development/Projects/Scratch/warehouse/spec/requests/customers_spec.rb'
.

Finished in 0.164 seconds
1 example, 0 failures

real     &lt;b&gt;0m15.428s&lt;/b&gt;
user     0m22.083s
sys     0m1.258s
time bundle exec /Users/brasten/.rvm/rubies/jruby-1.5.5/bin/jruby -rrubygems -S /Users/brasten/.rvm/gems/jruby-1.5.5/gems/rspec-core-2.1.0/bin/rspec --autotest '/Users/brasten/Development/Projects/Scratch/warehouse/spec/models/inventory_item_spec.rb'
*

Pending:
  InventoryItem add some examples to (or delete) /Users/brasten/Development/Projects/Scratch/warehouse/spec/models/inventory_item_spec.rb
    # Not Yet Implemented
    # ./spec/models/inventory_item_spec.rb:4

Finished in 0.002 seconds
1 example, 0 failures, 1 pending

real     &lt;b&gt;0m15.415s&lt;/b&gt;
user     0m22.214s
sys     0m1.231s
time bundle exec /Users/brasten/.rvm/rubies/jruby-1.5.5/bin/jruby -rrubygems -S /Users/brasten/.rvm/gems/jruby-1.5.5/gems/rspec-core-2.1.0/bin/rspec --autotest '/Users/brasten/Development/Projects/Scratch/warehouse/spec/controllers/customers_controller_spec.rb'
*

Pending:
  CustomersController add some examples to (or delete) /Users/brasten/Development/Projects/Scratch/warehouse/spec/controllers/customers_controller_spec.rb
    # Not Yet Implemented
    # ./spec/controllers/customers_controller_spec.rb:4

Finished in 0.001 seconds
1 example, 0 failures, 1 pending

real     &lt;b&gt;0m15.908s&lt;/b&gt;
user     0m22.447s
sys     0m1.233s

&lt;/code&gt;
&lt;/pre&gt;
&lt;/p&gt;


&lt;h3&gt;Autotest w/ ScriptingContainers&lt;/h3&gt;

&lt;p&gt;To get this running, make the following changes:&lt;/p&gt;

&lt;ol&gt;

     &lt;li&gt;
          &lt;p&gt;Modify (or create) the &amp;lt;u&gt;autotest/discover.rb&amp;lt;/u&gt; file in your project so that it looks like the following:&lt;/p&gt;
          &lt;p&gt;
               &lt;pre class=&quot;basicCode&quot;&gt;
                    &lt;code&gt;
Autotest.add_discovery { &quot;jruby&quot; }
Autotest.add_discovery { &quot;rails&quot; }
Autotest.add_discovery { &quot;rspec2&quot; }               
                    &lt;/code&gt;
               &lt;/pre&gt;
          &lt;/p&gt;
     &lt;/li&gt;

     &lt;li&gt;
          &lt;p&gt;Next, create &amp;lt;u&gt;autotest/jruby_rails_rspec2.rb&amp;lt;/u&gt; with the following contents:&lt;/p&gt;
          &lt;p&gt;
               &lt;pre class=&quot;basicCode&quot;&gt;
                    &lt;code&gt;
require 'java'
require 'benchmark'
require 'autotest/rails_rspec2'
require 'pathname'

# Sends RSpec to stdout and provided buffer
#
class ResultsCollector
 
  class &amp;lt;&amp;lt; self
   
    # ... inexplicable syntax preference
    def into(buffer)
      self.new(buffer)
    end
  end
 
  def initialize(resultsBuffer)
    @buffer = resultsBuffer
  end
 
  def puts(line=&quot;&quot;)
    Kernel.puts(line)
    @buffer &amp;lt;&amp;lt; &quot;#{line}\n&quot;
  end
  def print(line=&quot;&quot;)
    Kernel.print(line)
    @buffer &amp;lt;&amp;lt; line
  end
 
end

class Autotest::JrubyRailsRspec2 &amp;lt; Autotest::RailsRspec2
  java_import 'org.jruby.embed.ScriptingContainer'
  java_import 'org.jruby.embed.LocalContextScope'
  java_import 'org.jruby.embed.LocalVariableBehavior'

  def initialize
    super
    setup_scripting_container
  end
 
  # Setup a ScriptingContainer so it's ready to go
  # the next time we need it
  #
  def setup_scripting_container
    trap('INT') do
      exit!(1)
    end
   
    tms = Benchmark.measure {
      puts &quot;setting up scripting container...&quot;
      @runtime = ScriptingContainer.new(LocalContextScope::SINGLETHREAD, LocalVariableBehavior::PERSISTENT)

      # ... requiring spec_helper here offloads even more startup time from our testing cycle, but for
      #     some projects (maybe most?) this may not work.  If spec_helper does anything that loads your
      #     application files, then you should comment out that line.
      #
      #     This should be a config option somewhere probably.
      #
      @runtime.runScriptlet(&amp;lt;&amp;lt;-script&gt;&amp;lt;&amp;lt; 'spec'
        require 'config/application'
        RSpec::Core::Runner.disable_autorun!
      SCRIPT
    }

    puts &quot;scripting container set up in #{format('%.3f', tms.real)} seconds&quot;
    puts
  end

  def run_tests
    hook :run_command

    new_mtime = self.find_files_to_test
    return unless new_mtime
    self.last_mtime = new_mtime

    files_to_test = self.files_to_test
    file_list = normalize(files_to_test).keys.flatten.join(' ')
    return if file_list.empty?

    file_display = normalize(files_to_test).keys.flatten.map {|f|
                     &quot; -&gt; &quot; + Pathname.new(f).relative_path_from(Pathname.new(File.expand_path('../..', __FILE__)))
                  }.join(&quot;\n&quot;)

    puts &quot;Running:&quot;
    puts file_display

    self.results = &quot;&quot;
     
    @runtime.put(&quot;outputStream&quot;, ResultsCollector.into(self.results))

    tms = Benchmark.measure {
      # ... we should probably respect config settings here... eventually.
      #
      @runtime.runScriptlet(&amp;lt;&amp;lt;-script&gt;&lt;/code&gt;
               &lt;/pre&gt;
          &lt;/p&gt;
     &lt;/li&gt;

&lt;/ol&gt;

&lt;p&gt;And you're done.  To the specs!&lt;/p&gt;

&lt;p&gt;
&lt;pre class=&quot;basicCode&quot;&gt;
&lt;b&gt;&amp;lt;u&gt;Initial run of all tests&amp;lt;/u&gt;&lt;/b&gt;
&lt;code&gt;
setting up scripting container...
scripting container set up in 7.047 seconds

Running:
 -&gt; spec/controllers/customers_controller_spec.rb
 -&gt; spec/controllers/inventory_items_controller_spec.rb
 -&gt; spec/helpers/customers_helper_spec.rb
 -&gt; spec/helpers/inventory_items_helper_spec.rb
 -&gt; spec/models/inventory_item_spec.rb
 -&gt; spec/requests/customers_spec.rb
*****.

Pending:
  CustomersController add some examples to (or delete) /Users/brasten/Development/Projects/Scratch/warehouse/spec/controllers/customers_controller_spec.rb
    # Not Yet Implemented
    # ./spec/controllers/customers_controller_spec.rb:4
  InventoryItemsController add some examples to (or delete) /Users/brasten/Development/Projects/Scratch/warehouse/spec/controllers/inventory_items_controller_spec.rb
    # Not Yet Implemented
    # ./spec/controllers/inventory_items_controller_spec.rb:4
  CustomersHelper add some examples to (or delete) /Users/brasten/Development/Projects/Scratch/warehouse/spec/helpers/customers_helper_spec.rb
    # Not Yet Implemented
    # ./spec/helpers/customers_helper_spec.rb:14
  InventoryItemsHelper add some examples to (or delete) /Users/brasten/Development/Projects/Scratch/warehouse/spec/helpers/inventory_items_helper_spec.rb
    # Not Yet Implemented
    # ./spec/helpers/inventory_items_helper_spec.rb:14
  InventoryItem add some examples to (or delete) /Users/brasten/Development/Projects/Scratch/warehouse/spec/models/inventory_item_spec.rb
    # Not Yet Implemented
    # ./spec/models/inventory_item_spec.rb:4

Finished in 0.29 seconds
6 examples, 0 failures, 5 pending
tests completed in 2.624 seconds

setting up scripting container...
scripting container set up in 5.168 seconds
&lt;/code&gt;

&lt;b&gt;&amp;lt;u&gt;Running modified specs&amp;lt;/u&gt;&lt;/b&gt;
&lt;code&gt;
Running:
 -&gt; spec/requests/customers_spec.rb
.

Finished in 0.156 seconds
1 example, 0 failures
tests completed in &lt;b&gt;1.952 seconds&lt;/b&gt;


setting up scripting container...
scripting container set up in 4.635 seconds

Running:
 -&gt; spec/models/inventory_item_spec.rb
*

Pending:
  InventoryItem add some examples to (or delete) /Users/brasten/Development/Projects/Scratch/warehouse/spec/models/inventory_item_spec.rb
    # Not Yet Implemented
    # ./spec/models/inventory_item_spec.rb:4

Finished in 0.001 seconds
1 example, 0 failures, 1 pending
tests completed in &lt;b&gt;1.785 seconds&lt;/b&gt;


setting up scripting container...
scripting container set up in 4.441 seconds

Running:
 -&gt; spec/controllers/customers_controller_spec.rb
*

Pending:
  CustomersController add some examples to (or delete) /Users/brasten/Development/Projects/Scratch/warehouse/spec/controllers/customers_controller_spec.rb
    # Not Yet Implemented
    # ./spec/controllers/customers_controller_spec.rb:4

Finished in 0.001 seconds
1 example, 0 failures, 1 pending
tests completed in &lt;b&gt;1.825 seconds&lt;/b&gt;


setting up scripting container...
scripting container set up in 4.405 seconds
&lt;/code&gt;

&lt;/pre&gt;
&lt;/p&gt;


&lt;h3&gt;The Results&lt;/h3&gt;

&lt;p&gt;It's a little tough to see exactly what's happening here just from the text.  Autotest is ensuring that a fresh ScriptingContainer is set up and ready to go shortly after a test run is completed.  The initial run isn't going to see any significant improvements, of course, but executions triggered by detecting file modifications already have an environment set up to run against.&lt;/p&gt;

&lt;p&gt;Anyway, it's been a long day so I'm sure I did not do a fantastic job explaining this, but give it a shot and see for yourself.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Update:&lt;/b&gt; This seems to leak memory.  I'll be filing a JRuby bug momentarily.  In the meantime you may need to restart Autotest every once in a while.  Like I said at the beginning, hack.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.ibrasten.com/">
    <author>
      <name>brasten</name>
    </author>
    <id>tag:www.ibrasten.com,2010-11-15:9905</id>
    <published>2010-11-15T04:11:00Z</published>
    <updated>2011-01-06T21:17:45Z</updated>
    <link href="http://www.ibrasten.com/articles/2010/11/15/reducing-jruby-startup-by-ditching-bundler" rel="alternate" type="text/html"/>
    <title>Reducing JRuby Startup by Ditching Bundler</title>
<content type="html">
            &lt;div class=&quot;update&quot;&gt;
&lt;p&gt;&lt;b&gt;UPDATE 2:&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;
Amazingly, I was unaware of the &lt;a href=&quot;https://github.com/vjoel/crown&quot;&gt;Crown&lt;/a&gt; RubyGem when I wrote this article. It clearly would simplify the task of creating your monolithic 'lib' directory called for toward the end of this post.
&lt;/p&gt;
&lt;/div&gt;

&lt;div class=&quot;update&quot;&gt;
&lt;p&gt;
  &lt;b&gt;UPDATE:&lt;/b&gt;
&lt;/p&gt;

&lt;p&gt;
  The introduction of &lt;i&gt;--standalone&lt;/i&gt; to Bundler (head) largely invalidates this post, and hurray for that! At the risk of repeating myself: Bundler is a fantastic dev-time tool, but should not be a run-time dependency. I haven't yet had the time to play with &lt;i&gt;--standalone&lt;/i&gt; to see how it changes the steps specified in this post, but as soon as I do I'll post an update.
&lt;/p&gt;

&lt;p&gt;
I'd like to think that the timing of &lt;i&gt;--standalone&lt;/i&gt;'s introduction into Bundler was influenced by this post. I have no evidence to back that up. :-)
&lt;/p&gt;
&lt;/div&gt;

&lt;h3&gt;Prelude&lt;/h3&gt;

&lt;p&gt;
Has it really been over two years since I last blogged? I certainly *started* a lot of blog posts in that time but usually run out of steam before finishing them. Turns out that Twitter / Facebook is a lot more suited to my writing style.
&lt;/p&gt;

&lt;p&gt;
Nevertheless, a post such as this simply won't fit on Twitter and won't reach many folks on Facebook, so here I am.
&lt;/p&gt;

&lt;h3&gt;I Love JRuby, but...&lt;/h3&gt;

&lt;p&gt;
This shouldn't surprise most people: JRuby kicks ass; JRuby startup sucks&lt;sup&gt;&lt;a href=&quot;#sub_1&quot;&gt;(1)&lt;/a&gt;&lt;/sup&gt;. This is not an indictment against JRuby, &lt;a href=&quot;http://twitter.com/headius&quot;&gt;@headius&lt;/a&gt; or any of the other JRuby devs. JRuby is in a sense booting up a VM on top of a VM, so it's going to take a little time.
&lt;/p&gt;

&lt;p&gt;
Turns out, though, you can cut JRuby startup times significantly for many applications -- over 50% on several projects I've worked on.
&lt;/p&gt;

&lt;h3&gt;I Love Bundler, but...&lt;/h3&gt;

&lt;p&gt;
I really do. But, Bundler is -- or should be -- a dev-time tool, not a runtime tool. This is not a new concept (&lt;a href=&quot;http://tomayko.com/writings/require-rubygems-antipattern&quot;&gt;http://tomayko.com/writings/require-rubygems-antipattern&lt;/a&gt;) and I'm a little surprised at how quickly the Ruby community in general has accepted 'require &quot;bundler&quot;' in their code even as they were starting to reject 'require &quot;rubygems&quot;'.
&lt;/p&gt;

&lt;p&gt;
It also turns out to be a huge performance drain during startup on JRuby. I'm guessing this is because the JIT can't really optimize that startup code in time to make a difference.
&lt;/p&gt;

&lt;p&gt;
In any case, Bundler -- at runtime -- has to go.
&lt;/p&gt;

&lt;h3&gt;The Project and Initial Benchmark&lt;/h3&gt;
&lt;p&gt;
Let's start with a standard Rails 3 application and run some performance tests&lt;sup&gt;&lt;a href=&quot;#sub_2&quot;&gt;(2)&lt;/a&gt;&lt;/sup&gt;.
&lt;/p&gt;

&lt;p&gt;
To assist with benchmarking, I've modified the Rakefile and wrapped the standard header lines in individual benchmarked blocks.  I've also created  a task that executes Rails' &quot;routes&quot; task -- this is just to ensure that the Rails environment is loaded and hit once.
&lt;/p&gt;

&lt;p&gt;
&lt;pre&gt;
&lt;b&gt;&amp;lt;u&gt;Rakefile&amp;lt;/u&gt;&lt;/b&gt;
&lt;code&gt;
require 'benchmark'

Benchmark.bm(20) do |x|
  x.report(&quot;application:&quot;) {
    require File.expand_path('../config/application', __FILE__)
  }
  x.report(&quot;rake:&quot;) {
    require 'rake'
  }
 
  x.report(&quot;load_tasks:&quot;) {
    Warehouse::Application.load_tasks
  }
end

task :report do
 
  Benchmark.bm(20) do |x|
    x.report(&quot;Routes:&quot;) {
      Rake::Task[:routes].invoke()
    }
  end
  puts &quot;Bundler  : #{defined?(Bundler) ? 'YES' : 'NO'}&quot;

end
&lt;/code&gt;
&lt;/pre&gt;
&lt;/p&gt;

&lt;p&gt;
Because I will be changing them later, here is the original config/boot.rb and config/application.rb files for our Rails 3 application:
&lt;/p&gt;

&lt;p&gt;
&lt;pre&gt;
&lt;b&gt;&amp;lt;u&gt;boot.rb&amp;lt;/u&gt;&lt;/b&gt;
&lt;code&gt;
require 'rubygems'

# Set up gems listed in the Gemfile.
gemfile = File.expand_path('../../Gemfile', __FILE__)
begin
  ENV['BUNDLE_GEMFILE'] = gemfile
  require 'bundler'
  Bundler.setup
rescue Bundler::GemNotFound =&gt; e
  STDERR.puts e.message
  STDERR.puts &quot;Try running `bundle install`.&quot;
  exit!
end if File.exist?(gemfile)
&lt;/code&gt;
&lt;/pre&gt;

&lt;pre&gt;
&lt;b&gt;&amp;lt;u&gt;application.rb&amp;lt;/u&gt;&lt;/b&gt;
&lt;code&gt;
require File.expand_path('../boot', __FILE__)
require 'rails/all'

Bundler.require(:default, Rails.env) if defined?(Bundler)

module Warehouse
  class Application &amp;lt; Rails::Application
    config.encoding = &quot;utf-8&quot;
    config.filter_parameters += [:password]
  end
end
&lt;/code&gt;
&lt;/pre&gt;
&lt;/p&gt;

&lt;p&gt;
Now let's run some benchmarks; first, for comparison, Ruby 1.9.2:
&lt;/p&gt;

&lt;p&gt;
&lt;pre&gt;
&lt;b&gt;&amp;lt;u&gt;Ruby 1.9.2&amp;lt;/u&gt;&lt;/b&gt;
&lt;code&gt;
brasten@SilverBook ~/D/P/S/warehouse&gt; time ruby -I. -S rake report
(in /Users/brasten/Development/Projects/Scratch/warehouse)
                          user     system      total        real
application:          0.680000   0.180000   0.860000 (  0.870297)
rake:                 0.000000   0.000000   0.000000 (  0.000031)
load_tasks:           0.030000   0.010000   0.040000 (  0.045394)
                          user     system      total        real
Routes:               0.720000   0.130000   0.850000 (  0.853033)
Bundler  : YES
        2.03 real         1.62 user         0.37 sys
&lt;/code&gt;
&lt;/pre&gt;
&lt;/p&gt;

&lt;p&gt;
2 seconds, not horrible ... now JRuby:
&lt;/p&gt;

&lt;p&gt;
&lt;pre&gt;
&lt;b&gt;&amp;lt;u&gt;JRuby 1.5.3&amp;lt;/u&gt;&lt;/b&gt;
&lt;code&gt;
brasten@SilverBook ~/D/P/S/warehouse&gt; time rake report
(in /Users/brasten/Development/Projects/Scratch/warehouse)
                          user     system      total        real
application:          4.851000   0.000000   4.851000 (  4.851000)
rake:                 0.000000   0.000000   0.000000 (  0.000000)
load_tasks:           0.410000   0.000000   0.410000 (  0.410000)
                          user     system      total        real
Routes:               2.118000   0.000000   2.118000 (  2.118000)
Bundler  : YES
       &lt;b&gt;10.15 real&lt;/b&gt;        14.61 user         0.75 sys
&lt;/code&gt;
&lt;/pre&gt;
&lt;/p&gt;

&lt;p&gt;
Ouch, 10 seconds.  So this is our starting point.
&lt;/p&gt;

&lt;h3&gt;The Great Bundler Removal&lt;/h3&gt;
&lt;p&gt;
Next, let's remove Bundler.  The steps for removing Bundler from your Rails 3 application are as follows:
&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Install your gems somewhere in your project.&lt;/p&gt;

    &lt;p&gt;One way to do this is simply to run &quot;bundle install --path=vendor/gems&quot;.&lt;/p&gt;

    &lt;p&gt;For my projects, I have a Rake task that packages gems in &quot;deps/development&quot; and &quot;deps/runtime&quot; to handle gem groups. Following examples will assume an install path of deps/development (via &quot;bundle install --path=deps/development&quot;).&lt;/p&gt;
  &lt;/li&gt;

  &lt;li&gt;
    &lt;p&gt;Create a file that adds your gem lib dirs to the load path. In my case, we'll assume a file called &quot;deps/development.rb.&quot; &lt;/p&gt;

&lt;p&gt;
&lt;pre&gt;
&lt;b&gt;&amp;lt;u&gt;deps/development.rb&amp;lt;/u&gt;&lt;/b&gt;
&lt;code&gt;
platform = (defined?(JRUBY_VERSION) ? 'jruby/1.8' : 'ruby/1.9.1')
deps_dir = File.expand_path(&quot;deps/development/#{platform}/gems&quot;)

Dir[&quot;#{deps_dir}/**/lib&quot;].each { |d| $:.unshift(d) }
&lt;/code&gt;
&lt;/pre&gt;
&lt;/p&gt;
  &lt;/li&gt;


  &lt;li&gt;
    &lt;p&gt;Replace the default boot.rb code with a 'require &quot;deps/development&quot;':&lt;/p&gt;

&lt;p&gt;
&lt;pre&gt;
&lt;b&gt;&amp;lt;u&gt;boot.rb&amp;lt;/u&gt;&lt;/b&gt;
&lt;code&gt;
require 'deps/development'
&lt;/code&gt;
&lt;/pre&gt;
&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
  &lt;p&gt;
  Remove or comment the Bundler.require line in application.rb:
  &lt;/p&gt;

&lt;p&gt;
&lt;pre&gt;
&lt;b&gt;&amp;lt;u&gt;application.rb&amp;lt;/u&gt;&lt;/b&gt;
&lt;code&gt;
require File.expand_path('../boot', __FILE__)
require 'rails/all'

# BUNDLER is commented out!
# Bundler.require(:default, Rails.env) if defined?(Bundler)

module Warehouse
  class Application &amp;lt; Rails::Application
    config.encoding = &quot;utf-8&quot;
    config.filter_parameters += [:password]
  end
end
&lt;/code&gt;
&lt;/pre&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You're done!  To the benchmarks:&lt;/p&gt;

&lt;p&gt;
&lt;pre&gt;
&lt;b&gt;&amp;lt;u&gt;JRuby 1.5.3&amp;lt;/u&gt;&lt;/b&gt;
&lt;code&gt;
brasten@SilverBook ~/D/P/S/warehouse&gt; time rake report
(in /Users/brasten/Development/Projects/Scratch/warehouse)
                          user     system      total        real
application:          1.696000   0.000000   1.696000 (  1.696000)
rake:                 0.000000   0.000000   0.000000 (  0.000000)
load_tasks:           0.471000   0.000000   0.471000 (  0.471000)
                          user     system      total        real
Routes:               2.744000   0.000000   2.744000 (  2.744000)
Bundler  : NO
        &lt;b&gt;7.28 real&lt;/b&gt;        11.05 user         0.73 sys
&lt;/code&gt;
&lt;/pre&gt;
&lt;/p&gt;

&lt;p&gt;
Viola! Almost 30% reduction in startup time. This is essentially an empty project. In my experience, the more gems your application depends on the more dramatic a startup reduction you'll see.  I was able to reduced the startup time of a recent large-ish project by over 50%.
&lt;/p&gt;

&lt;p&gt;
For what it's worth, you get a barely noticeable improvement in 1.9.2 as well:
&lt;/p&gt;

&lt;p&gt;
&lt;pre&gt;
&lt;b&gt;&amp;lt;u&gt;Ruby 1.9.2&amp;lt;/u&gt;&lt;/b&gt;
&lt;code&gt;
brasten@SilverBook ~/D/P/S/warehouse&gt; time ruby -I. -S rake report
(in /Users/brasten/Development/Projects/Scratch/warehouse)
                          user     system      total        real
application:          0.300000   0.180000   0.480000 (  0.513892)
rake:                 0.000000   0.000000   0.000000 (  0.000045)
load_tasks:           0.050000   0.020000   0.070000 (  0.078305)
                          user     system      total        real
Routes:               0.840000   0.210000   1.050000 (  1.075324)
Bundler  : NO
        1.92 real         1.38 user         0.46 sys
&lt;/code&gt;
&lt;/pre&gt;
&lt;/p&gt;

&lt;h3&gt;Even More Awesomeness&lt;/h3&gt;
&lt;p&gt;
If your project requires even faster startup times, you can go even one step further.
&lt;/p&gt;

&lt;p&gt;
This is not a trivial change, but it can accomplish some impressive startup time reductions.
&lt;/p&gt;

&lt;p&gt;
Apparently, scanning the load_path for each required file is a relatively expensive operation in JRuby. One solution to this is simply to flatten your load path as much as possible.
&lt;/p&gt;

&lt;p&gt;
Not all gems behave well this way, so it can take some trial and error. You should be able to combine the load paths from *most* of your dependencies and keep the misbehaving gems separate.
&lt;/p&gt;

&lt;p&gt;
The steps are:
&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;
    Copy all files from each gem's &quot;lib&quot; directory into a single directory in your project. My directory is called &quot;deps/development/rap&quot; for irrelevant reasons.
    &lt;/p&gt;
  &lt;/li&gt;

  &lt;li&gt;
  &lt;p&gt;
    Create a bin/rake file. You'll use this to run rake:
    &lt;/p&gt;

&lt;p&gt;
&lt;pre&gt;
&lt;b&gt;&amp;lt;u&gt;bin/rake&amp;lt;/u&gt;&lt;/b&gt;
&lt;code&gt;
#!/usr/bin/env ruby
require 'deps/development'
require 'rake'
Rake.application.run
&lt;/code&gt;
&lt;/pre&gt;
&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;
Modify deps/development.rb to add your combined library directory to the load_path:
&lt;/p&gt;

&lt;p&gt;
&lt;pre&gt;
&lt;b&gt;&amp;lt;u&gt;deps/development.rb&amp;lt;/u&gt;&lt;/b&gt;
&lt;code&gt;
deps_dir = File.expand_path(&quot;deps/development/rap&quot;)
$:.unshift(deps_dir)
&lt;/code&gt;
&lt;/pre&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;
And that's it.  Benchmarks:
&lt;/p&gt;

&lt;p&gt;
&lt;pre&gt;
&lt;b&gt;&amp;lt;u&gt;JRuby 1.5.3&amp;lt;/u&gt;&lt;/b&gt;
&lt;code&gt;
brasten@SilverBook ~/D/P/S/warehouse&gt; time bin/rake report
(in /Users/brasten/Development/Projects/Scratch/warehouse)
                          user     system      total        real
application:          1.328000   0.000000   1.328000 (  1.328000)
rake:                 0.000000   0.000000   0.000000 (  0.000000)
load_tasks:           0.173000   0.000000   0.173000 (  0.173000)
                          user     system      total        real
Routes:               2.376000   0.000000   2.376000 (  2.376000)
Bundler  : NO
        &lt;b&gt;5.53 real&lt;/b&gt;         8.07 user         0.40 sys
&lt;/code&gt;
&lt;/pre&gt;
&lt;/p&gt;


&lt;p&gt;
Also interesting, the startup times for Ruby 1.9.2 are noticeably faster, too:
&lt;/p&gt;

&lt;p&gt;
&lt;pre&gt;
&lt;b&gt;&amp;lt;u&gt;Ruby 1.9.2&amp;lt;/u&gt;&lt;/b&gt;
&lt;code&gt;
brasten@SilverBook ~/D/P/S/warehouse&gt; time ruby -I. bin/rake report
(in /Users/brasten/Development/Projects/Scratch/warehouse)
                          user     system      total        real
application:          0.210000   0.100000   0.310000 (  0.324459)
rake:                 0.000000   0.000000   0.000000 (  0.000013)
load_tasks:           0.030000   0.010000   0.040000 (  0.037808)
                          user     system      total        real
Routes:               0.750000   0.170000   0.920000 (  0.908417)
Bundler  : NO
        1.40 real         1.08 user         0.31 sys
&lt;/code&gt;
&lt;/pre&gt;
&lt;/p&gt;

&lt;h3&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;
So, that's that.  You'll have to decide for yourself whether or not the extra effort is worth the reduced startup time.
&lt;/p&gt;

&lt;p&gt;
Ideally gem authors would ensure that their gems only depended on files on the load_path and would properly namespace their code.  The Bundler or some other tool could more easily automate packaging libraries into combined directories.
&lt;/p&gt;

&lt;p&gt;
Anyway, something to think about. 
&lt;/p&gt;

&lt;ol&gt;
  &lt;a /&gt;
  &lt;li&gt;Where &quot;sucks&quot; is roughly equivalent to a compile and relaunch of a Java app.  Not necessarily prohibitive, but as Ruby folk we've gotten used to instant gratification.&lt;/li&gt;
  &lt;a /&gt;
  &lt;li&gt;Benchmarks were ran on JRuby 1.5.3 and Ruby 1.9.2.  In general, I ran each benchmark ~10 times, tossed the first few and picked up the most common benchmark.  This is entirely informal, but I did run tests and select examples in good faith.  In any case, feel free to run the scenario yourself.&lt;/li&gt;
&lt;/ol&gt;
          </content>  </entry>
  <entry xml:base="http://www.ibrasten.com/">
    <author>
      <name>brasten</name>
    </author>
    <id>tag:www.ibrasten.com,2008-04-14:4668</id>
    <published>2008-04-14T10:49:00Z</published>
    <updated>2008-04-14T10:50:11Z</updated>
    <category term="ruby"/>
    <category term="scruffy"/>
    <link href="http://www.ibrasten.com/articles/2008/4/14/available-mildly-successful-open-source-project" rel="alternate" type="text/html"/>
    <title>Available: Mildly successful open-source project.</title>
<content type="html">
            &lt;p&gt;
It shouldn't surprise anyone to learn that I haven't been able to work on &lt;a href=&quot;http://scruffy.rubyforge.org&quot;&gt;Scruffy&lt;/a&gt; -- the Ruby-based SVG graphing engine -- in a very long time.  And yet, it seems like people continue to download and use it more and more.  Since my need for a graphing library is nonexistent for the foreseeable future, I don't think I'm the best person to continue working on Scruffy at this point.  Software is best written by those who need it.
&lt;/p&gt;
&lt;p&gt;
I do not intend on handing Scruffy to any random person, but if anyone out there thinks they can make a case for themselves you're welcome to &lt;a href=&quot;mailto:brasten@gmail.com&quot;&gt;contact me&lt;/a&gt;.  In general, I'm keeping an eye out for someone who &lt;strong&gt;has been using Scruffy professionally for some time&lt;/strong&gt; and has ideally &lt;strong&gt;already made significant code changes to Scruffy&lt;/strong&gt; for their projects.  
&lt;/p&gt;
&lt;p&gt;
I'd also like to find someone who has a similar vision for Scruffy as I do.  I never intended for Scruffy to be simply a Gruff replacement.  Gruff is good enough for what it does.  Today, most Scruffy usage involves rasterizing the SVG graph to an image.  At the time this was a necessary evil, but I think we're rapidly approaching a time when &lt;strong&gt;Scruffy could serve straight SVG&lt;/strong&gt;.  This is, I believe, the ultimate goal for Scruffy and opens a bunch of new possibilities ( layout and theming via CSS, dynamic graph updates via JavaScript, etc ).
&lt;/p&gt;
&lt;p&gt;
I'll be maintaining control of Scruffy for the foreseeable future as I'm not currently aware of anyone I'd trust to take it.  But I'd love to hear from anyone who thinks they may be that developer.
&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.ibrasten.com/">
    <author>
      <name>brasten</name>
    </author>
    <id>tag:www.ibrasten.com,2008-04-13:4655</id>
    <published>2008-04-13T20:27:00Z</published>
    <updated>2008-04-13T20:31:29Z</updated>
    <category term="merb"/>
    <category term="perl"/>
    <category term="rails"/>
    <category term="ruby"/>
    <link href="http://www.ibrasten.com/articles/2008/4/13/a-quick-summary-perl-and-merb" rel="alternate" type="text/html"/>
    <title>A quick summary: Perl and Merb</title>
<content type="html">
            &lt;p&gt;
There are quite a few little topics to catch up on since I've last posted, so I'm going to try and break them up into fewer, smaller posts.  This post is just a general overview of what I've been up to over the last few months.
&lt;/p&gt;

&lt;h3&gt;A brief detour into Perl-land&lt;/h3&gt;
&lt;p&gt;
Just over six months ago I took a contract working in Perl.  I had never worked in Perl and quite honestly had &lt;strong&gt;never intended on working in Perl&lt;/strong&gt;.  Still, the project sounded fun and I enjoy the opportunity to learn new [to me] things.  It also provided the opportunity to work for/with a guy who is basically the Perl version of Tobias L&amp;uuml;tke or Rick Olson.  It's difficult to turn down an opportunity to learn a new technology from one of the best that technology has to offer.
&lt;/p&gt;
&lt;p&gt;
Six months of Perl development later, I'm able to say that &lt;strong&gt;Perl doesn't suck&lt;/strong&gt; as much as I'd always thought.  The language itself is tricky, and this seems to have produced an awful lot of horrible Perl code &quot;out there.&quot;  I discovered, though, if you know how to write good Perl you can produce some decent looking code.  With the project soon coming to an end, I'm saddened that I'll not be able to continue using my newly-acquired skills.  Getting comfortable with Perl took me a little time, but I think I was just starting to [relatively] rock at it!  If the right opportunity came along, I would not be opposed to working in Perl again.
&lt;/p&gt;
&lt;p&gt;
My language-crush on Ruby did not disappear, however.  The mental separation of working in Perl and playing in Ruby gave me a chance to play with some personal projects in my spare time  -- free of the outside influences of a Ruby-based project.  All of which leads me to my second topic...
&lt;/p&gt;

&lt;h3&gt;Merb, Merb, the musical fruit...&lt;/h3&gt;
&lt;p&gt;
This isn't a very elegant way of putting it, but:  &lt;strong&gt;Merb. Kicks. Ass.&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
I had honestly begun to feel a bit disenchanted with Rails when I took the Perl project.  I quickly discovered that I was not as eager to build a random Rails application in my spare time when I no longer had any financial incentive to work with it.  I'm not complaining; I completely respect that &lt;em&gt;DHH did not develop Rails to make Brasten Sager happy&lt;/em&gt;.  Rails is what DHH needs it to be, and in my completely irrelevant opinion it's still the second-best framework for my purposes.
&lt;/p&gt;
&lt;p&gt;
This post is more of a personal narrative than any kind of technical article, so I'll skip the bullet-point list of &lt;em&gt;Reasons I Like Merb&lt;/em&gt;.  Instead, here's the one-paragraph explanation.  Every time I created a new Rails application I often ended up writing the same code (or copying from a previous project) to solve a whole list of minor annoyances.  Merb largely solves all those things for me right out of the box.  The Merb guys obviously write web applications the same way I do and they've written a framework that feels the way I want a framework to feel.
&lt;/p&gt;
&lt;p&gt;
Of course, your mileage may vary.
&lt;/p&gt;
&lt;p&gt;
More posts hopefully coming soon, stay tuned!
&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.ibrasten.com/">
    <author>
      <name>brasten</name>
    </author>
    <id>tag:www.ibrasten.com,2007-10-24:3069</id>
    <published>2007-10-24T20:07:00Z</published>
    <updated>2007-12-06T06:16:02Z</updated>
    <category term="textmate netbeans ruby themes"/>
    <link href="http://www.ibrasten.com/articles/2007/10/24/fadetogrey-netbeans-textmate-themes" rel="alternate" type="text/html"/>
    <title>FadeToGrey - NetBeans/TextMate themes</title>
<content type="html">
            &lt;p&gt;Heavily modified, but based on the &lt;a href=&quot;http://www.rubyrobot.org/article/rubyrobot-theme-for-textmate&quot;&gt;RubyRobot&lt;/a&gt; theme for TextMate (worth checking out).&lt;/p&gt; 

&lt;p&gt;HTML/XML colors are intentionally higher contrast than normal since, in my experience, I'm often looking for specific attributes/values or Ruby code.&lt;/p&gt;

&lt;p&gt;Slight differences between NetBeans and TextMate versions, obviously, due to different syntax colorization rules.  NetBeans pictured below:&lt;/p&gt;

&lt;img src=&quot;http://farm3.static.flickr.com/2327/1732727100_547cacc6de.jpg?v=0&quot; width=&quot;375&quot; /&gt;&lt;br /&gt;
&lt;img src=&quot;http://farm3.static.flickr.com/2186/1731873161_a228de3b2b.jpg?v=0&quot; width=&quot;375&quot; /&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;/com-superruby-netbeans-themes-fadetogrey.nbm&quot;&gt;FadeToGrey - NetBeans&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/FadeToGrey.tmTheme&quot;&gt;FadeToGrey - TextMate&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.ibrasten.com/">
    <author>
      <name>brasten</name>
    </author>
    <id>tag:www.ibrasten.com,2007-10-23:3059</id>
    <published>2007-10-23T18:22:00Z</published>
    <updated>2010-07-23T22:48:38Z</updated>
    <category term="rails java glassfish jruby netbeans"/>
    <link href="http://www.ibrasten.com/articles/2007/10/23/three-things-you-should-care-about" rel="alternate" type="text/html"/>
    <title>Three things you *should* care about...</title>
<content type="html">
            &lt;p&gt;The top three things Ruby developers SHOULD be paying attention to:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
&lt;b&gt;&lt;a href=&quot;http://jruby.codehaus.org/&quot;&gt;JRuby&lt;/a&gt;&lt;/b&gt;
&lt;p&gt;I have to admit, this one has surprised me.  I was a big fan of JRuby a while back, but not as a general-purpose Ruby runtime.  It was showing some promise as a niche integration project, but nobody was actually going to run Rails applications on it, right?&lt;/p&gt;
&lt;p&gt;Oops.&lt;/p&gt;
&lt;p&gt;Turns out, running a Rails application on JRuby is becoming more reasonable every day (more on that later).  JRuby is making huge leaps in performance and compatibility and, I believe, Ruby-to-bytecode compilation has the potential to be a game-changer.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
&lt;b&gt;&lt;a href=&quot;http://www.netbeans.org&quot;&gt;NetBeans&lt;/a&gt;&lt;/b&gt;
&lt;p&gt;I'm as big of a TextMate fan as the next guy.  One of my favorite side-effects of switching to Ruby was leaving my old Java IDEs behind.  Well, time has changed, and as of NetBeans 6 Beta 1 I've pretty much left TextMate behind.&lt;/p&gt;
&lt;p&gt;I'm not necessarily saying that you should switch to NetBeans TODAY...  but at the pace they're going, it's definitely something to keep your eye on in the near future.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
&lt;b&gt;&lt;a href=&quot;http://glassfish.dev.java.net&quot;&gt;GlassFish&lt;/a&gt;&lt;/b&gt;
&lt;p&gt;The fact is, current production Ruby/Rails options kind of suck.  Yes, it's as &quot;easy&quot; as &quot;mongrel_rails start&quot;, at first.  But then you need to set up a cluster of, let's say, 3 mongrels.  Then you need to proxy requests from Apache in some kind of load-balanced fashion which -- in many installations -- requires a separate application. Then you REALLY need to set up monit because, honestly, Mongrel doesn't stay up 24x7x52.&lt;/p&gt;
&lt;p&gt;Then what if one of them gets slashdotted (literally or figuratively)?  I had to run 8 Mongrels on one particular application just to keep it running during a traffic spike.  Now, the application's developers had NOT designed it for high-traffic, but regardless, it still took frantic manual intervention to keep it running.&lt;/p&gt;
&lt;p&gt;... now imagine a Rails server that requires only one instance running...  performant enough to bypass Apache in many cases...  capable of scaling up or down the number of Rails threads running based on traffic levels, automatically... can do all of this for any number of Rails applications you wish to deploy, and comes with a pretty nifty web console to administrate it all (if desired).&lt;/p&gt;
&lt;p&gt;That's the promise of Rails on GlassFish v3.  It's still a ways off, but you'd be doing yourself a favor to start thinking about it now.&lt;/p&gt;
  &lt;/li&gt;

&lt;/ol&gt;
          </content>  </entry>
  <entry xml:base="http://www.ibrasten.com/">
    <author>
      <name>brasten</name>
    </author>
    <id>tag:www.ibrasten.com,2007-07-20:1465</id>
    <published>2007-07-20T15:55:00Z</published>
    <updated>2008-05-29T10:41:32Z</updated>
    <category term="apple"/>
    <link href="http://www.ibrasten.com/articles/2007/7/20/apple-hp" rel="alternate" type="text/html"/>
    <title>Apple &gt;= HP?</title>
<content type="html">
            Has anyone else noticed that AAPL is dangerously close to surpassing HPQ?  $121 billion to $126 billion as of this morning.
          </content>  </entry>
  <entry xml:base="http://www.ibrasten.com/">
    <author>
      <name>brasten</name>
    </author>
    <id>tag:www.ibrasten.com,2007-06-19:732</id>
    <published>2007-06-19T19:59:00Z</published>
    <updated>2007-09-24T23:37:40Z</updated>
    <category term="rails edge"/>
    <link href="http://www.ibrasten.com/articles/2007/6/19/edge-report-with_scope-protected" rel="alternate" type="text/html"/>
    <title>Edge report: with_scope protected</title>
<content type="html">
            &lt;p&gt;I knew all along that using with_scope outside my models was a bad idea, but I did it anyway.  So once this little change came through, I had to rethink some of my code&#8230;  &lt;/p&gt;

&lt;p&gt;Just to throw this out there &#8211; let&#8217;s &lt;a href=&quot;http://www.robbyonrails.com/articles/2007/06/18/rails-code-audits-and-reviews-continued&quot;&gt;call it peer-review&lt;/a&gt; &#8211; my new method of encapsulating with_scope usages sort of piggy-backs on &lt;a href=&quot;http://blog.imperialdune.com/2007/4/19/find-methods-in-controllers&quot;&gt;finder encapsulation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Take, for example, the following code:&lt;/p&gt;

&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;cl&quot;&gt;Post&lt;/span&gt; &amp;lt; &lt;span class=&quot;co&quot;&gt;ActiveRecord&lt;/span&gt;::&lt;span class=&quot;co&quot;&gt;Base&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;pc&quot;&gt;self&lt;/span&gt;.find_active&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;c&quot;&gt;# ... some finder code to return all active posts&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;cl&quot;&gt;PostsController&lt;/span&gt; &amp;lt; &lt;span class=&quot;co&quot;&gt;ApplicationController&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;index&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;iv&quot;&gt;@posts&lt;/span&gt; = &lt;span class=&quot;co&quot;&gt;Post&lt;/span&gt;::find_active&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;&#8230; despite my habit of encapsulating finders, I still found myself doing this:&lt;/p&gt;

&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;  &lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;c&quot;&gt;# In around-filter or action&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;co&quot;&gt;Post&lt;/span&gt;::with_scope( ... conditions ... ) &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;c&quot;&gt;# ... yield or something&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;&#8211; Obviously, BAD.  So the alternative is to do something like Post::scope_by_active or something.  What about adding a fairly simple block_given? condition to the existing find_active method? Use your imagination on the implementation of that, but the usage would now look something like this:&lt;/p&gt;

&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;  &lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;c&quot;&gt;# No block, returns all active&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;iv&quot;&gt;@posts&lt;/span&gt; = &lt;span class=&quot;co&quot;&gt;Post&lt;/span&gt;::find_active&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;c&quot;&gt;# block, scopes to active, returns result of block.&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;iv&quot;&gt;@my_posts&lt;/span&gt; = &lt;span class=&quot;co&quot;&gt;Post&lt;/span&gt;::find_active &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;              &lt;span class=&quot;co&quot;&gt;Post&lt;/span&gt;::find_by_user( user )&lt;tt&gt;
&lt;/tt&gt;            &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;Soooo&#8230;  peer-review away!&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.ibrasten.com/">
    <author>
      <name>brasten</name>
    </author>
    <id>tag:www.ibrasten.com,2007-06-06:612</id>
    <published>2007-06-06T22:53:00Z</published>
    <updated>2008-05-29T10:42:11Z</updated>
    <category term="cbs"/>
    <category term="jericho"/>
    <category term="map"/>
    <link href="http://www.ibrasten.com/articles/2007/6/6/cbs-revives-jericho" rel="alternate" type="text/html"/>
    <title>CBS revives Jericho!</title>
<content type="html">
            &lt;p&gt;Impressive campaign &#8211; I put together a little Yahoo Maps illustration with the location and amounts of most of the contributions to &lt;a href=&quot;http://www.nutsonline.com&quot;&gt;NutsOnline.com&lt;/a&gt;&#8217;s &lt;a href=&quot;http://www.nutsonline.com/jericho&quot;&gt;Save Jericho&lt;/a&gt; campaign.  The live version &lt;a href=&quot;http://www.ibrasten.com/jericho-map.html&quot;&gt;can be seen here.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Well done everyone!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://farm2.static.flickr.com/1019/533737212_17efd64324.jpg?v=0&quot; /&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.ibrasten.com/">
    <author>
      <name>brasten</name>
    </author>
    <id>tag:www.ibrasten.com,2007-06-01:583</id>
    <published>2007-06-01T04:55:00Z</published>
    <updated>2007-09-24T23:38:42Z</updated>
    <category term="rails rspec bdd"/>
    <link href="http://www.ibrasten.com/articles/2007/6/1/effectively-communicating-your-expectations" rel="alternate" type="text/html"/>
    <title>Effectively communicating your expectations</title>
<content type="html">
            &lt;p&gt;So, if you&#8217;ve tried RSpec, you know it let&#8217;s you write test code that&#8217;s easy to understand.  There are other reasons for BDD, but that is probably the first one you&#8217;ll notice.  Describe this, it should do that, this should not have five of those, etc etc.  It&#8217;s great for less assertive people like myself.&lt;/p&gt;

&lt;p&gt;Occasionally, you&#8217;ll run into situations that are not easily described with the stock RSpec API.  The RSpec guys have done a fantastic job putting together an API that is easy to manipulate, so don&#8217;t be afraid to do that!&lt;/p&gt;

&lt;p&gt;Let&#8217;s look at an example:&lt;/p&gt;

&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;describe &lt;span class=&quot;co&quot;&gt;TicketsController&lt;/span&gt;, &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;with unauthenticated visitor&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  it &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;should require login to access /index&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    get &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;c&quot;&gt;# This is the line I'll be picking on.&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    response.should redirect_to( &lt;span class=&quot;sy&quot;&gt;:controller&lt;/span&gt; =&amp;gt; &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;sy&quot;&gt;:action&lt;/span&gt; =&amp;gt; &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;login&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt; )&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;Pretty basic, right?  But here&#8217;s the part that bugs me: &lt;strong&gt;it &#8220;should require login to access /index&#8221;&lt;/strong&gt; vs. &lt;strong&gt;response.should redirect_to( :controller =&amp;gt; &#8216;account&#8217;, :action =&amp;gt; &#8216;login&#8217; )&lt;/strong&gt;.  &lt;/p&gt;

&lt;p&gt;The expectation I&#8217;ve described in english is not the same as the expectation I&#8217;ve described in code.  Redirecting to a login page is a function of the before_filter handling your app&#8217;s security, not of the TicketsController itself.&lt;/p&gt;

&lt;p&gt;In english, my expectation is pretty clear: &#8216;it should require login&#8217;.  So let&#8217;s make the code match.&lt;/p&gt;

&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;describe &lt;span class=&quot;co&quot;&gt;TicketsController&lt;/span&gt;, &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;with unauthenticated visitor&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  it &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;should require login to access /index&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    get &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;c&quot;&gt;# Doesn't this make a lot more sense??&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    response.should require_login&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;Turns out, this is shockingly easy to accomplish:&lt;/p&gt;

&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;c&quot;&gt;# Add this to your spec_helper.rb or another required file&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;cl&quot;&gt;Spec::Rails::Matchers&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;require_login&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;co&quot;&gt;RedirectTo&lt;/span&gt;.new(request, { &lt;span class=&quot;sy&quot;&gt;:controller&lt;/span&gt; =&amp;gt; &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;sy&quot;&gt;:action&lt;/span&gt; =&amp;gt; &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;login&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt; })&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;And there you go.  Requiring a login is now an expectation on the same level as all others.  It&#8217;s really very cool!  &lt;/p&gt;

&lt;p&gt;Additionally, this ALMOST gets us the negative expectation ( &#8220;response.should_not require_login&#8221; ).  There&#8217;s a very minor tweak needed to get that working, but that&#8217;s an exercise I&#8217;ll leave to you.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you don&#8217;t want to figure it out, I can be bribed with gift cards to Caffe Ladro for as little as $5.  =)&lt;/em&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.ibrasten.com/">
    <author>
      <name>brasten</name>
    </author>
    <id>tag:www.ibrasten.com,2007-05-27:556</id>
    <published>2007-05-27T05:07:00Z</published>
    <updated>2008-05-29T10:42:18Z</updated>
    <category term="jericho"/>
    <category term="railsconf"/>
    <category term="railsconf07"/>
    <link href="http://www.ibrasten.com/articles/2007/5/27/25lbs-of-nuts-for-jericho" rel="alternate" type="text/html"/>
    <title>~25lbs of nuts for Jericho!</title>
<content type="html">
            &lt;p&gt;The Fremont office-mates contributed $30 to the NutsOnline Jericho pool.  NutsOnline is shipping packaged nuts to CBS in a fan-organized effort to save Jericho.  Some 20,000 pounds have been shipped thus far.  If you&#8217;re a Jericho fan, why not &lt;a href=&quot;http://www.nutsonline.com/jericho&quot;&gt;pitch in&lt;/a&gt;??&lt;/p&gt;

&lt;p&gt;Though I&#8217;m very much a fan of this show, it does need to be kept in perspective.  If you&#8217;re considering donating to the Jericho pool and haven&#8217;t yet contributed to one of the RailsConf charities, please &lt;a href=&quot;http://pragmaticstudio.com/donate/&quot;&gt;donate there first&lt;/a&gt;.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.ibrasten.com/">
    <author>
      <name>brasten</name>
    </author>
    <id>tag:www.ibrasten.com,2007-05-20:514</id>
    <published>2007-05-20T07:24:00Z</published>
    <updated>2007-09-24T23:38:52Z</updated>
    <category term="railsconf railsconf2007"/>
    <link href="http://www.ibrasten.com/articles/2007/5/20/rejectconf-was-worth-the-railsconf-fee" rel="alternate" type="text/html"/>
    <title>RejectConf was worth the RailsConf fee...</title>
<content type="html">
            &lt;p&gt;&#8230; moreso than RailsConf has been.  The issues with RailsConf have been and will continue to be well documented, but the RejectConf guys kicked ass!&lt;/p&gt;

&lt;p&gt;I had to jet afterwards, but those of you wanting to chat, catch me at the conference tomorrow.&lt;/p&gt;

&lt;p&gt;On a final note, after weeks of attempting to find a Nintendo Wii in Seattle, I was able to track one down here in Portland!!  Awesome machine!!  It&#8217;s hooked up in the hotel room now, and in fact, this entire post was created from the Wii&#8217;s browser.  =)&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.ibrasten.com/">
    <author>
      <name>brasten</name>
    </author>
    <id>tag:www.ibrasten.com,2007-05-18:500</id>
    <published>2007-05-18T00:14:00Z</published>
    <updated>2008-05-29T10:42:31Z</updated>
    <category term="jericho"/>
    <category term="nuclear"/>
    <category term="war"/>
    <link href="http://www.ibrasten.com/articles/2007/5/18/any-other-closet-jericho-fans" rel="alternate" type="text/html"/>
    <title>Any other closet 'Jericho' fans?</title>
<content type="html">
            &lt;p&gt;Jericho canceled.  Unbelievable.&lt;/p&gt;

&lt;p&gt;I think I&#8217;m done watching TV.  Good shows don&#8217;t stand a chance anymore.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.ibrasten.com/">
    <author>
      <name>brasten</name>
    </author>
    <id>tag:www.ibrasten.com,2007-05-17:497</id>
    <published>2007-05-17T22:17:00Z</published>
    <updated>2008-05-29T10:42:46Z</updated>
    <category term="baseball"/>
    <link href="http://www.ibrasten.com/articles/2007/5/17/ode-to-baseball-2" rel="alternate" type="text/html"/>
    <title>Ode to Baseball</title>
<content type="html">
            &lt;p&gt;Google &#8220;Ode to Baseball.&#8221;&lt;/p&gt;

&lt;p&gt;I&#8217;m #5!&lt;/p&gt;

&lt;p&gt;Awesome.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.ibrasten.com/">
    <author>
      <name>brasten</name>
    </author>
    <id>tag:www.ibrasten.com,2007-05-16:487</id>
    <published>2007-05-16T22:46:00Z</published>
    <updated>2008-05-29T10:42:56Z</updated>
    <category term="railsconf"/>
    <category term="railsconf2007"/>
    <link href="http://www.ibrasten.com/articles/2007/5/16/railsconf" rel="alternate" type="text/html"/>
    <title>RailsConf!</title>
<content type="html">
            &lt;p&gt;I&#8217;ll be heading on down to Portland in a little over a day for RailsConf!&lt;/p&gt;

&lt;p&gt;If you&#8217;re there, track me down and say hi!  If there are any hacking sessions planned, maybe I&#8217;ll take the opportunity to hack on Scruffy.&lt;/p&gt;

&lt;p&gt;I also plan on picking up a new MacBook while I&#8217;m there!  So, a lot of stuff to fit into a few days.  Should be fun!&lt;/p&gt;
          </content>  </entry>
</feed>

