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

<channel>
	<title>Pivotal Labs &#187; Alex Chaffee</title>
	<atom:link href="http://pivotallabs.com/author/alex/feed/" rel="self" type="application/rss+xml" />
	<link>http://pivotallabs.com</link>
	<description>Agility Developed</description>
	<lastBuildDate>Wed, 19 Jun 2013 16:27:53 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>Code Monkey</title>
		<link>http://pivotallabs.com/code-monkey/</link>
		<comments>http://pivotallabs.com/code-monkey/#comments</comments>
		<pubDate>Fri, 20 May 2011 17:56:00 +0000</pubDate>
		<dc:creator>Alex Chaffee</dc:creator>
				<category><![CDATA[Labs]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://pivotallabs.com/code-monkey/</guid>
		<description><![CDATA[<p><p>So I didn't go to <a href="http://en.oreilly.com/rails2011">whatever was going on in Baltimore</a> this week, but I did do a whole bunch of open source coding over the past week or two:</p>

<ul>
<li><a href="http://testfirst.org">TestFirst</a> has a totally revamped design, including the downloadable &#40;or cloneable&#41; student exercises, and <em>Learn JavaScript</em> is now a first-class citizen</li>
<li><a href="https://github.com/sconover/wrong">Wrong</a>'s <code>expect</code> alias now plays nicer with RSpec's <code>expect</code></li>
<li><a href="https://github.com/alexch/rerun">Rerun</a> got a few new command-line options, including <code>--clear</code> and <code>--exit</code> so you can now easily rerun regular scripts &#40;like <code>rerun -cx rake test</code>&#41; when their files change</li>
<li>I submitted a patch to <a href="https://github.com/rubygems/rubygems/pull/59">RubyGems</a> to make the <a href="http://pivotallabs.com/users/alex/blog/articles/1687-rubygems-warningitis-outbreak">warningitis</a> less ZOMG and more KTHXBY</li>
<li><a href="http://alexch.github.com/bookmarklets/#fonzie">Fonzie</a> is a bookmarklet that tells you what font you're looking at</li>
<li><a href="alexch.github.com/bookmarklets/#twitterrss">Twitter RSS</a> is a bookmarklet that brings back the RSS link to the New Twitter UI</li>
<li><a href="https://github.com/alexch/showoff">Showoff</a> works better with nested bullets and missing <code>showoff.json</code> files -- so go <a href="https://github.com/schacon/showoff/pull/88">nag Scott</a> if you want him to accept my patches <code>;-&#41;</code></li>
<li>I also finally got my <a href="http://stackoverflow.com/questions/591923/make-git-automatically-remove-trailing-whitespace-before-committing/4597057#4597057">git pre-commit hook</a> correctly stripping whitespace, and </li>
</ul>

<p>A lot of these projects, especially <a href="http://testfirst.org">TestFirst</a>, are aching for improvement, so if you feel like contributing code or courseware, or even just feature requests, please <a href="mailto:alex@stinky.com">get in touch</a>!</p> <a href="http://pivotallabs.com/code-monkey/">Continue reading <span class="meta-nav">&#8594;</span></a></p><p>The post <a href="http://pivotallabs.com/code-monkey/">Code Monkey</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>So I didn&#8217;t go to <a href="http://en.oreilly.com/rails2011">whatever was going on in Baltimore</a> this week, but I did do a whole bunch of open source coding over the past week or two:</p>
<ul>
<li><a href="http://testfirst.org">TestFirst</a> has a totally revamped design, including the downloadable &#40;or cloneable&#41; student exercises, and <em>Learn JavaScript</em> is now a first-class citizen</li>
<li><a href="https://github.com/sconover/wrong">Wrong</a>&#8216;s <code>expect</code> alias now plays nicer with RSpec&#8217;s <code>expect</code></li>
<li><a href="https://github.com/alexch/rerun">Rerun</a> got a few new command-line options, including <code>--clear</code> and <code>--exit</code> so you can now easily rerun regular scripts &#40;like <code>rerun -cx rake test</code>&#41; when their files change</li>
<li>I submitted a patch to <a href="https://github.com/rubygems/rubygems/pull/59">RubyGems</a> to make the <a href="http://pivotallabs.com/users/alex/blog/articles/1687-rubygems-warningitis-outbreak">warningitis</a> less ZOMG and more KTHXBY</li>
<li><a href="http://alexch.github.com/bookmarklets/#fonzie">Fonzie</a> is a bookmarklet that tells you what font you&#8217;re looking at</li>
<li><a href="alexch.github.com/bookmarklets/#twitterrss">Twitter RSS</a> is a bookmarklet that brings back the RSS link to the New Twitter UI</li>
<li><a href="https://github.com/alexch/showoff">Showoff</a> works better with nested bullets and missing <code>showoff.json</code> files &#8212; so go <a href="https://github.com/schacon/showoff/pull/88">nag Scott</a> if you want him to accept my patches <code>;-&#41;</code></li>
<li>I also finally got my <a href="http://stackoverflow.com/questions/591923/make-git-automatically-remove-trailing-whitespace-before-committing/4597057#4597057">git pre-commit hook</a> correctly stripping whitespace, and </li>
</ul>
<p>A lot of these projects, especially <a href="http://testfirst.org">TestFirst</a>, are aching for improvement, so if you feel like contributing code or courseware, or even just feature requests, please <a href="mailto:alex@stinky.com">get in touch</a>!</p>
<p>The post <a href="http://pivotallabs.com/code-monkey/">Code Monkey</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://pivotallabs.com/code-monkey/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>RubyGems Warningitis Outbreak</title>
		<link>http://pivotallabs.com/rubygems-warningitis-outbreak/</link>
		<comments>http://pivotallabs.com/rubygems-warningitis-outbreak/#comments</comments>
		<pubDate>Thu, 12 May 2011 18:20:00 +0000</pubDate>
		<dc:creator>Alex Chaffee</dc:creator>
				<category><![CDATA[Labs]]></category>
		<category><![CDATA[gem]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[ruby on rails]]></category>

		<guid isPermaLink="false">http://pivotallabs.com/rubygems-warningitis-outbreak/</guid>
		<description><![CDATA[<p><p>Have you upgraded RubyGems lately? Is your console suddenly filled with warnings like this?</p>

<pre><code>NOTE: Gem::Specification#default_executable= is deprecated with no replacement. It will be removed on or after 2011-10-01.
Gem::Specification#default_executable= called from /Users/chaffee/.rvm/gems/ruby-1.9.2-p0/specifications/thin-1.2.7.gemspec:10.
</code></pre>

<p>You may be showing signs of a new malady known as Warningitis! So far there is no cure, but doing the following will temporarily cure your symptoms:</p>

<pre><code>gem update --system 1.7.2
</code></pre>

<p><a href="https://gist.github.com/965921">Several</a> <a href="https://github.com/rubygems/rubygems/pull/59">experimental</a> <a href="https://github.com/mikbe/chicken_little">treatments</a> are being hastily developed as well, but these have not yet been approved by the FDA. Check <a href="https://rubyforge.org/tracker/index.php?func=detail&#38;aid=29176&#38;group_id=126&#38;atid=575">the "scary warnings are scary" bug thread</a> for more details.</p>

<p>This has been a public health alert. Please do not panic. SARS masks and iodine pills are <strong>not</strong> recommended at this time.</p> <a href="http://pivotallabs.com/rubygems-warningitis-outbreak/">Continue reading <span class="meta-nav">&#8594;</span></a></p><p>The post <a href="http://pivotallabs.com/rubygems-warningitis-outbreak/">RubyGems Warningitis Outbreak</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>Have you upgraded RubyGems lately? Is your console suddenly filled with warnings like this?</p>
<pre><code>NOTE: Gem::Specification#default_executable= is deprecated with no replacement. It will be removed on or after 2011-10-01.
Gem::Specification#default_executable= called from /Users/chaffee/.rvm/gems/ruby-1.9.2-p0/specifications/thin-1.2.7.gemspec:10.
</code></pre>
<p>You may be showing signs of a new malady known as Warningitis! So far there is no cure, but doing the following will temporarily cure your symptoms:</p>
<pre><code>gem update --system 1.7.2
</code></pre>
<p><a href="https://gist.github.com/965921">Several</a> <a href="https://github.com/rubygems/rubygems/pull/59">experimental</a> <a href="https://github.com/mikbe/chicken_little">treatments</a> are being hastily developed as well, but these have not yet been approved by the FDA. Check <a href="https://rubyforge.org/tracker/index.php?func=detail&amp;aid=29176&amp;group_id=126&amp;atid=575">the &#8220;scary warnings are scary&#8221; bug thread</a> for more details.</p>
<p>This has been a public health alert. Please do not panic. SARS masks and iodine pills are <strong>not</strong> recommended at this time.</p>
<p>The post <a href="http://pivotallabs.com/rubygems-warningitis-outbreak/">RubyGems Warningitis Outbreak</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://pivotallabs.com/rubygems-warningitis-outbreak/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Upgrading your Rakefile from RSpec 1.3 to RSpec 2</title>
		<link>http://pivotallabs.com/upgrading-your-rakefile-from-rspec-1-3-to-rspec-2/</link>
		<comments>http://pivotallabs.com/upgrading-your-rakefile-from-rspec-1-3-to-rspec-2/#comments</comments>
		<pubDate>Tue, 26 Oct 2010 18:12:00 +0000</pubDate>
		<dc:creator>Alex Chaffee</dc:creator>
				<category><![CDATA[Labs]]></category>
		<category><![CDATA[erector]]></category>
		<category><![CDATA[rspec]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://pivotallabs.com/upgrading-your-rakefile-from-rspec-1-3-to-rspec-2/</guid>
		<description><![CDATA[<p><p>I'm updating <a href="http://erector.rubyforge.org">Erector</a> to RSpec 2 and came across two problems for which solutions were surprisingly difficult to Google. Here are my &#40;finally successful&#41; results.</p>

<hr />

<h2>Problem:</h2>

<pre><code>no such file to load -- spec/rake/spectask
</code></pre>

<h3>Before:</h3>

<pre><code>require "spec/rake/spectask"  # RSpec 1.3
</code></pre>

<h3>After:</h3>

<pre><code>require "rspec/core/rake_task" # RSpec 2.0
</code></pre>

<hr />

<h2>Problem:</h2>

<pre><code>undefined method `spec_files=' for #&#60;RSpec::Core::RakeTask:0x00000101550aa8&#62;
</code></pre>

<h3>Before:</h3>

<pre><code># RSpec 1.3
Spec::Rake::SpecTask.new&#40;:core&#41; do &#124;spec&#124;
  spec.spec_files = FileList['spec/erector/*_spec.rb']
  spec.spec_opts = ['--backtrace']
end
</code></pre>

<h3>After:</h3>

<pre><code># RSpec 2.0
RSpec::Core::RakeTask.new&#40;:core&#41; do &#124;spec&#124;
  spec.pattern = 'spec/erector/*_spec.rb'
  spec.rspec_opts = ['--backtrace']
end
</code></pre>

<hr />

<p>See also <a href="http://github.com/rspec/rspec-core/blob/master/Upgrade.markdown">http://github.com/rspec/rspec-core/blob/master/Upgrade.markdown</a> &#40;curiously cloaked from Google searches for the above problem strings&#41;.</p> <a href="http://pivotallabs.com/upgrading-your-rakefile-from-rspec-1-3-to-rspec-2/">Continue reading <span class="meta-nav">&#8594;</span></a></p><p>The post <a href="http://pivotallabs.com/upgrading-your-rakefile-from-rspec-1-3-to-rspec-2/">Upgrading your Rakefile from RSpec 1.3 to RSpec 2</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>I&#8217;m updating <a href="http://erector.rubyforge.org">Erector</a> to RSpec 2 and came across two problems for which solutions were surprisingly difficult to Google. Here are my &#40;finally successful&#41; results.</p>
<hr />
<h2>Problem:</h2>
<pre><code>no such file to load -- spec/rake/spectask
</code></pre>
<h3>Before:</h3>
<pre><code>require "spec/rake/spectask"  # RSpec 1.3
</code></pre>
<h3>After:</h3>
<pre><code>require "rspec/core/rake_task" # RSpec 2.0
</code></pre>
<hr />
<h2>Problem:</h2>
<pre><code>undefined method `spec_files=' for #&lt;RSpec::Core::RakeTask:0x00000101550aa8&gt;
</code></pre>
<h3>Before:</h3>
<pre><code># RSpec 1.3
Spec::Rake::SpecTask.new&#40;:core&#41; do |spec|
  spec.spec_files = FileList['spec/erector/*_spec.rb']
  spec.spec_opts = ['--backtrace']
end
</code></pre>
<h3>After:</h3>
<pre><code># RSpec 2.0
RSpec::Core::RakeTask.new&#40;:core&#41; do |spec|
  spec.pattern = 'spec/erector/*_spec.rb'
  spec.rspec_opts = ['--backtrace']
end
</code></pre>
<hr />
<p>See also <a href="http://github.com/rspec/rspec-core/blob/master/Upgrade.markdown">http://github.com/rspec/rspec-core/blob/master/Upgrade.markdown</a> &#40;curiously cloaked from Google searches for the above problem strings&#41;.</p>
<p>The post <a href="http://pivotallabs.com/upgrading-your-rakefile-from-rspec-1-3-to-rspec-2/">Upgrading your Rakefile from RSpec 1.3 to RSpec 2</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://pivotallabs.com/upgrading-your-rakefile-from-rspec-1-3-to-rspec-2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Where, oh where has my gem server gone?</title>
		<link>http://pivotallabs.com/oops-du-jour/</link>
		<comments>http://pivotallabs.com/oops-du-jour/#comments</comments>
		<pubDate>Mon, 09 Aug 2010 01:01:00 +0000</pubDate>
		<dc:creator>Alex Chaffee</dc:creator>
				<category><![CDATA[Labs]]></category>
		<category><![CDATA[gem]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://pivotallabs.com/oops-du-jour/</guid>
		<description><![CDATA[<p><p>Uh-oh!</p>

<pre><code>ERROR:  While executing gem ... &#40;Gem::RemoteFetcher::FetchError&#41;
    bad response Moved Permanently 301 &#40;http://gems.rubyforge.org/latest_specs.4.8&#41;
</code></pre>

<p>Whew!</p>

<pre><code>gem sources -a http://rubygems.org/
gem sources -r http://gems.rubyforge.org/
</code></pre>

<p>Looks like they weren't kidding when they said to switch from  rubyforge to rubygems.org &#40;née gemcutter&#41;!</p>

<p>[Edited to change "http://production.s3.rubygems.org/" to "http://rubygems.org/". Note that the trailing slash is significant!]</p> <a href="http://pivotallabs.com/oops-du-jour/">Continue reading <span class="meta-nav">&#8594;</span></a></p><p>The post <a href="http://pivotallabs.com/oops-du-jour/">Where, oh where has my gem server gone?</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>Uh-oh!</p>
<pre><code>ERROR:  While executing gem ... &#40;Gem::RemoteFetcher::FetchError&#41;
    bad response Moved Permanently 301 &#40;http://gems.rubyforge.org/latest_specs.4.8&#41;
</code></pre>
<p>Whew!</p>
<pre><code>gem sources -a http://rubygems.org/
gem sources -r http://gems.rubyforge.org/
</code></pre>
<p>Looks like they weren&#8217;t kidding when they said to switch from  rubyforge to rubygems.org &#40;née gemcutter&#41;!</p>
<p>[Edited to change "http://production.s3.rubygems.org/" to "http://rubygems.org/". Note that the trailing slash is significant!]</p>
<p>The post <a href="http://pivotallabs.com/oops-du-jour/">Where, oh where has my gem server gone?</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://pivotallabs.com/oops-du-jour/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>monkey patch of the day &#8211; activesupport vs. json_pure vs. Ruby 1.8</title>
		<link>http://pivotallabs.com/monkey-patch-of-the-day-activesupport-vs-json-pure-vs-ruby-1-8/</link>
		<comments>http://pivotallabs.com/monkey-patch-of-the-day-activesupport-vs-json-pure-vs-ruby-1-8/#comments</comments>
		<pubDate>Sun, 25 Jul 2010 19:13:00 +0000</pubDate>
		<dc:creator>Alex Chaffee</dc:creator>
				<category><![CDATA[Labs]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[ruby on rails]]></category>

		<guid isPermaLink="false">http://pivotallabs.com/monkey-patch-of-the-day-activesupport-vs-json-pure-vs-ruby-1-8/</guid>
		<description><![CDATA[<p><p>The error:</p>

<pre><code>/Library/Ruby/Gems/1.8/gems/json_pure-1.4.3/lib/json/pure/generator.rb:232:in `__send__': undefined method `except' for #&#60;JSON::Pure::Generator::State:0x102f245b0&#62; &#40;NoMethodError&#41;
</code></pre>

<p>The environment: Ruby 1.8.7, DataMapper, dm-types, ActiveSupport, or just </p>

<pre><code>require 'json/pure'
require 'active_support'
</code></pre>

<p>&#40;as seen in <a href="http://gist.github.com/339528">http://gist.github.com/339528</a>&#41;</p>

<p>My solution:</p>

<pre><code># workaround for activesupport vs. json_pure vs. Ruby 1.8 glitch
if JSON.const_defined?&#40;:Pure&#41;
  class JSON::Pure::Generator::State
    include ActiveSupport::CoreExtensions::Hash::Except
  end
end
</code></pre> <a href="http://pivotallabs.com/monkey-patch-of-the-day-activesupport-vs-json-pure-vs-ruby-1-8/">Continue reading <span class="meta-nav">&#8594;</span></a></p><p>The post <a href="http://pivotallabs.com/monkey-patch-of-the-day-activesupport-vs-json-pure-vs-ruby-1-8/">monkey patch of the day &#8211; activesupport vs. json_pure vs. Ruby 1.8</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>The error:</p>
<pre><code>/Library/Ruby/Gems/1.8/gems/json_pure-1.4.3/lib/json/pure/generator.rb:232:in `__send__': undefined method `except' for #&lt;JSON::Pure::Generator::State:0x102f245b0&gt; &#40;NoMethodError&#41;
</code></pre>
<p>The environment: Ruby 1.8.7, DataMapper, dm-types, ActiveSupport, or just </p>
<pre><code>require 'json/pure'
require 'active_support'
</code></pre>
<p>&#40;as seen in <a href="http://gist.github.com/339528">http://gist.github.com/339528</a>&#41;</p>
<p>My solution:</p>
<pre><code># workaround for activesupport vs. json_pure vs. Ruby 1.8 glitch
if JSON.const_defined?&#40;:Pure&#41;
  class JSON::Pure::Generator::State
    include ActiveSupport::CoreExtensions::Hash::Except
  end
end
</code></pre>
<p>The post <a href="http://pivotallabs.com/monkey-patch-of-the-day-activesupport-vs-json-pure-vs-ruby-1-8/">monkey patch of the day &#8211; activesupport vs. json_pure vs. Ruby 1.8</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://pivotallabs.com/monkey-patch-of-the-day-activesupport-vs-json-pure-vs-ruby-1-8/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Windowed String Comparison for RSpec</title>
		<link>http://pivotallabs.com/windowed-string-comparison-for-rspec/</link>
		<comments>http://pivotallabs.com/windowed-string-comparison-for-rspec/#comments</comments>
		<pubDate>Fri, 16 Jul 2010 17:55:00 +0000</pubDate>
		<dc:creator>Alex Chaffee</dc:creator>
				<category><![CDATA[Labs]]></category>
		<category><![CDATA[rspec]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://pivotallabs.com/windowed-string-comparison-for-rspec/</guid>
		<description><![CDATA[<p><p>When two strings fail to match, if the difference is somewhere in the middle of the strings, it can be annoying/impossible to track down the
actual difference. I've written a little <a href="http://gist.github.com/474363">Comparison</a> object that
overrides the failure message for <code>.should ==</code> like this:</p>

<pre><code>Strings differ at position 12:
expected: ..."efghijklmnopqrst"...
  actual: ..."efghijklXXopqrst"...
</code></pre>

<p>It shows a "prelude" of a few characters, then the difference, lined up on successive lines so they're easy to visually scan. It also does the right thing &#40;or tries to&#41; if the difference is near the beginning or end of the string &#40;i.e. does or doesn't show ellipses&#41;. </p>

<p><a href="http://gist.github.com/474363">http://gist.github.com/474363</a></p>

<p>For people who can't wait for this to get incorporated into RSpec
proper, you can grab the code from github and <code>require "comparison"</code> in your <code>spec_helper.rb</code> and it'll override the existing RSpec <code>==</code> matcher. Or wait for <a href="http://github.com/rspec/rspec-expectations/issues/issue/9">Issue 9</a> to be pulled into version 2.1 &#40;maybe&#41;. Or if you want to use it in your favorite testing framework, the object is completely self-contained and should be easy to call from your own <code>assert_equals</code> or whatever.</p>

<p>One open question is whether the exception message should show the
full actual string as well as the comparison... On one hand, it adds
to screen clutter, but on the other hand, it can be important in
tracking down the problem, especially if the prelude is ambiguous. </p> <a href="http://pivotallabs.com/windowed-string-comparison-for-rspec/">Continue reading <span class="meta-nav">&#8594;</span></a></p><p>The post <a href="http://pivotallabs.com/windowed-string-comparison-for-rspec/">Windowed String Comparison for RSpec</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>When two strings fail to match, if the difference is somewhere in the middle of the strings, it can be annoying/impossible to track down the<br />
actual difference. I&#8217;ve written a little <a href="http://gist.github.com/474363">Comparison</a> object that<br />
overrides the failure message for <code>.should ==</code> like this:</p>
<pre><code>Strings differ at position 12:
expected: ..."efghijklmnopqrst"...
  actual: ..."efghijklXXopqrst"...
</code></pre>
<p>It shows a &#8220;prelude&#8221; of a few characters, then the difference, lined up on successive lines so they&#8217;re easy to visually scan. It also does the right thing &#40;or tries to&#41; if the difference is near the beginning or end of the string &#40;i.e. does or doesn&#8217;t show ellipses&#41;. </p>
<p><a href="http://gist.github.com/474363">http://gist.github.com/474363</a></p>
<p>For people who can&#8217;t wait for this to get incorporated into RSpec<br />
proper, you can grab the code from github and <code>require "comparison"</code> in your <code>spec_helper.rb</code> and it&#8217;ll override the existing RSpec <code>==</code> matcher. Or wait for <a href="http://github.com/rspec/rspec-expectations/issues/issue/9">Issue 9</a> to be pulled into version 2.1 &#40;maybe&#41;. Or if you want to use it in your favorite testing framework, the object is completely self-contained and should be easy to call from your own <code>assert_equals</code> or whatever.</p>
<p>One open question is whether the exception message should show the<br />
full actual string as well as the comparison&#8230; On one hand, it adds<br />
to screen clutter, but on the other hand, it can be important in<br />
tracking down the problem, especially if the prelude is ambiguous. </p>
<p>The post <a href="http://pivotallabs.com/windowed-string-comparison-for-rspec/">Windowed String Comparison for RSpec</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://pivotallabs.com/windowed-string-comparison-for-rspec/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Basic Ruby Webapp Performance Tuning (Rails or Sinatra)</title>
		<link>http://pivotallabs.com/basic-ruby-webapp-performance-tuning-rails-or-sinatra/</link>
		<comments>http://pivotallabs.com/basic-ruby-webapp-performance-tuning-rails-or-sinatra/#comments</comments>
		<pubDate>Thu, 29 Apr 2010 02:37:00 +0000</pubDate>
		<dc:creator>Alex Chaffee</dc:creator>
				<category><![CDATA[Labs]]></category>
		<category><![CDATA[activerecord]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[ruby on rails]]></category>
		<category><![CDATA[sinatra]]></category>

		<guid isPermaLink="false">http://pivotallabs.com/basic-ruby-webapp-performance-tuning-rails-or-sinatra/</guid>
		<description><![CDATA[<p><p>My company launched our app, <a href="http://www.cohuman.com">Cohuman</a>, a few weeks ago. The rush of finishing features, fixing bugs, and responding to user feedback has subsided a bit, and it's time to go back and give the little baby a tune-up. I find that a good development process will ebb and flow, and as long as you don't let something slide for too long, it's perfectly acceptable to let bugs, or performance issues, or development chores pile up for a bit and then attack them concertedly for an entire day or two. A bug-fest or chore-fest or tuning-fest can actually increase efficiency as you get in a rhythm... and it feels really good at the end of the day when you see all the bugs you slayed or all the milliseconds you shaved.</p>

<p>In this article I'd like to describe some of my techniques. I make no claim of originality or great expertise; I just want to share what I know, and hear &#40;in comments&#41; what other people have learned. I'm using Sinatra and ActiveRecord, but not Rails; hopefully this discussion will help people no matter what framework they're using.</p> <a href="http://pivotallabs.com/basic-ruby-webapp-performance-tuning-rails-or-sinatra/">Continue reading <span class="meta-nav">&#8594;</span></a></p><p>The post <a href="http://pivotallabs.com/basic-ruby-webapp-performance-tuning-rails-or-sinatra/">Basic Ruby Webapp Performance Tuning (Rails or Sinatra)</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>My company launched our app, <a href="http://www.cohuman.com">Cohuman</a>, a few weeks ago. The rush of finishing features, fixing bugs, and responding to user feedback has subsided a bit, and it&#8217;s time to go back and give the little baby a tune-up. I find that a good development process will ebb and flow, and as long as you don&#8217;t let something slide for too long, it&#8217;s perfectly acceptable to let bugs, or performance issues, or development chores pile up for a bit and then attack them concertedly for an entire day or two. A bug-fest or chore-fest or tuning-fest can actually increase efficiency as you get in a rhythm&#8230; and it feels really good at the end of the day when you see all the bugs you slayed or all the milliseconds you shaved.</p>
<p>In this article I&#8217;d like to describe some of my techniques. I make no claim of originality or great expertise; I just want to share what I know, and hear &#40;in comments&#41; what other people have learned. I&#8217;m using Sinatra and ActiveRecord, but not Rails; hopefully this discussion will help people no matter what framework they&#8217;re using.</p>
<h1>Metrics and Logs</h1>
<p>The first step, and often the most overlooked, is to gather metrics. Without knowing how it&#8217;s working now, how are you going to know what to improve? And how are you going to know whether you made things better or worse? Frequently I&#8217;ll make a change that I&#8217;m sure will improve performance, only to discover that it&#8217;s made no change, or helped in one place but hurt in another.</p>
<p>Where to begin? We&#8217;re using <a href="http://www.newrelic.com/">New Relic</a> for live performance monitoring, so my decision of what to optimize was easy: I went to their Web Transactions panel and looked at the Most Time Consuming and Slowest Average Response Time reports. If you don&#8217;t have a flashing signpost like that, it&#8217;s easy enough to decide on a path to work on: either go with user reports, or click around your app and see what feels slow, or choose the most popular request &#40;which is usually the home page&#41;. </p>
<p>I always pick a single path to work on, from request to controller to database to view, and work on the slowest parts. This demands more metrics! It&#8217;s a common mistake to jump in and start tuning the database when the view is actually taking twice as long. What&#8217;s the use of cutting the database access from 400 to 200 msec when the view is taking 1200 msec to render?</p>
<p>I also like to grab a copy of the production DB and bring it to my development machine so I can be sure I&#8217;m profiling real cases, and not being fooled by artifacts of generated data. We&#8217;re lucky that our app is currently small enough to do this; when the app gets bigger we&#8217;ll have to write a script that grabs only selected users&#8217; data as a slice of the whole enchilada. &#40;Note that there are some privacy concerns here: we are careful to only log in locally using our own accounts, and only to gather statistics in aggregate, not to look at details of user-entered data unless it&#8217;s to diagnose a specific user-reported issue or bug.&#41;</p>
<p>Lots of in-app metrics tools exist &#40;e.g. ruby-prof, benchmark&#41;, but I prefer the simple approach: I rolled my own Marker class that spits out basic msec timing information to the logs. In single-request performance tuning, what matters is relative timing between sections of code, so any objections to this technique on grounds of accuracy or detail are outweighed by its advantages: it&#8217;s simple, it shows where your bottlenecks are, and it divides the logs into sections so you can get a sense of who&#8217;s making what calls.</p>
<pre><code>class Marker
  def self.mark&#40;msg, logger = ActiveRecord::Base.logger&#41;
    start = Time.now
    logger.info&#40;"#{start} --&gt; starting #{msg} from #{caller[2]}:#{caller[1]}"&#41;
    result = yield
    finish = Time.now
    logger.info&#40;"#{finish} --&lt; finished #{msg} --- #{"%2.3f sec" % &#40;finish - start&#41;}"&#41;
    result
  end
end
</code></pre>
<p>Usage is simple: pick a block you&#8217;re interested and wrap it in <code>Marker.mark&#40;"foo"&#41; do...end</code>. You can then scan the logs using &#8220;less&#8221; &#40;or a text editor&#41; and search for the name you gave the block. Marking your controller and your view is a natural place to start; later you can insert marks inside interesting blocks of domain code. In Sinatra, you can do something like this:</p>
<pre><code>get '/foo/:id' do
  foo = Marker.mark&#40;"loading foo"&#41; do
    Foo.find&#40;params[:id]&#41;
  end
  Marker.mark&#40;"rendering foo"&#41; do
    FooWidget.new&#40;:foo =&gt; foo&#41;.to_s # Erector
  end
end
</code></pre>
<p>I&#8217;ve also got a nice little Rack middleware component that marks the time spent inside each request. Note here that you can put lots of fun information in the name that can be helpful for debugging.</p>
<pre><code>class Marking
  def initialize&#40;app&#41;
    @app = app
  end

  def call&#40;env&#41;
    response = nil
    Marker.mark&#40;"#{env['REQUEST_METHOD']} #{env['SCRIPT_NAME']}#{env['PATH_INFO']}"&#41; do
      response = @app.call&#40;env&#41;
    end
    response
  end
end
</code></pre>
<p>Figuring out where a particular log message &#40;especially a DB query&#41; is coming from is essential. It&#8217;s important not to make assumptions. If you think you know where the call is coming from, put in a stack trace to make sure, and rerun the request to confirm. That&#8217;s why Marker is outputting caller &#8212; <code>caller[0]</code> is the code that names the mark, so you already know where that is; <code>caller[1]</code> is the line that called it, and <code>caller[2]</code> is the line that called <code>caller[1]</code>. If that&#8217;s not enough context, drop in a logger.info&#40;caller.join&#40;&#8221;nt&#8221;&#41;&#41; so you can scan the entire stack trace back up to the application code that you understand.</p>
<p>I&#8217;ve found that while ActiveRecord &#40;2.3.5&#41; tries to show where a result is coming from, it doesn&#8217;t always get it right, especially if you&#8217;re using plugins or gems that insert themselves into the call chain. So I monkey-patched AR to be a little smarter about its tracing:</p>
<pre><code>module ActiveRecord
  module ConnectionAdapters
    class AbstractAdapter
      # strip library file pathnames from logged stack traces
      def log_info&#40;sql, name, ms&#41;
        if @logger &amp;&amp; @logger.debug?
          c = caller.detect{|line| line !~ /&#40;activerecord|active_support|__DELEGATION__|vendor|new_?relic&#41;/i}
          c.gsub!&#40;"#{File.expand_path&#40;File.dirname&#40;RAILS_ROOT&#41;&#41;}/", ''&#41; if defined?&#40;RAILS_ROOT&#41;
          name = '%s &#40;%.1fms&#41; %s' % [name || 'SQL', ms, c]
          @logger.debug&#40;format_log_entry&#40;name, sql.squeeze&#40;' '&#41;&#41;&#41;
        end
      end
    end
  end
end
</code></pre>
<p>All this leads to log entries that look like this:</p>
<pre><code>Thu Apr 15 11:09:17 -0700 2010 --&gt; starting GET /app from /Users/cohumancomputer27inmac/dev/cohuman/lib/query_caching.rb:15:in `call':/Library/Ruby/Gems/1.8/gems/activerecord-2.3.5/lib/active_record/connection_adapters/abstract/query_cache.rb:34:in `cache'
  User Load &#40;0.8ms&#41; domain/user.rb:362:in `authenticate_from_login_token'   SELECT * FROM "users" WHERE &#40;"users"."login_token" = E'abc123xyz'&#41; LIMIT 1
Thu Apr 15 11:09:17 -0700 2010 --&gt; starting rendering ApplicationPage from /Users/cohumancomputer27inmac/dev/cohuman/controllers/app_controller.rb:4:in `GET /app':/Library/Ruby/Gems/1.8/gems/sinatra-0.9.4/lib/sinatra/base.rb:779:in `call'  Project Load &#40;13.4ms&#41; domain/user.rb:146:in `projects'   SELECT "projects".* FROM "projects" INNER JOIN "memberships" ON "projects".id = "memberships".project_id WHERE &#40;&#40;"memberships".user_id = 2&#41;&#41;
  User Load &#40;3.2ms&#41; domain/user.rb:135:in `coprojectmates'   SELECT "users".* FROM "users" INNER JOIN "memberships" ON memberships.user_id = users.id WHERE &#40;memberships.project_id in &#40;4,129,122,1,66,82,102,684,533,139,3,155,624,106,90,394,399,153&#41; AND memberships.user_id != 2&#41;   Email Load &#40;2.1ms&#41; domain/user.rb:135:in `coprojectmates'   SELECT "emails".* FROM "emails" WHERE &#40;"emails".user_id IN &#40;1,3,5,7,8,11,12,9,6,14,15,16,17,18,22,27,26,35,45,32,30,79,37,109,80,504,507,508,39,165,521,725,727,729,730,731,734,735,736,105,28,58,240,381,51,40,36,785,834,839,844,847,850,842,840,841,843,889&#41;&#41;
  User Load &#40;11.7ms&#41; domain/user.rb:128:in `cohumans'   SELECT "users".* FROM "users" INNER JOIN "cohumanities" ON "users".id = "cohumanities".cohuman_id WHERE &#40;&#40;"cohumanities".actor_id = 2&#41;&#41;
  Email Load &#40;19.4ms&#41; domain/user.rb:128:in `cohumans'   SELECT "emails".* FROM "emails" WHERE &#40;"emails".user_id IN &#40;1,6,108,8,22,35,509,852,853,854,862,864,866,3,895,896,897,929,930,931,30,944,165,827,976,977,978,735,1024,2003,2004,59&#41;&#41;
  SQL &#40;0.5ms&#41; domain/user.rb:177:in `temporary?'   SELECT count&#40;*&#41; AS count_all FROM "emails" WHERE &#40;"emails".user_id = 2&#41;
  Email Load &#40;0.3ms&#41; domain/user.rb:173:in `verified?'   SELECT * FROM "emails" WHERE &#40;"emails".user_id = 2&#41;
Thu Apr 15 11:09:17 -0700 2010 --&lt; finished rendering ApplicationPage --- 0.307 sec
Thu Apr 15 11:09:17 -0700 2010 --&lt; finished GET /app --- 0.311 sec
</code></pre>
<p>I know it can look daunting, but when scanning logs, it&#8217;s important to keep a clear head. Let&#8217;s examine this little burst of gibberish and try to make sense of it.</p>
<p>Line 1 says &#8220;&#8211;> starting GET /app&#8221; which means that the user has made a GET request for our main URL. We can skip ahead &#40;search for &#8220;&#8211;&lt; GET /app&#8221;&#41; and see that the entire request took 0.311 seconds. This isn&#8217;t bad, but it could be better. </p>
<p>Line 3 says &#8220;&#8211;> starting rendering ApplicationPage&#8221; which means that all the other queries are happening from inside the rendering view code. </p>
<p>Note that the database queries are only taking 49.3 msec out of 311 msec, which means 84% of the time is spent either processing DB results or rendering them. This request is probably not a good candidate for DB-level tuning.</p>
<p>&#40;How&#8217;d I add up all those scary milliseconds without an abacus? Piped my log text into this bad boy:</p>
<pre><code>  ruby -e 'x = 0; STDIN.each do |line| if line =~ /&#40;&#40;[0-9.]*&#41;ms&#41;/; then x += $1.to_f; end; end; puts x'
</code></pre>
<p>&#41;</p>
<h1>Indexes</h1>
<p>Most &#40;if not all&#41; databases add an index for the primary key of a table. But a quick scan of the database logs will show many fields that are used in queries, and chances are you haven&#8217;t added indexes for them. &#40;In fact, you probably shouldn&#8217;t add an index for a field until it shows up in the logs, since indexing slows down writes and takes up extra disk space. Not a lot, but it might add up.&#41; In the above example, look at the User Load &#8212; every time a user hits the site we check to see if he&#8217;s logged in by querying the database for his login cookie. Adding an index for the &#8220;login_token&#8221; field in the users table sped up this query by a factor of 10. &#40;Yes, that violates my &#8220;don&#8217;t fix what ain&#8217;t slow&#8221; dictum, since going from 10 ms to 1 ms isn&#8217;t really fixing much, but I figure it adds up over time since it happens on every single app request.&#41;</p>
<h1>Avoidance</h1>
<p>The only perfect program is the one with zero lines of code. And the fastest code is that which is not run.</p>
<p>Sometimes you can optimize a section of code by removing unnecessary calls from your app layer. One nice trick these days is to move stuff behind an Ajax call. In Cohuman, we do this with some of our tabs: if you switch to a tab, and it hasn&#8217;t been loaded yet, it shows a spinny and starts an Ajax call to load it in. As long as we can keep each Ajax call under a second in length, the user-perceived delay is negligible.</p>
<h1>Query Caching</h1>
<p>ActiveRecord maintains a query cache, so if you run the same query &#40;and I mean the same SQL&#41;, it won&#8217;t hit the database again. But if you&#8217;re not using Rails, query caching is disabled by default. So I wrote yet another Rack middleware so I don&#8217;t have to remember to wrap all my controllers in a <code>ActiveRecord::Base.cache do</code> block:</p>
<pre><code># a Rack middleware component that enables ActiveRecord query caching
# To use, put "use QueryCaching" in your Sinatra app.

class QueryCaching
  def initialize&#40;app&#41;
    @app = app
  end

  def call&#40;env&#41;
    if is_static_file?&#40;env&#41;
      @app.call&#40;env&#41;
    else
      response = nil
      ActiveRecord::Base.cache do
        response = @app.call&#40;env&#41;
      end
      response
    end
  end

  def is_static_file?&#40;env&#41;
     # if the path end with a dot-extension &#40;e.g. 'foo.jpg'&#41; then we assume
     # it's a static file and don't enable the query cache. &#40;This will only
     # work for some application URL schemes, naturally.&#41;
    env['PATH_INFO'] =~ //[^/]*.[^/.]+$/
  end

end
</code></pre>
<p>Note that this is a query cache, not an object cache &#40;see below&#41;.</p>
<h1>Query Tuning</h1>
<p>Once you&#8217;ve identified some troublesome queries, you need to decide how to optimize them. You&#8217;ve basically got two choices here; which to choose should be obvious from the logs. Are there many low-latency queries, or a few high-latency queries? High-latency queries are an obvious target, and you should do your best &#40;with indexes and SQL&#41; to cut them down to size, but don&#8217;t let them distract you. There are two hidden costs to low-latency queries:</p>
<p><strong>They actually take longer than they say they do</strong> &#8211; the AR log line only displays the time for the database connector to return the raw data. It doesn&#8217;t show the time to create AR instances, build association &#8220;classes&#8221; &#40;which takes an annoyingly long time, since all their methods are built on the fly for each instance&#41;, and run post-load initialization code. &#40;I just did a little experiment loading ~3000 of our User objects, which have a fair number of associations; <code>SELECT * FROM users</code> took 21 msec but <code>User.all</code> took 547 msec. That&#8217;s about 25x as long!&#41;</p>
<p><strong>They stack up, and I&#8217;m not talking pancakes</strong> &#8211; chances are you&#8217;ve got a lot of webapp processes hitting a single database &#40;or a small number of slaves&#41;. As traffic increases, the queries will stack up like airplanes requesting permission to land. At a certain point you&#8217;ll hit a cliff &#40;sorry for the mixed metaphor &#8212; it&#8217;s not fun to imagine a plane hitting a cliff&#41; and per-request latency will rise dramatically. Lowering the number of queries per web request will, um, raise the ceiling? Lengthen the runway? Lower the cliff? Anyway, it&#8217;ll make this problem, uh, less worse. It&#8217;s kind of counterintuitive, but the limiting factor for modern webapps is really the number of queries, not the amount of data returned by each query.</p>
<p>ActiveRecord associations &#40;like <code>has_many</code> and <code>belongs_to</code>&#41; are great for getting an app up and running, but as you peruse your logs you&#8217;ll notice some things they&#8217;re doing that aren&#8217;t very efficient. Our app loads a lot of objects, each of which has lots of associated objects, some of which associate to other objects. If we&#8217;re displaying a list of Users, and each user has associated Emails &#40;via <code>has_many :emails</code>&#41;, and we want to render a list of users and their email addresses, we&#8217;ll probably see one query that loads all users, and then one query for each user loading his or her emails. </p>
<p>Adding an <code>:include</code> to the declaration is a good way to reduce these from N+1 to 2, but it doesn&#8217;t always work. I have never been able to comprehend AR&#8217;s alien logic, so my logs are often littered with queries despite my best efforts fiddling with the association declaration. Furthermore, AR is quite naive about object graphs: for example, <code>user.emails.first.user</code> will make an extra query and return a <em>different</em> user than the one you started with, even though they have the same id and you loaded the emails via <code>:include</code>.</p>
<p>So I&#8217;ve gotten good performance boosts by moving away from ActiveRecord and doing some nested queries by hand. Not by writing literal SQL, but by doing one query, extracting the necessary ids, and then doing the next query, and saving or plugging in values directly. This led naturally to Treasury &#40;see below&#41;.</p>
<p>Sometimes, of course, writing SQL is unavoidable; fortunately, AR allows it, and there are many people who are much better at that than I, so I won&#8217;t embarrass myself by discussing it further here.</p>
<h1>Object Caching and the Repository Pattern</h1>
<p>During my first pass at tuning Cohuman several months ago, I took a little time to write a library that implements a Repository Pattern. The <a href="http://github.com/alexch/treasury">Treasury</a> is a work in progress that sits in front of ActiveRecord &#40;and eventually, other ORMs&#41; and caches object instances as they pass through. If you then request an object via the Treasury, it will check in its cache and return a pointer to the existing object instead of making a query; if you specify a list of ids, then it will only query for the ones it doesn&#8217;t yet have. &#40;There are other features I won&#8217;t go into here, including a DSL for building queries&#8230; expect an upcoming article to officially introduce Treasury to the world.&#41;</p>
<p>I&#8217;ve heard that DataMapper has an object cache, but I haven&#8217;t yet dug into the details of how it works, so I don&#8217;t know if Treasury is redundant with it, or if it would make sense to plug in DM behind it. &#40;I&#8217;ve also heard it solves the N+1 query problem gracefully. Anyone want to proselytize DM in the comments?&#41; </p>
<p>All the caches I&#8217;ve mentioned only persist within a single request. This is probably a good thing, since allowing instances to persist between requests would open a can of data integrity, thread safety, and multi-host worms. But I can&#8217;t shake this vision I have of a sort of in-process memcache for Ruby objects, where multiple processes communicate changes to each other via TCP wormholes&#8230; Does anyone else share this vision, or am I doomed to wander the Ruby blog desert, mumbling incoherently at strangers?</p>
<p>The post <a href="http://pivotallabs.com/basic-ruby-webapp-performance-tuning-rails-or-sinatra/">Basic Ruby Webapp Performance Tuning (Rails or Sinatra)</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://pivotallabs.com/basic-ruby-webapp-performance-tuning-rails-or-sinatra/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>TextMate: The Last Straw</title>
		<link>http://pivotallabs.com/textmate-the-last-straw/</link>
		<comments>http://pivotallabs.com/textmate-the-last-straw/#comments</comments>
		<pubDate>Tue, 16 Mar 2010 21:36:00 +0000</pubDate>
		<dc:creator>Alex Chaffee</dc:creator>
				<category><![CDATA[Labs]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://pivotallabs.com/textmate-the-last-straw/</guid>
		<description><![CDATA[<p><p>That's it. I'm done with TextMate. It hasn't been updated in over 2 years, either for essential functionality &#40;replace in path&#41; or performance fixes &#40;searching through log files&#41; or UI issues &#40;how many boxes must you click to enable autosave?&#41; or bug fixes. Every few months the author pokes his head up and says "I'm working on TextMate 3.0!" and then disappears again, happily accepting new license fees into his PayPal account.</p>

<p>I've just been bitten twice in two weeks by a bug that caused not just data loss, but data mangling in a way that was very difficult to fix. Here's the rough steps to reproduce:</p>

<ol>
<li>Edit some files in TextMate</li>
<li>Leave TextMate running in the foreground</li>
<li>Switch to console and "git pull" in the latest code from your workmates</li>
<li>Run a search-and-replace that edits a file that was changed &#40;by someone else&#41; during the merge</li>
<li>Save that edit</li>
</ol>

<p>You'll see &#40;with "git diff"&#41; that your version of the file has your new post-merge changes... but it <em>also</em> has reverted your buddy's changes from the merge. It's like you decided that those changes were no good and reverted them yourself and then added your own.</p>

<p>If you fail to notice this before checking in, you will totally hose your version control... but just for that one file. You can't just revert a whole commit... you'll have to step through change by change to figure out which change was theirs, which change was yours, and which change <em>looks</em> like it was yours but was actually an inadvertent revert of theirs!</p>

<p>I can't work under these conditions. I'm switching to RubyMine today. See <a href="http://bjclark.me/2010/03/10/rubymine-a-love-story/">http://bjclark.me/2010/03/10/rubymine-a-love-story/</a> for why.</p>

<p>P.S. I just found a bug report for this dated 2008-04-02. That's just about 2 years ago for a critical data-losing bug. Woot.</p>

<ul>
<li><a href="http://ticket.macromates.com/show?ticket_id=B036CF83">http://ticket.macromates.com/show?ticket_id=B036CF83</a></li>
<li><a href="http://ticket.macromates.com/show?ticket_id=CACBB533">http://ticket.macromates.com/show?ticket_id=CACBB533</a></li>
</ul> <a href="http://pivotallabs.com/textmate-the-last-straw/">Continue reading <span class="meta-nav">&#8594;</span></a></p><p>The post <a href="http://pivotallabs.com/textmate-the-last-straw/">TextMate: The Last Straw</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>That&#8217;s it. I&#8217;m done with TextMate. It hasn&#8217;t been updated in over 2 years, either for essential functionality &#40;replace in path&#41; or performance fixes &#40;searching through log files&#41; or UI issues &#40;how many boxes must you click to enable autosave?&#41; or bug fixes. Every few months the author pokes his head up and says &#8220;I&#8217;m working on TextMate 3.0!&#8221; and then disappears again, happily accepting new license fees into his PayPal account.</p>
<p>I&#8217;ve just been bitten twice in two weeks by a bug that caused not just data loss, but data mangling in a way that was very difficult to fix. Here&#8217;s the rough steps to reproduce:</p>
<ol>
<li>Edit some files in TextMate</li>
<li>Leave TextMate running in the foreground</li>
<li>Switch to console and &#8220;git pull&#8221; in the latest code from your workmates</li>
<li>Run a search-and-replace that edits a file that was changed &#40;by someone else&#41; during the merge</li>
<li>Save that edit</li>
</ol>
<p>You&#8217;ll see &#40;with &#8220;git diff&#8221;&#41; that your version of the file has your new post-merge changes&#8230; but it <em>also</em> has reverted your buddy&#8217;s changes from the merge. It&#8217;s like you decided that those changes were no good and reverted them yourself and then added your own.</p>
<p>If you fail to notice this before checking in, you will totally hose your version control&#8230; but just for that one file. You can&#8217;t just revert a whole commit&#8230; you&#8217;ll have to step through change by change to figure out which change was theirs, which change was yours, and which change <em>looks</em> like it was yours but was actually an inadvertent revert of theirs!</p>
<p>I can&#8217;t work under these conditions. I&#8217;m switching to RubyMine today. See <a href="http://bjclark.me/2010/03/10/rubymine-a-love-story/">http://bjclark.me/2010/03/10/rubymine-a-love-story/</a> for why.</p>
<p>P.S. I just found a bug report for this dated 2008-04-02. That&#8217;s just about 2 years ago for a critical data-losing bug. Woot.</p>
<ul>
<li><a href="http://ticket.macromates.com/show?ticket_id=B036CF83">http://ticket.macromates.com/show?ticket_id=B036CF83</a></li>
<li><a href="http://ticket.macromates.com/show?ticket_id=CACBB533">http://ticket.macromates.com/show?ticket_id=CACBB533</a></li>
</ul>
<p>The post <a href="http://pivotallabs.com/textmate-the-last-straw/">TextMate: The Last Straw</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://pivotallabs.com/textmate-the-last-straw/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>UTC vs Ruby, ActiveRecord, Sinatra, Heroku and Postgres</title>
		<link>http://pivotallabs.com/utc-vs-ruby-activerecord-sinatra-heroku-and-postgres/</link>
		<comments>http://pivotallabs.com/utc-vs-ruby-activerecord-sinatra-heroku-and-postgres/#comments</comments>
		<pubDate>Fri, 22 Jan 2010 20:17:00 +0000</pubDate>
		<dc:creator>Alex Chaffee</dc:creator>
				<category><![CDATA[Labs]]></category>
		<category><![CDATA[activerecord]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[postgresql]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[ruby on rails]]></category>

		<guid isPermaLink="false">http://pivotallabs.com/utc-vs-ruby-activerecord-sinatra-heroku-and-postgres/</guid>
		<description><![CDATA[<p><p>Now that I'm starting to use DelayedJob to perform jobs in the future in my Heroku Sinatra app, its important that they happen at the scheduled time. But unless you pay attention, you'll find that times get mysteriously changed -- in my case, since I'm in San Francisco in the wintertime, by +/-8 hours -- which means that some conversion to or from UTC is being attempted, but it's only working halfway.</p>

<p>Trying to keep a handle on which libraries are attempting, and which are failing, to convert times is a losing battle, so I'm trying to do the right thing and save all my times in the database in UTC, and convert them to and from the user's local time as close to the UI as possible. Unfortunately, a variety of gotchas in Ruby and ActiveRecord and PostgreSQL makes this trickier than it should be. Here's a little catalog of my workarounds. </p> <a href="http://pivotallabs.com/utc-vs-ruby-activerecord-sinatra-heroku-and-postgres/">Continue reading <span class="meta-nav">&#8594;</span></a></p><p>The post <a href="http://pivotallabs.com/utc-vs-ruby-activerecord-sinatra-heroku-and-postgres/">UTC vs Ruby, ActiveRecord, Sinatra, Heroku and Postgres</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>Now that I&#8217;m starting to use DelayedJob to perform jobs in the future in my Heroku Sinatra app, its important that they happen at the scheduled time. But unless you pay attention, you&#8217;ll find that times get mysteriously changed &#8212; in my case, since I&#8217;m in San Francisco in the wintertime, by +/-8 hours &#8212; which means that some conversion to or from UTC is being attempted, but it&#8217;s only working halfway.</p>
<p>Trying to keep a handle on which libraries are attempting, and which are failing, to convert times is a losing battle, so I&#8217;m trying to do the right thing and save all my times in the database in UTC, and convert them to and from the user&#8217;s local time as close to the UI as possible. Unfortunately, a variety of gotchas in Ruby and ActiveRecord and PostgreSQL makes this trickier than it should be. Here&#8217;s a little catalog of my workarounds. </p>
<hr />
<p>You must set both <code>Time.zone = "UTC"</code> and <code>ActiveRecord::Base.default_timezone = :utc</code>. Since I&#8217;m using Sinatra, not Rails, this stuff goes either in <code>main</code> &#40;i.e. not inside any class&#41; right after <code>require 'active_record'</code>, or in a <code>configure</code> block in your app, depending on your preference.</p>
<hr />
<p>When ActiveRecord creates queries &#8212; which are used for both reading <strong>and</strong> writing, mind you &#8212; it will only convert to UTC times that are instances of ActiveSupport&#8217;s proprietary <code>TimeWithZone</code> class. It will <strong>not</strong> convert regular Ruby <code>Time</code> objects, even though <code>Time</code> objects are perfectly aware of their time zones, and AR is perfectly aware that you&#8217;d prefer they be written as UTC &#40;due to the <code>default_timezone</code> setting&#41;. This is clearly a bug IMHO, but the Rails core marked the bug as &#8220;will not fix&#8221;, so w/e. Here&#8217;s a monkey patch, courtesy of <a href="http://marklunds.com/articles/one/402">Peter Marklund</a>:</p>
<pre><code>  module ActiveRecord
    module ConnectionAdapters # :nodoc:
      module Quoting
        # Convert dates and times to UTC so that the following two will be equivalent:
        # Event.all&#40;:conditions =&gt; ["start_time &gt; ?", Time.zone.now]&#41;
        # Event.all&#40;:conditions =&gt; ["start_time &gt; ?", Time.now]&#41;
        def quoted_date&#40;value&#41;
          value.respond_to?&#40;:utc&#41; ? value.utc.to_s&#40;:db&#41; : value.to_s&#40;:db&#41;
        end
      end
    end
  end
</code></pre>
<hr />
<p>When outputting timestamps to a UI &#8212; either inside HTML or in a JSON API &#8212; you&#8217;ll probably want to use <code>Time#strftime</code>. Beware: on Mac OS X under Ruby 1.8, the <code>%z</code> &#40;lowercase Z&#41; selector will emit the <strong>local time zone</strong>, not the zone of the Time object you&#8217;ve called <code>strftime</code> on. The solution is to either use <code>%Z</code> &#40;capital Z&#41; or just a plain <code>Z</code> which stands for Zulu Time. The latter is OK if you know you&#8217;re using UTC, which, if you&#8217;ve followed my advice, you probably do. This is a pretty annoying issue, since it&#8217;s much safer to use <code>%z</code>&#8216;s hour offsets than <code>%Z</code>&#8216;s three-letter codes, since the three-letter codes can be ambiguous, and in any case require an extra conversion to time offset, so you may as well just emit the offset. </p>
<p>Here are some methods on Time you may want to use that work around this <code>%z</code> issue:</p>
<pre><code>  # Note: do NOT call this file 'time.rb' :-D

  require 'time'

  class Time
    def full_date_and_time
      strftime&#40;'%Y-%m-%d %H:%M:%S %Z'&#41;
    end

    def iso8601
      strftime&#40;'%Y-%m-%dT%H:%M:%SZ'&#41; # the final "Z" means "Zulu time" which is ok since we're now doing all times in UTC
    end
  end
</code></pre>
<p>That <code>iso8601</code> method comes in really handy when you&#8217;re using the excellent <a href="http://github.com/rmm5t/jquery-timeago">timeago jQuery plugin</a> by Ryan McGeary &#40;@rmm5t&#41;.</p>
<hr />
<p>By default PostgreSQL saves timestamps <em>sans</em> time zone, which means that ActiveRecord interprets them as being in the <code>default_timezone</code>. If you want to be extra clear and save them <em>with</em> time zone, you&#8217;ll have to change the Postgres adapter&#8217;s type mapping. ActiveRecord doesn&#8217;t let you configure this but here&#8217;s a monkey patch, courtesy of<br />
<a href="http://jacqueschirag.wordpress.com/2007/08/13/timestamp-support-rails-and-mysqlpostgresqloracle/">Chirag Patel</a> &#40;with a couple of mods&#41;:</p>
<pre><code>    require 'active_record/connection_adapters/postgresql_adapter'
    class ActiveRecord::ConnectionAdapters::PostgreSQLAdapter &lt; ActiveRecord::ConnectionAdapters::AbstractAdapter
      def native_database_types
        {
          :primary_key =&gt; "serial primary key".freeze,
          :string      =&gt; { :name =&gt; "character varying", :limit =&gt; 255 },
          :text        =&gt; { :name =&gt; "text" },
          :integer     =&gt; { :name =&gt; "integer" },
          :float       =&gt; { :name =&gt; "float" },
          :decimal     =&gt; { :name =&gt; "decimal" },
          :datetime    =&gt; { :name =&gt; "timestamp with time zone" },
          :timestamp   =&gt; { :name =&gt; "timestamp with time zone" },
          :time        =&gt; { :name =&gt; "time" },
          :date        =&gt; { :name =&gt; "date" },
          :binary      =&gt; { :name =&gt; "bytea" },
          :boolean     =&gt; { :name =&gt; "boolean" }
        }
      end
    end
</code></pre>
<p>It turned out that I didn&#8217;t need this, so I ended up commenting it out. It may be that storing timestamps <strong>with</strong>  time zones will cause a hiccup with some other random DB code, so watch out. If you do use it, and you&#8217;ve already got some data, make sure to write a migration that changes the types of all extant <code>datetime</code> and <code>timestamp</code> fields, and maybe a <a href="http://www.zetetic.net/blog/2009/03/23/moving-a-rails-app-to-utc-in-postgresql/">migration that shifts the times</a> too.</p>
<hr />
<p>That&#8217;s all I&#8217;ve got for right now. I&#8217;m sure some more problems will come up on <a href="http://eclipse.gsfc.nasa.gov/SEhelp/daylightsaving.html">March 14, 2010</a>&#8230;</p>
<p>The post <a href="http://pivotallabs.com/utc-vs-ruby-activerecord-sinatra-heroku-and-postgres/">UTC vs Ruby, ActiveRecord, Sinatra, Heroku and Postgres</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://pivotallabs.com/utc-vs-ruby-activerecord-sinatra-heroku-and-postgres/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>opacity (or, a paucity of transparency)</title>
		<link>http://pivotallabs.com/opacity-or-a-paucity-of-transparency/</link>
		<comments>http://pivotallabs.com/opacity-or-a-paucity-of-transparency/#comments</comments>
		<pubDate>Sun, 13 Dec 2009 23:48:00 +0000</pubDate>
		<dc:creator>Alex Chaffee</dc:creator>
				<category><![CDATA[Labs]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[html]]></category>

		<guid isPermaLink="false">http://pivotallabs.com/opacity-or-a-paucity-of-transparency/</guid>
		<description><![CDATA[<p><p>The rules for how to make parts of your HTML page translucent are kind of hard to understand -- in other words, the opacity rules are pretty opaque. &#40;Anyone who can make that into a good pun, let me know and I'll change the title of this article accordingly.&#41; The following represents the results of a couple of days of empirical research and as such may be incomplete or inadequate, but here goes.</p>

<p>In the brave new HTML5 world, with all the CSS gizmos supported by Safari and Chrome and Firefox, there are now three ways to make things translucent. And none of them works quite the way I naïvely expected.</p>

<p><em>One</em>. Use the "opacity" CSS attribute. This attribute works pretty well... at first. It applies to an element and all its children, but according to the spec it's meant to act as an upper bound on the opacity of all its children, and while it can technically be overridden, the overridden value is applied as a multiplier to the previous value, not as a whole separate value. So if you want some fully opaque children inside a translucent container, you can't get there from here. The children are always going to be at least as transparent as the parent -- in other words, they can't transcend their parent's transparency.</p>

<p>This is spelled out in detail in <a href="https://developer.mozilla.org/En/Useful_CSS_tips/Color_and_Background">https://developer.mozilla.org/En/Useful_CSS_tips/Color_and_Background</a> and as a solution they propose either pulling the child out of the normal hierarchy &#40;ugh -- that means you lose all the other CSS inherited styles and positioning&#41;, or ...</p>

<p><em>Two</em>. Make an alpha channel PNG and use it as the parent's background, probably with <code>background-repeat:repeat</code>. This is adequate, except that there's now <em>another</em>, cleaner way...</p>

<p><em>Three</em>. For the parent, use <code>background-color: rgba&#40;255, 255, 255, 0.5&#41;</code> &#40;where '0.5' is the opacity and '255,255,255' is the decimal RGB value&#41; -- that will work the same as an alpha PNG but without needing to go round-trip to Photoshop every time you want to change the color or level. Much better.</p>

<p>I have no idea what the level of support for rgba background colors is, but it seems to work in the latest Safari and Firefox so I'm happy.</p> <a href="http://pivotallabs.com/opacity-or-a-paucity-of-transparency/">Continue reading <span class="meta-nav">&#8594;</span></a></p><p>The post <a href="http://pivotallabs.com/opacity-or-a-paucity-of-transparency/">opacity (or, a paucity of transparency)</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>The rules for how to make parts of your HTML page translucent are kind of hard to understand &#8212; in other words, the opacity rules are pretty opaque. &#40;Anyone who can make that into a good pun, let me know and I&#8217;ll change the title of this article accordingly.&#41; The following represents the results of a couple of days of empirical research and as such may be incomplete or inadequate, but here goes.</p>
<p>In the brave new HTML5 world, with all the CSS gizmos supported by Safari and Chrome and Firefox, there are now three ways to make things translucent. And none of them works quite the way I naïvely expected.</p>
<p><em>One</em>. Use the &#8220;opacity&#8221; CSS attribute. This attribute works pretty well&#8230; at first. It applies to an element and all its children, but according to the spec it&#8217;s meant to act as an upper bound on the opacity of all its children, and while it can technically be overridden, the overridden value is applied as a multiplier to the previous value, not as a whole separate value. So if you want some fully opaque children inside a translucent container, you can&#8217;t get there from here. The children are always going to be at least as transparent as the parent &#8212; in other words, they can&#8217;t transcend their parent&#8217;s transparency.</p>
<p>This is spelled out in detail in <a href="https://developer.mozilla.org/En/Useful_CSS_tips/Color_and_Background">https://developer.mozilla.org/En/Useful_CSS_tips/Color_and_Background</a> and as a solution they propose either pulling the child out of the normal hierarchy &#40;ugh &#8212; that means you lose all the other CSS inherited styles and positioning&#41;, or &#8230;</p>
<p><em>Two</em>. Make an alpha channel PNG and use it as the parent&#8217;s background, probably with <code>background-repeat:repeat</code>. This is adequate, except that there&#8217;s now <em>another</em>, cleaner way&#8230;</p>
<p><em>Three</em>. For the parent, use <code>background-color: rgba&#40;255, 255, 255, 0.5&#41;</code> &#40;where &#8217;0.5&#8242; is the opacity and &#8217;255,255,255&#8242; is the decimal RGB value&#41; &#8212; that will work the same as an alpha PNG but without needing to go round-trip to Photoshop every time you want to change the color or level. Much better.</p>
<p>I have no idea what the level of support for rgba background colors is, but it seems to work in the latest Safari and Firefox so I&#8217;m happy.</p>
<p>The post <a href="http://pivotallabs.com/opacity-or-a-paucity-of-transparency/">opacity (or, a paucity of transparency)</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://pivotallabs.com/opacity-or-a-paucity-of-transparency/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic (Feed is rejected)
Page Caching using apc
Database Caching using apc
Object Caching 1167/1288 objects using apc

 Served from: pivotallabs.com @ 2013-06-19 13:59:26 by W3 Total Cache -->