<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[Prioritized.net]]></title>
  <link href="http://prioritized.net/atom.xml" rel="self"/>
  <link href="http://prioritized.net/"/>
  <updated>2012-01-20T11:43:48-05:00</updated>
  <id>http://prioritized.net/</id>
  <author>
    <name><![CDATA[Derek Prior]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Gemify Assets for Rails]]></title>
    <link href="http://prioritized.net/blog/gemify-assets-for-rails/"/>
    <updated>2012-01-11T15:47:00-05:00</updated>
    <id>http://prioritized.net/blog/gemify-assets-for-rails</id>
    <content type="html"><![CDATA[<p>The <a href="http://guides.rubyonrails.org/asset_pipeline.html">asset pipeline</a>, introduced with Rails 3.1, makes it simple to include versioned external assets as application dependencies. Provided those assets are packaged as Ruby gems, the process is as simple as adding the gem to your <code>Gemfile</code>, running <code>bundle install</code> and, in the case of CSS and JavaScript, adding a require to the proper manifest file.</p>

<p>Many popular CSS frameworks and JavaScript libraries are already available as gems. Search <a href="https://rubygems.org">RubyGems</a> to see if the assets you&#8217;re interested in are already packaged this way. What if the JavaScript library you use isn&#8217;t yet available as a gem? Packaging and publishing asset gems is simple. Here&#8217;s your chance.</p>

<!-- more -->


<p>External assets are made available in Rails via <a href="http://railscasts.com/episodes/277-mountable-engines">Rails engines</a>. When the engine is loaded into your Rails application, the engine&#8217;s asset paths are added to your application&#8217;s load paths. This makes them available for require in your manifest files. An asset gem is just an absurdly simple engine. As an example, I&#8217;ll walk you through the process I recently took for <a href="https://github.com/derekprior/momentjs-rails">momentjs-rails</a>. The process is wordy, but it&#8217;s really pretty simple.</p>

<h2>Create Gem Framework</h2>

<p>Bundler makes it simple to create the files and folders necessary for creating a gem. Run the following command to create and initialize a Git repository along with several template files for the gem.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>bundle gem momentjs-rails
</span></code></pre></td></tr></table></div></figure>


<h2>Versioning</h2>

<p>In this case, momentjs-rails is a gem packaged version of the <a href="http://momentjs.com">Moment.js</a> library. Its version should track the version of JavaScript library it wraps, which is currently 1.3.0. Open <code>lib/momentjs-rails/version.rb</code> and set the version like so:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">module</span> <span class="nn">Momentjs</span>
</span><span class='line'>  <span class="k">module</span> <span class="nn">Rails</span>
</span><span class='line'>    <span class="no">VERSION</span> <span class="o">=</span> <span class="s2">&quot;1.3.0&quot;</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>In the event that you need to push an update to your gem that does not change the version of the assets it wraps, I would investigate adding a fourth value to the version string (<code>1.3.0.1</code>).</p>

<h2>Start Your Engine</h2>

<p>Bundler created the gem as a standard Ruby module, but we want it to be a Rails engine. Edit <code>lib/momentjs-rails.rb</code> to subclass <code>Rails::Engine</code> like so:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="nb">require</span> <span class="s2">&quot;momentjs-rails/version&quot;</span>
</span><span class='line'>
</span><span class='line'><span class="k">module</span> <span class="nn">Momentjs</span>
</span><span class='line'>  <span class="k">module</span> <span class="nn">Rails</span>
</span><span class='line'>    <span class="k">class</span> <span class="nc">Engine</span> <span class="o">&lt;</span> <span class="o">::</span><span class="no">Rails</span><span class="o">::</span><span class="no">Engine</span>
</span><span class='line'>    <span class="k">end</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>Yes, the class is empty on purpose. All we&#8217;re doing here is declaring the gem as an engine. This will cause rails to add its directories to the load path when the gem is required.</p>

<h2>Add The Assets</h2>

<p>Download the asset files you want to include in the gem. If availble, I prefer to use the uncompressed, non-minified versions. They&#8217;ll actually be readable if you need to dig into them and you can rely on the asset pipeline to minify them in production or on precompilation. In the case of the Moment.js library, I downloaded the release version to my desktop and ran the following commands:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>mkdir -p vendor/assets/javascripts
</span><span class='line'><span class="nv">$ </span>cp ~/Downloads/moment.js vendor/assets/javascripts/moment.js
</span></code></pre></td></tr></table></div></figure>


<p>I used the <code>vendor/assets</code> directory here because these aren&#8217;t assets I&#8217;m maintaining directly. If they were assets I was responsible for maintaining, I would put them in <code>app/assets</code> though the difference is purely semantic.</p>

<h2>Complete The Gemspec</h2>

<p>The <code>momentjs-rails.gemspec</code> file contains all of the details that describe the gem. Open it up and complete any pending <code>TODO</code>s left by Bundler. I usually set the homepage to the GitHub repository for the gem. Additionally, I removed the <code>gem.executables</code> and <code>gem.test_files</code> lines, as this gem has neither. I also prefer to change the <code>gem.files</code> setting to avoid shelling out to git. I used the following pure-ruby implementation instead:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">gem</span><span class="o">.</span><span class="n">files</span> <span class="o">=</span> <span class="no">Dir</span><span class="o">[</span><span class="s2">&quot;{lib,vendor}/**/*&quot;</span><span class="o">]</span> <span class="o">+</span> <span class="o">[</span><span class="s2">&quot;MIT-LICENSE&quot;</span><span class="p">,</span> <span class="s2">&quot;README.md&quot;</span><span class="o">]</span>
</span></code></pre></td></tr></table></div></figure>


<p>Railties needs to be declared as a dependency of the gem. Our gem needs Rails 3.1 or greater, but we&#8217;ll stop short of 4.0 for now. Use the following setting:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">gem</span><span class="o">.</span><span class="n">add_dependency</span> <span class="s2">&quot;railties&quot;</span><span class="p">,</span> <span class="s2">&quot;~&gt; 3.1&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<h2>Build and Test</h2>

<p>Bundler set up some default rake tasks for us that save a few characters when building. Simply run <code>rake build</code> to build the gem.</p>

<p>I haven&#8217;t included any specs with this gem. Full-featured engines usually have a dummy Rails application in the test directory that loads the engine and can be used to run tests. While this would work to test the asset gem, I haven&#8217;t set this up yet. Instead, I generally do the following:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>rails new momentjs-test
</span><span class='line'><span class="nv">$ </span><span class="nb">cd </span>momentjs-test
</span><span class='line'><span class="nv">$ </span><span class="nb">echo</span> <span class="s1">&#39;gem &quot;momentjs-rails&quot;, :path =&gt; &quot;/Absolute/Path/To/Gem/Directory&quot;&#39;</span> &gt;&gt; Gemfile
</span><span class='line'><span class="nv">$ </span>bundle install
</span><span class='line'><span class="nv">$ </span><span class="nb">echo</span> <span class="s1">&#39;//= require moment&#39;</span> &gt;&gt; app/assets/javascripts/application.js
</span><span class='line'><span class="nv">$ </span>rails server &amp;
</span><span class='line'><span class="nv">$ </span>curl http://localhost:3000/assets/moment.js
</span><span class='line'><span class="nv">$ </span><span class="nb">fg</span>
</span><span class='line'>&lt;ctrl-c&gt;
</span></code></pre></td></tr></table></div></figure>


<p>That&#8217;s quite the little dance, but the <code>curl</code> command should return the contents of the moment.js file if everything is wired up correctly.</p>

<h2>README</h2>

<p>I included a very simple readme file with the Gem as its sole documentation. I brifely described Moment.js, supplied simple usage instructions, and a word about versioning. See the <a href="https://github.com/derekprior/momentjs-rails/blob/master/README.md">momentjs-rails readme</a>.</p>

<h2>Push To GitHub and RubyGems</h2>

<p>Create a GitHub repository for your project, stage all of your commits, commit, and push the code to GitHub.</p>

<p>If you&#8217;ve never published a gem on RubyGems before, you&#8217;ll need to sign up for an account there. Your account settings will contain an API key that should be copied to <code>~/.gem/credentials</code>. Once that&#8217;s done, publishing your gem is as simple as:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>rake release
</span></code></pre></td></tr></table></div></figure>


<p>This will create a Git tag for this version, and push the built gem to RubyGems.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Simple Navigation in Rails]]></title>
    <link href="http://prioritized.net/blog/simple-navigation-in-rails/"/>
    <updated>2011-12-30T15:41:00-05:00</updated>
    <id>http://prioritized.net/blog/simple-navigation-in-rails</id>
    <content type="html"><![CDATA[<p>Most web applications call for at least one level of navigational structure. Many will have two or more levels and require the active node in each level to have distinct styling via an <code>active</code> class. I&#8217;ve seen as many navigation solutions as I&#8217;ve seen rails projects. Most look similar in that each level of navigation is represented by a partial. Some track the active node via local variables passed with the call to <code>render</code>, but this approach isn&#8217;t very DRY. Some track the active node via instance variables on the controller, but this is a painful violation of MVC which gets especially tedious to maintain in multilevel scenarios.</p>

<p>Thankfully, there&#8217;s a mature, simple, and actively maintained solution just a gem away. <a href="https://github.com/andi/simple-navigation">Simple Navigation</a> handles just about whatever you can throw at it. I was surprised, however, by how hard it was to unearth when I was looking for the solution to my navigational troubles.  It&#8217;s an elegant solution that deserves more attention.</p>

<!-- More -->


<p>With Simple Navigation, the application&#8217;s entire navigational structure is contained in a single configuration file. The configration is specified in a simple DSL that allows for multiple levels of navigation. You can render the entire structure, with appropriate sub menus with a call to <code>render_navigation</code> or you can render each level explicitly with calls to <code>render_navigation :level =&gt; 2</code>. There is, of course, support for configuring the exact classes, elements, and ids used in the HTML.</p>

<p>Active item tracking can be done automatically, which works surprisingly well in basic cases. Alternatively, you can supply a regular expression or proc to determin which item should be tracked as active. If your navigation has more than one level, then the parent of an active item will also be marked as active.</p>

<p>The <a href="https://github.com/andi/simple-navigation/wiki">project wiki</a> has good documentation for most features. There are a lot of options, but the configration is still easily understood. For instance, here&#8217;s a chunk of the configuration for my current project. The navigation features a static top bar with any applicable secondary menu rendered as tabs below. The entire &#8216;Admin&#8217; menu is visible only to users who are administrators.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="no">SimpleNavigation</span><span class="o">::</span><span class="no">Configuration</span><span class="o">.</span><span class="n">run</span> <span class="k">do</span> <span class="o">|</span><span class="n">navigation</span><span class="o">|</span>
</span><span class='line'>  <span class="n">navigation</span><span class="o">.</span><span class="n">autogenerate_item_ids</span> <span class="o">=</span> <span class="kp">false</span>
</span><span class='line'>  <span class="n">navigation</span><span class="o">.</span><span class="n">selected_class</span> <span class="o">=</span> <span class="s1">&#39;active&#39;</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">navigation</span><span class="o">.</span><span class="n">items</span> <span class="k">do</span> <span class="o">|</span><span class="n">primary</span><span class="o">|</span>
</span><span class='line'>    <span class="n">primary</span><span class="o">.</span><span class="n">item</span> <span class="ss">:schedule</span><span class="p">,</span> <span class="s1">&#39;Schedule&#39;</span><span class="p">,</span> <span class="n">schedules_path</span>
</span><span class='line'>    <span class="n">primary</span><span class="o">.</span><span class="n">item</span> <span class="ss">:admin</span><span class="p">,</span> <span class="s1">&#39;Admin&#39;</span><span class="p">,</span> <span class="n">admin_root_path</span><span class="p">,</span> <span class="ss">:if</span> <span class="o">=&gt;</span> <span class="no">Proc</span><span class="o">.</span><span class="n">new</span> <span class="p">{</span> <span class="n">current_user</span><span class="o">.</span><span class="n">administrator?</span> <span class="p">}</span> <span class="k">do</span> <span class="o">|</span><span class="n">admin</span><span class="o">|</span>
</span><span class='line'>      <span class="n">admin</span><span class="o">.</span><span class="n">item</span> <span class="ss">:admin_shifts</span><span class="p">,</span> <span class="s1">&#39;Shifts&#39;</span><span class="p">,</span> <span class="n">admin_shifts_path</span><span class="p">,</span> <span class="ss">:highlights_on</span> <span class="o">=&gt;</span> <span class="sr">/admin\/?$|admin\/shifts/i</span>
</span><span class='line'>      <span class="n">admin</span><span class="o">.</span><span class="n">item</span> <span class="ss">:admin_responsibilities</span><span class="p">,</span> <span class="s1">&#39;Responsibilities&#39;</span><span class="p">,</span> <span class="n">admin_responsibilities_path</span><span class="p">,</span> <span class="ss">:highlights_on</span> <span class="o">=&gt;</span> <span class="ss">:subpath</span>
</span><span class='line'>      <span class="n">admin</span><span class="o">.</span><span class="n">item</span> <span class="ss">:admin_locations</span><span class="p">,</span> <span class="s1">&#39;Locations&#39;</span><span class="p">,</span> <span class="n">admin_locations_path</span><span class="p">,</span> <span class="ss">:highlights_on</span> <span class="o">=&gt;</span> <span class="ss">:subpath</span>
</span><span class='line'>      <span class="n">admin</span><span class="o">.</span><span class="n">item</span> <span class="ss">:admin_holiday_schedules</span><span class="p">,</span> <span class="s1">&#39;Holidays&#39;</span><span class="p">,</span> <span class="n">admin_holiday_schedules_path</span><span class="p">,</span> <span class="ss">:highlights_on</span> <span class="o">=&gt;</span> <span class="ss">:subpath</span>
</span><span class='line'>      <span class="n">admin</span><span class="o">.</span><span class="n">item</span> <span class="ss">:admin_users</span><span class="p">,</span> <span class="s1">&#39;Users&#39;</span><span class="p">,</span> <span class="n">admin_users_path</span><span class="p">,</span> <span class="ss">:highlights_on</span> <span class="o">=&gt;</span> <span class="ss">:subpath</span>
</span><span class='line'>      <span class="n">admin</span><span class="o">.</span><span class="n">dom_class</span> <span class="o">=</span> <span class="s1">&#39;tabs span16&#39;</span>
</span><span class='line'>    <span class="k">end</span>
</span><span class='line'>    <span class="n">primary</span><span class="o">.</span><span class="n">item</span> <span class="ss">:preferences</span><span class="p">,</span> <span class="s1">&#39;Preferences&#39;</span><span class="p">,</span> <span class="n">preferences_path</span>
</span><span class='line'>    <span class="n">primary</span><span class="o">.</span><span class="n">item</span> <span class="ss">:help</span><span class="p">,</span> <span class="s1">&#39;Help&#39;</span><span class="p">,</span> <span class="n">help_path</span>
</span><span class='line'>    <span class="n">primary</span><span class="o">.</span><span class="n">dom_class</span> <span class="o">=</span> <span class="s1">&#39;nav&#39;</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>Check out Simple Navigation for use in your Rails projects. It&#8217;s simple, powerful, and DRY.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Upgrading Vim on OS X]]></title>
    <link href="http://prioritized.net/blog/upgrading-vim-on-os-x/"/>
    <updated>2011-12-22T10:52:00-05:00</updated>
    <id>http://prioritized.net/blog/upgrading-vim-on-os-x</id>
    <content type="html"><![CDATA[<p>Mac OS X ships with a console version of Vim, but it is outdated and it was not compiled with Ruby or Python support. <a href="https://wincent.com/products/command-t">Command-T</a>, for one, requires vim to be compiled with Ruby support and thus will not work with the version of Vim shipped with the operating system.  You may also have configuration settings in your <code>.vimrc</code> that are incompatible with Vim 7.2. Thankfully, there are a few rather simple options for updating Vim.</p>

<!-- more -->


<h2>Simplest: Homebrew built MacVim</h2>

<p> <a href="http://mxcl.github.com/homebrew/">Homebrew</a> is my favorite OS X package manager. If you&#8217;re not familiar with Homebrew, you should check it out. You can use Homebrew to install MacVim, which includes both a GUI and console version of Vim 7.3. Passing a simple flag to <code>brew install</code> will instruct homebrew to setup the necessary symlinks to replace the system console Vim with the version provided by MacVim.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>brew install macvim --override-system-vim
</span><span class='line'>
</span><span class='line'><span class="c"># If you need the app bundle linked in /Applications...</span>
</span><span class='line'><span class="nv">$ </span>brew linkapps
</span></code></pre></td></tr></table></div></figure>


<p><strong>Note</strong>: Please see the caveat below concerning building Vim</p>

<h2>Simple: Homebrew built Vim</h2>

<p>If you don&#8217;t want the version of Vim shipped with MacVim, you can build Vim directly from source, also using Homebrew. Homebrew does not include a formula for Vim in its official repository as that would be counter to its (occasionally broken) <a href="https://github.com/mxcl/homebrew/wiki/Acceptable-Formula">rule</a> to not provide system duplicates. There&#8217;s a <a href="https://raw.github.com/adamv/homebrew-alt/master/duplicates/vim.rb">formula</a> in the <a href="https://github.com/adamv/homebrew-alt">homebrew-alt</a> repository that will get the job done in just a few short steps, however.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="c"># mercurial required - install if you don&#39;t already have it.</span>
</span><span class='line'><span class="nv">$ </span>brew install mercurial
</span><span class='line'>
</span><span class='line'><span class="c"># install Vim from homebrew-alt</span>
</span><span class='line'><span class="nv">$ </span>brew install https://raw.github.com/adamv/homebrew-alt/master/duplicates/vim.rb
</span><span class='line'>
</span><span class='line'><span class="c"># if /usr/bin is before /usr/local/bin in your $PATH,</span>
</span><span class='line'><span class="c"># hide the system Vim so the new version is found first</span>
</span><span class='line'><span class="nv">$ </span>sudo mv /usr/bin/vim /usr/bin/vim72
</span><span class='line'>
</span><span class='line'><span class="c"># should return /usr/local/bin/vim</span>
</span><span class='line'><span class="nv">$ </span>which vim
</span></code></pre></td></tr></table></div></figure>


<p><strong>Note</strong>: Please see the caveat below concerning building Vim</p>

<h2>Without Homebrew</h2>

<p>If you&#8217;re interested in Vim, I&#8217;m guessing you&#8217;re also fully capable of using a package manager, but if you want to do this quickly and without involving Homebrew and without running afoul of the caveat below, you can download and install the <a href="http:code.google.com/p/macvim">MacVim</a> app bundle  and setup an alias to point to its version of Vim. Assuming you have MacVim installed to <code>/Applications/</code>, you can add the folowing to <code>~/.bash_profile</code> or other appropriate configuration file.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span><span class="nb">alias </span><span class="nv">vim</span><span class="o">=</span><span class="s2">&quot;/Applications/MacVim.app/Contents/MacOS/Vim&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<h2>Caveat: Locally Built Vim</h2>

<p>If you build Vim locally via Homebrew or any other method and you use <a href="http://rvm.beginrescueend.com">RVM</a> or <a href="https://github.com/sstephenson/rbenv">rbenv</a> to manage multiple rubies, you should be sure to switch to the system installed Ruby when building Vim and any compiled plugins (such as Command-T). If you build Vim against one Ruby and Command-T against another, the penalty will be a SegFault when launching Vim. In that case, rebuild both against a consistent Ruby.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Embracing Promiscuous Gemfiles]]></title>
    <link href="http://prioritized.net/blog/embracing-promiscuous-gemfiles/"/>
    <updated>2011-12-13T16:42:00-05:00</updated>
    <id>http://prioritized.net/blog/embracing-promiscuous-gemfiles</id>
    <content type="html"><![CDATA[<p><a href="http://gembundler.com">Bundler</a> has been around for quite some time now, but I continue to see what I consider to be be bad advice with regards to specifying version constraints in your project <code>Gemfile</code>. My position is simple: <strong>Do not constrain gem versions in your Gemfile until you have a good reason to do so</strong>.  I typically encounter two arguments against this position. The first is misinformed, showing a critical lack of understanding of how bundler works. The second is a defensible position, but seems to offer no advantage over my approach.</p>

<!-- more -->


<h3>Specific Versions For Everything!</h3>

<p>Developers in the first camp routinely lock gems down to specific versions (<code>'3.1.0'</code>) They argue that this ensures all developers and all deployment environments run the same version of the project&#8217;s dependencies. While this is true for direct dependencies listed in the <code>Gemfile</code>, it is not true for the dependencies of those dependencies. This position shows a fundamental misunderstanding of how bundler works. The complete versioning picture is maintained by bundler in <code>Gemfile.lock</code>, which is generated when <code>bundle install</code> is run for the first time. Subsequent runs of <code>bundle install</code> install only the exact versions listed in <code>Gemfile.lock</code>. This is why it&#8217;s critical that <code>Gemfile.lock</code> be checked into source control. It&#8217;s <code>Gemfile.lock</code> &#8211; and not <code>Gemfile</code> &#8211; that provides complete consistency across deployments.</p>

<blockquote><p>This is important: <strong>the Gemfile.lock makes your application a single package of both your own code and the third-party code it ran the last time you know for sure that everything worked</strong>. Specifying exact versions of the third-party code you depend on in your Gemfile would not provide the same guarantee, because gems usually declare a range of versions for their dependencies.</p><footer><strong>Bundler Documentation</strong> <cite><a href='http://gembundler.com/rationale.html'>Bundler Rationale</a></cite></footer></blockquote>


<h3>Pessimistic Version Constraints for All!</h3>

<p>Some developers lean on the use of the <a href="http://docs.rubygems.org/read/chapter/16#page74">pessimistic version constraint</a> (<code>~&gt;</code>). In fact, the rubygems web interface encourages this explicitly on every gem page. In the absence of an existing version that breaks compatibility I find this unnecessary as well.</p>

<p>The pessimistic constraint is typically used to lock a gem to a specific major.minor version while allowing the patch level to increase. For instance, <code>'~&gt; 3.1.0'</code> would lock the gem to version 3.1.x. The effectiveness of this approach depends on gem authors strictly following a <a href="http://docs.rubygems.org/read/chapter/7">rational</a> or <a href="http://semver.org">semantic</a> versioning policy. Even well-meaning gem maintainers accidentally introduce breaking changes or performance regressions in patch number releases. A patch level release may also take new versions (major, minor, or patch level) of its dependencies which may cause issues with a different direct dependency in your gemfile.</p>

<p>Regardless of the constraints used in the <code>Gemfile</code>, the developer must still exercise caution when updating the bundle. It&#8217;s unclear to me what advantage using pessimistic version constraints by default offers.</p>

<h3>Promiscuous Gemfiles</h3>

<p>I opt to leave my gems unconstrained by default. Updating gems in the application bundle is done with <code>bundle update &lt;gemname&gt;</code> and will change <code>Gemfile.lock</code>. This is a conscious operation and is undertaken with care. If the project&#8217;s test suite or QA plan fail then it&#8217;s appropriate to add a version constraint to the offending gem or update the application to remedy the incompatibility.</p>

<p>I will leverage a pessimistic version constraint when, for instance, maintaining a rails 2.3.x project. The <code>'~&gt; 2.3.14'</code> constraint would allow the project to update to newer security fixes while not introducing changes I know to be breaking from the 3.x releases. I will use an exact version constraint if, for example, a gem introduces breaking changes in a patch number release. The result is a less noisy <code>Gemfile</code> where all of the version constraints are immediately obvious and usually documented with appropriate comments.</p>

<p>The introduction of bundler 1.1 (currently at release candidate 3), adds the command <code>bundle outdated</code> which is a boon to this approach. <code>bundle outdated</code> returns a list of gems that would be updated if <code>bundle update</code> were run with no arguments. This allows me to easily see which gems have been updated and investigate the changes before running <code>bundle update</code>. It&#8217;s important to note that <code>bundle outdated</code> will not show you versions that don&#8217;t meet the constraints specified in your gemfile. If you have a gem specified with the constraint <code>'~&gt;2.0.0'</code> and the maintainer releases version 2.1 <code>bundle outdated</code> won&#8217;t alert you to this. When paired with an unconstrained <code>Gemfile</code>, <code>bundle outdated</code> can help developers keep up with changes to dependencies that might prove useful in their project.</p>

<h3>Conclusion</h3>

<p>Unnecessary constraints make updating gems a hassle, particularly as your project ages or new versions of your dependencies and their dependencies are released. If you alter a constraint to pick up a new version of a direct dependency, you may find that <code>bundle update</code> fails until you alter additional constraints. This hoop jumping can be avoided by removing all but the strictly necessary constraints and employing <code>bundle update</code> with care.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Using PeepOpen With RubyMine]]></title>
    <link href="http://prioritized.net/blog/using-peepopen-with-rubymine/"/>
    <updated>2011-08-11T21:27:00-04:00</updated>
    <id>http://prioritized.net/blog/using-peepopen-with-rubymine</id>
    <content type="html"><![CDATA[<p>I&#8217;ve been doing a lot of development in <a href="https://github.com/carlhuda/janus">MacVim</a> of late, but there are times when I long for the warm embrace of an IDE. For many reasons that I won&#8217;t detail here, I find  <a href="http://www.jetbrains.com/ruby/">RubyMine</a> to be the best Ruby IDE out there. While its keyboard-based file navigation is functional, I much prefer the interface provided by <a href="http://peepcode.com/products/peepopen">PeepOpen</a> that I had grown acustomed to when using MacVim and TextMate.</p>

<p>Fortunately, with a little work we can use the External Tools configuration in RubyMine to invoke PeepOpen.</p>

<!--more-->


<ol>
<li><p>With RubyMine closed, navigate to your /Applications folder and rename the RubyMine app bundle (i.e. RubyMine 3.2.3) to RubyMine. I tried numerous escape sequences when configuring the external tool to avoid this, but none of them worked.</p></li>
<li><p>Launch RubyMine, open preferences, and navigate to the &#8220;External Tools&#8221; section under IDE Settings. Add a new external tool. Name it, group it, and describe it however you wish. Make sure you turn off the console option. Set the program to <code>open</code> and the parameters to <code>peepopen://$ProjectFileDir$?editor=RubyMine</code>. My configuration looks like <a href="http://prioritized.net/images/posts/peepopen_rubymine.png">this</a>. Apply these changes to save the new command.</p></li>
<li><p>Go to the KeyMap settings in RubyMine and search for the command you just created. Add a keyboard shortcut of your choosing. I used command-t, just as I had in MacVim and TextMate.</p></li>
<li><p>Be sure to apply all changes before exiting the preferences. Load up a project and give it a shot!</p></li>
</ol>


<h2>Notes</h2>

<ul>
<li><p>The <code>editor=</code> line in the parameter tells PeepOpen which application it should send the file to. The space in the RubyMine app bundle name was causing this to fail. I tried numerous ways of escaping this before giving up and renaming the bundle. I&#8217;ve <a href="http://youtrack.jetbrains.net/issue/RUBY-8671?projectKey=RUBY">always been annoyed</a> by it, anyway.</p></li>
<li><p>I had some issues with the <code>$ProjectFileDir$</code> macro in my project. <code>$Projectpath$</code> and <code>$SourcePath$</code> were also <a href="http://devnet.jetbrains.net/thread/311347;jsessionid=E7D0E5AB18FE559CEF75DB75A5761214?tstart=0">incorrectly mapped</a>. I fixed this by adding/removing some random items under the Project Structure settings, but it&#8217;s not clear why this was necessary.</p></li>
<li><p>You probably want to open your PeepOpen preferences and set it to exclude the .idea directory by adding that path to &#8220;Directories to Ignore&#8221;.</p></li>
</ul>

]]></content>
  </entry>
  
</feed>

