Close
Glad You're Ready. Let's Get Started!

Let us know how we can contact you.

Thank you!

We'll respond shortly.

Alex Chaffee

Posts By

LABS
Code Monkey

So I didn't go to whatever was going on in Baltimore this week, but I did do a whole bunch of open source coding over the past week or two:

  • TestFirst has a totally revamped design, including the downloadable (or cloneable) student exercises, and Learn JavaScript is now a first-class citizen
  • Wrong's expect alias now plays nicer with RSpec's expect
  • Rerun got a few new command-line options, including --clear and --exit so you can now easily rerun regular scripts (like rerun -cx rake test) when their files change
  • I submitted a patch to RubyGems to make the warningitis less ZOMG and more KTHXBY
  • Fonzie is a bookmarklet that tells you what font you're looking at
  • Twitter RSS is a bookmarklet that brings back the RSS link to the New Twitter UI
  • Showoff works better with nested bullets and missing showoff.json files -- so go nag Scott if you want him to accept my patches ;-)
  • I also finally got my git pre-commit hook correctly stripping whitespace, and

A lot of these projects, especially TestFirst, are aching for improvement, so if you feel like contributing code or courseware, or even just feature requests, please get in touch!

LABS
RubyGems Warningitis Outbreak

Have you upgraded RubyGems lately? Is your console suddenly filled with warnings like this?

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.

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:

gem update --system 1.7.2

Several experimental treatments are being hastily developed as well, but these have not yet been approved by the FDA. Check the "scary warnings are scary" bug thread for more details.

This has been a public health alert. Please do not panic. SARS masks and iodine pills are not recommended at this time.

LABS
Upgrading your Rakefile from RSpec 1.3 to RSpec 2

I'm updating Erector to RSpec 2 and came across two problems for which solutions were surprisingly difficult to Google. Here are my (finally successful) results.


Problem:

no such file to load -- spec/rake/spectask

Before:

require "spec/rake/spectask"  # RSpec 1.3

After:

require "rspec/core/rake_task" # RSpec 2.0

Problem:

undefined method `spec_files=' for #<RSpec::Core::RakeTask:0x00000101550aa8>

Before:

# RSpec 1.3
Spec::Rake::SpecTask.new(:core) do |spec|
  spec.spec_files = FileList['spec/erector/*_spec.rb']
  spec.spec_opts = ['--backtrace']
end

After:

# RSpec 2.0
RSpec::Core::RakeTask.new(:core) do |spec|
  spec.pattern = 'spec/erector/*_spec.rb'
  spec.rspec_opts = ['--backtrace']
end

See also http://github.com/rspec/rspec-core/blob/master/Upgrade.markdown (curiously cloaked from Google searches for the above problem strings).

LABS
Where, oh where has my gem server gone?

Uh-oh!

ERROR:  While executing gem ... (Gem::RemoteFetcher::FetchError)
    bad response Moved Permanently 301 (http://gems.rubyforge.org/latest_specs.4.8)

Whew!

gem sources -a http://rubygems.org/
gem sources -r http://gems.rubyforge.org/

Looks like they weren't kidding when they said to switch from rubyforge to rubygems.org (née gemcutter)!

[Edited to change "http://production.s3.rubygems.org/" to "http://rubygems.org/". Note that the trailing slash is significant!]

LABS
monkey patch of the day – activesupport vs. json_pure vs. Ruby 1.8

The error:

/Library/Ruby/Gems/1.8/gems/json_pure-1.4.3/lib/json/pure/generator.rb:232:in `__send__': undefined method `except' for #<JSON::Pure::Generator::State:0x102f245b0> (NoMethodError)

The environment: Ruby 1.8.7, DataMapper, dm-types, ActiveSupport, or just

require 'json/pure'
require 'active_support'

(as seen in http://gist.github.com/339528)

My solution:

# workaround for activesupport vs. json_pure vs. Ruby 1.8 glitch
if JSON.const_defined?(:Pure)
  class JSON::Pure::Generator::State
    include ActiveSupport::CoreExtensions::Hash::Except
  end
end

LABS
Windowed String Comparison for RSpec

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 Comparison object that overrides the failure message for .should == like this:

Strings differ at position 12:
expected: ..."efghijklmnopqrst"...
  actual: ..."efghijklXXopqrst"...

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 (or tries to) if the difference is near the beginning or end of the string (i.e. does or doesn't show ellipses).

http://gist.github.com/474363

For people who can't wait for this to get incorporated into RSpec proper, you can grab the code from github and require "comparison" in your spec_helper.rb and it'll override the existing RSpec == matcher. Or wait for Issue 9 to be pulled into version 2.1 (maybe). 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 assert_equals or whatever.

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.

LABS
Basic Ruby Webapp Performance Tuning (Rails or Sinatra)

My company launched our app, Cohuman, 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.

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 (in comments) 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.

LABS
TextMate: The Last Straw

That's it. I'm done with TextMate. It hasn't been updated in over 2 years, either for essential functionality (replace in path) or performance fixes (searching through log files) or UI issues (how many boxes must you click to enable autosave?) 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.

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:

  1. Edit some files in TextMate
  2. Leave TextMate running in the foreground
  3. Switch to console and "git pull" in the latest code from your workmates
  4. Run a search-and-replace that edits a file that was changed (by someone else) during the merge
  5. Save that edit

You'll see (with "git diff") that your version of the file has your new post-merge changes... but it also 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.

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 looks like it was yours but was actually an inadvertent revert of theirs!

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

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.

LABS
UTC vs Ruby, ActiveRecord, Sinatra, Heroku and Postgres

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.

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.

LABS
opacity (or, a paucity of transparency)

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. (Anyone who can make that into a good pun, let me know and I'll change the title of this article accordingly.) The following represents the results of a couple of days of empirical research and as such may be incomplete or inadequate, but here goes.

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.

One. 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.

This is spelled out in detail in https://developer.mozilla.org/En/Useful_CSS_tips/Color_and_Background and as a solution they propose either pulling the child out of the normal hierarchy (ugh -- that means you lose all the other CSS inherited styles and positioning), or ...

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

Three. For the parent, use background-color: rgba(255, 255, 255, 0.5) (where '0.5' is the opacity and '255,255,255' is the decimal RGB value) -- 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.

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.