<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/atom10full.xsl" type="text/xsl" media="screen"?><?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/itemcontent.css" type="text/css" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" xml:lang="en-US">
  <title>jmacaulay.net - Home</title>
  <id>tag:jmacaulay.net,2008:mephisto/</id>
  <generator uri="http://mephistoblog.com" version="0.8.0">Mephisto Drax</generator>
  
  <link href="http://jmacaulay.net/" rel="alternate" type="text/html" />
  <updated>2008-04-22T15:04:02Z</updated>
  <link rel="self" href="http://feeds.feedburner.com/jmacaulay" type="application/atom+xml" /><entry xml:base="http://jmacaulay.net/">
    <author>
      <name>James MacAulay</name>
    </author>
    <id>tag:jmacaulay.net,2008-04-21:475</id>
    <published>2008-04-21T21:05:00Z</published>
    <updated>2008-04-22T15:04:02Z</updated>
    <category term="Code" />
    <category term="activemerchant" />
    <category term="activeshipping" />
    <category term="Code" />
    <category term="code" />
    <category term="rails" />
    <category term="Rails" />
    <category term="ruby" />
    <category term="shopify" />
    <category term="Shopify" />
    <link href="http://feeds.feedburner.com/~r/jmacaulay/~3/275517370/active-shipping" rel="alternate" type="text/html" />
    <title>Active Shipping</title>
<content type="html">
            &lt;p&gt;Active Shipping is now available under an open source license. &lt;a href="http://github.com/Shopify/active_shipping"&gt;It's on GitHub, here&lt;/a&gt;. Active Shipping is an extension for &lt;a href="http://www.activemerchant.org"&gt;Active Merchant&lt;/a&gt; which I wrote to let &lt;a href="http://www.shopify.com"&gt;Shopify&lt;/a&gt; users provide carrier-calculated shipping rates to their customers. You can easily include Active Shipping in your Rails project as a plugin (or in any other ruby project, for that matter) and start doing things like this:&lt;/p&gt;

&lt;pre class="ruby"&gt;
include ActiveMerchant::Shipping
usps = USPS.new(:login =&gt; '123JAMES4567')

origin = Location.new(:country =&gt; 'US', :zip =&gt; '90210')
destination = Location.new(:country =&gt; 'CA', :postal_code =&gt; 'K2P 0K3')

grams = 100
centimetres = [20,10,10]
packages = [Package.new(grams, centimetres)]

response = usps.find_rates(origin, destination, packages)
rates = response.rates.sort_by(&amp;:price)
cheapest = rates.map {|r| [ r.service_name,
                            r.price.to_f / 100, # rates returned in cents
                            r.currency]}.first
# =&gt; ["USPS First-Class Mail International", 1.62, "USD"]
&lt;/pre&gt;

&lt;p&gt;It's under active development and more details for contributing to the project can be found in the &lt;a href="http://github.com/shopify/active_shipping/tree/master#readme"&gt;README&lt;/a&gt;.&lt;/p&gt;
          </content>  <feedburner:origLink>http://jmacaulay.net/2008/4/21/active-shipping</feedburner:origLink></entry>
  <entry xml:base="http://jmacaulay.net/">
    <author>
      <name>James MacAulay</name>
    </author>
    <id>tag:jmacaulay.net,2008-02-14:474</id>
    <published>2008-02-14T04:29:00Z</published>
    <updated>2008-04-21T20:17:39Z</updated>
    <category term="Code" />
    <category term="Code" />
    <category term="code" />
    <category term="git" />
    <category term="migrations" />
    <category term="rails" />
    <category term="Rails" />
    <category term="rebase" />
    <category term="ruby" />
    <link href="http://feeds.feedburner.com/~r/jmacaulay/~3/234762626/rails-migrations-in-local-git-branches-not-so-atrocious-now" rel="alternate" type="text/html" />
    <title>Rails migrations in local git branches: not so atrocious now</title>
<content type="html">
            &lt;p&gt;One of the really annoying things about working on a Rails project with other developers is the inevitable conflicts with migration numbering. We recently switched to &lt;a href="http://git.or.cz/"&gt;Git&lt;/a&gt; for version control on &lt;a href="http://www.shopify.info"&gt;Shopify&lt;/a&gt;, and we all really love the ease of branching and merging to our hearts’ content. Here is a snippet of my workflow today:&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;Edit in my local “shipping” branch, adding some functionality to Shopify’s shipping system.&lt;/li&gt;
		&lt;li&gt;Commit a simple migration which adds a column that’s necessary for the aforementioned functionality.&lt;/li&gt;
		&lt;li&gt;Switch to my master branch and pull from our central repository to get the latest stuff.&lt;/li&gt;
		&lt;li&gt;Notice that &lt;a href="http://www.codyfauser.com/"&gt;Cody&lt;/a&gt; has added some crazy migration with an &lt;span class="caps"&gt;SQL&lt;/span&gt; query that I don’t really want to understand.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;Now, at this point, my usual required course of action would be to switch back to my shipping branch, migrate down, rename my migration (thankfully there was just one this time), then git-rebase onto the updated master branch and migrate back up again. This happens fairly often, and it makes the world a darker place.&lt;/p&gt;


	&lt;p&gt;So I wrote this script. Save it as .git/hooks/pre-rebase in your git repository and make it executable. Now whenever you rebase one of your local development branches it will detect potential migration conflicts with the target of the rebase and do most of the dirty work for you: it migrates down, renames your branch’s migrations so they’ll be at the end of the line, generates a new commit for you with the new renaming, then lets the rebase proceed.&lt;/p&gt;


	&lt;p&gt;It prompts before it does the renaming or committing, so if you really, &lt;em&gt;really&lt;/em&gt; want to have “23_foo.rb” and “23_bar.rb” after your rebase, then all the power to you. The prompts also give you a chance to ctrl-C out of the whole thing if you realize that the migrations will need more tweaking.&lt;/p&gt;


&lt;pre class="ruby"&gt;
#!/usr/bin/env ruby
# Save to .git/hooks/pre-rebase in your rails project and chmod +x
# 
# Checks for migration numbering conflicts and sorts them out automagically.
# Intended for use in multi-dev environments where you have a local branch for
# your own development that you rebase every so often onto an updated (i.e.
# freshly pulled) master branch. Conflicts will still come up, but this covers
# 90%+ of cases.

root_dir = File.expand_path(File.join(File.dirname(__FILE__), "..", ".."))
orig_dir = `pwd`.chomp

`cd #{root_dir}`

# uses parameters passed by git-rebase
upstream = ARGV[0]
subject = ARGV[1] || "HEAD" 
migration_changes = `git diff #{subject} #{upstream} --summary | grep db/migrate`
migration_ary= migration_changes.split(/\n/)

# not really deletions in terms of the rebase; just named so by the diff output
# really these "deletions" are just the current branch's migrations that don't exist
# in the target of the rebase
deletions = migration_ary.grep(/^\s*delete/)
other_changes = migration_ary - deletions

# filenames of any migrations affected in one way or another by the rebase
migration_files = migration_ary.map {|line| line.split.last }

version_pattern = /^db\/migrate\/(\d+)/

branch_migration_files = deletions.map {|line| line.split.last }.sort
deletion_versions = branch_migration_files.map {|file| file.match(version_pattern)[1].to_i }.sort
other_changes_versions = other_changes.map {|line| line.split.last.match(version_pattern)[1].to_i }.sort

# detect duplicate versions by looking at intersection of arrays
conflicts = deletion_versions &amp; other_changes_versions
conflict_files = migration_files.select {|f| conflicts.include? f.match(version_pattern)[1].to_i }

if conflicts.empty?
  puts "\nNo migration conflicts detected." 
else
  puts "\n*** Migration conflicts detected" 
  puts "\nLocal branch migrations not present in rebase target:" 
  puts(deletions.map {|line| line.gsub(/^.*(db\/migrate)/,      ' \1')}.join("\n") + "\n")
  puts "\nMigrations in rebase target to be added or modified:" 
  puts(other_changes.map {|line| line.gsub(/^.*(db\/migrate)/,  ' \1')}.join("\n") + "\n")

  print "\nFix by migrating down and renaming branch migrations? (Y/n) " 
  response = STDIN.readline.chomp.strip
  if response == '' or response =~ /^[Yy]/

    # migrate down
    puts (cmd = "rake db:migrate VERSION=#{(migration_files.map {|file| file.match(version_pattern)[1].to_i }).min - 1}")
    puts `#{cmd}`
    last_version = other_changes_versions.max

    # move each migration unique to the current branch to the end of the migration list
    branch_migration_files.each do |file|
      last_version += 1
      `git mv #{file} #{new_name}`
      puts "\nmoved #{file}" 
      puts "to    #{new_name}" 
    end

    print "Generate a new commit? (Y/n) " 
    response = STDIN.readline.chomp.strip
    if response == '' or response =~ /^[Yy]/
      puts(cmd = "git commit -a -m \"Renamed migrations\"")
      puts `#{cmd}`
    end

    puts "\n*** Be sure to run rake db:migrate after rebase has completed.\n" 
  else
    puts "Okay, not doing anything then." 
  end
end

`cd #{orig_dir}`

exit 0
&lt;/pre&gt;
          </content>  <feedburner:origLink>http://jmacaulay.net/2008/2/14/rails-migrations-in-local-git-branches-not-so-atrocious-now</feedburner:origLink></entry>
  <entry xml:base="http://jmacaulay.net/">
    <author>
      <name>James MacAulay</name>
    </author>
    <id>tag:jmacaulay.net,2007-11-09:48</id>
    <published>2007-11-09T03:37:00Z</published>
    <updated>2008-04-21T20:17:48Z</updated>
    <category term="Code" />
    <category term="Code" />
    <category term="code" />
    <category term="jaded pixel" />
    <category term="jaded Pixel" />
    <category term="Radiant" />
    <category term="radiant" />
    <category term="rails" />
    <category term="Rails" />
    <category term="shopify" />
    <category term="Shopify" />
    <link href="http://feeds.feedburner.com/~r/jmacaulay/~3/181988490/modified-rss_reader-radiant-extension" rel="alternate" type="text/html" />
    <title>Modified rss_reader Radiant extension</title>
<content type="html">
            &lt;p&gt;&lt;a href="http://www.shopify.info"&gt;&lt;img src="http://jmacaulay.net/assets/2007/11/9/shopify-news.png" alt="Shopify news on www.shopify.info" /&gt;&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;Part of my work at &lt;a href="http://jadedpixel.com"&gt;jaded Pixel&lt;/a&gt; a few months ago was development and writing for a new “brochure” site at &lt;a href="http://www.shopify.info"&gt;www.shopify.info&lt;/a&gt;. The current site, like the old one, is built with the fantastic &lt;a href="http://radiantcms.org"&gt;Radiant &lt;span class="caps"&gt;CMS&lt;/span&gt;&lt;/a&gt; and uses a modified version of the rss_reader extension from &lt;a href="http://scidept.com/"&gt;BJ Clark&lt;/a&gt;, &lt;a href="http://www.fn-group.com/"&gt;Loren Johnson&lt;/a&gt;, and Alessandro Preite Martinez.&lt;/p&gt;


	&lt;p&gt;We are using it to grab feeds that we publish in other places and re-display them to fit with the design of the site. For example our &lt;a href="http://shopify.info/screenshots"&gt;screenshots page&lt;/a&gt; is generated from our blog’s &lt;a href="http://jadedpixel.com/shop-of-the-moment"&gt;Shop of the Moment&lt;/a&gt; feed, and our &lt;a href="http://shopify.info/faq#customer-payment-methods"&gt;list of supported methods for accepting payment&lt;/a&gt; is fed directly by &lt;a href="http://app.shopify.com/services/gateways/all.xml"&gt;Shopify itself&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;Here is a modified version of the extension, available for your enjoyment and scrutiny:&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://jmacaulay.net/assets/2007/11/9/rss_reader-0.2a-jadedpixelmod.tgz"&gt;rss_reader-0.2a-jadedpixelmod.tgz&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;Just unpack with &lt;code&gt;tar xvzf rss_reader-0.2a-jadedpixelmod.tgz&lt;/code&gt; in your Radiant app’s root directory and it’ll put the necessary stuff in &lt;code&gt;lib&lt;/code&gt; and &lt;code&gt;vendor&lt;/code&gt;.&lt;/p&gt;


	&lt;p&gt;The modifications that I made add a few new features and, thanks to &lt;a href="http://blog.leetsoft.com"&gt;Tobi&lt;/a&gt;’s help, improved the robustness of the feed fetching code quite a bit. So for example, now you can order the feed however you want using a syntax similar to &lt;span class="caps"&gt;SQL&lt;/span&gt;’s &lt;code&gt;ORDER BY&lt;/code&gt;:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
&amp;lt;ul&amp;gt;

  &amp;lt;r:feed:items
      url="http://feeds.boingboing.net/boingboing/iBag" 
      order="creator ASC"&amp;gt;

    &amp;lt;li&amp;gt;&amp;lt;r:feed:link /&amp;gt;&amp;lt;/li&amp;gt;

  &amp;lt;/r:feed:items&amp;gt;

&amp;lt;/ul&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;You can also do headers to mark off sections:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
&amp;lt;ul&amp;gt;

  &amp;lt;r:feed:items
      url="http://feeds.boingboing.net/boingboing/iBag" 
      order="creator ASC"&amp;gt;

    &amp;lt;r:feed:header for="creator"&amp;gt;
      &amp;lt;h2&amp;gt;&amp;lt;r:feed:creator /&amp;gt;&amp;lt;/h2&amp;gt;
    &amp;lt;/r:feed:header&amp;gt;

    &amp;lt;li&amp;gt;&amp;lt;r:feed:link /&amp;gt;&amp;lt;/li&amp;gt;

  &amp;lt;/r:feed:items&amp;gt;

&amp;lt;/ul&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;This would show the code within the &lt;code&gt;&amp;lt;r:feed:header /&amp;gt;&lt;/code&gt; tag if and only if the “creator” attribute of the item is different from the previous item in the list. Thus, it would only make reasonable output if the feed were ordered by creator with the above method. Another more obvious grouping for headers would be the item’s “date” attribute. Yes, the date of a feed item has hours and minutes and seconds, but I made it so that a new header only appears on new days of the month.&lt;/p&gt;


	&lt;p&gt;You can sort items and group headers by date, title, content, creator, or link (i.e. the &lt;span class="caps"&gt;URL&lt;/span&gt; of the item). There are a few other options for the feed tags that I haven’t mentioned here but which are documented within the code.&lt;/p&gt;
          </content>  <feedburner:origLink>http://jmacaulay.net/2007/11/9/modified-rss_reader-radiant-extension</feedburner:origLink></entry>
  <entry xml:base="http://jmacaulay.net/">
    <author>
      <name>James MacAulay</name>
    </author>
    <id>tag:jmacaulay.net,2007-06-02:26</id>
    <published>2007-06-02T00:01:00Z</published>
    <updated>2008-02-14T02:32:03Z</updated>
    <category term="facebook hockey" />
    <link href="http://feeds.feedburner.com/~r/jmacaulay/~3/121512860/facebook-find-father-daughter-moment" rel="alternate" type="text/html" />
    <title>Facebook find: father-daughter moment</title>
<content type="html">
            &lt;p&gt;&lt;img src="http://jmacaulay.net/assets/2007/6/1/slaughter-those-fucking-ducks.png" alt="" /&gt;&lt;/p&gt;
          </content>  <feedburner:origLink>http://jmacaulay.net/2007/6/2/facebook-find-father-daughter-moment</feedburner:origLink></entry>
  <entry xml:base="http://jmacaulay.net/">
    <author>
      <name>James MacAulay</name>
    </author>
    <id>tag:jmacaulay.net,2007-05-25:25</id>
    <published>2007-05-25T15:16:00Z</published>
    <updated>2008-04-21T20:17:58Z</updated>
    <category term="Code" />
    <category term="bash" />
    <category term="OS X" />
    <category term="os x" />
    <category term="tips" />
    <category term="unix" />
    <link href="http://feeds.feedburner.com/~r/jmacaulay/~3/119659448/a-browser-history-for-the-command-line" rel="alternate" type="text/html" />
    <title>A browser history for the command line</title>
<content type="html">
            &lt;p&gt;I'm not a shell expert by any means. I'm certainly comfortable &lt;em&gt;enough&lt;/em&gt; on the command line and can pipe I/O fairly effectively; however, I know very little about bash scripting, and &lt;code&gt;irb&lt;/code&gt; and &lt;code&gt;svn&lt;/code&gt; really cover the vast majority of my Terminal usage aside from the ubiquitous &lt;code&gt;ls&lt;/code&gt; and &lt;code&gt;cd&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Even humble &lt;code&gt;cd&lt;/code&gt; has features which I had not initially fathomed: it was a wonderful moment when I recently saw &lt;a href="http://blog.leetsoft.com"&gt;Tobi&lt;/a&gt; use &lt;code&gt;cd -&lt;/code&gt; to flip back and forth from the last directory he had visited. I had been vaguely yearning for a way to go back directories for a while, but never got around to figuring it out. This &lt;code&gt;cd -&lt;/code&gt; thing wasn't really what I was looking for, though, because what I wanted was the equivalent of the back and forward buttons in a web browser and &lt;code&gt;cd -&lt;/code&gt; doesn't have a memory of anything more than the last directory you were in, via the environment variable &lt;code&gt;OLDPWD&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So I did some googling and found the necessary components to come up with something that is pretty darn satisfying.&lt;/p&gt;

&lt;h2&gt;How it works&lt;/h2&gt;

&lt;p&gt;I added three short functions in &lt;code&gt;~/.bash_profile&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;function cd {
    pushd "$@" &amp;gt; /dev/null
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Instead of its regular behaviour, &lt;code&gt;cd&lt;/code&gt; is now mapped to a nifty command called &lt;code&gt;pushd&lt;/code&gt;. This command takes a directory path as an argument and changes to that directory, just like &lt;code&gt;cd&lt;/code&gt; does, but it also stores the new path in a stack stored in an environment variable.&lt;/p&gt;

&lt;p&gt;It outputs the contents of that stack whenever you use &lt;code&gt;pushd&lt;/code&gt;, but I don't want to see it every time I change directory which is why I've redirected standard output to oblivion. &lt;code&gt;STDERR&lt;/code&gt; is left untouched so if I type a nonexistent directory then I will still find out about it. The &lt;code&gt;"$@"&lt;/code&gt; provides &lt;code&gt;pushd&lt;/code&gt; with all the arguments I pass to &lt;code&gt;cd&lt;/code&gt; separated by spaces, so everything stays the way I typed it; if I were to use &lt;code&gt;"$1"&lt;/code&gt; here, then it would choke on directory names with spaces in them.&lt;/p&gt;

&lt;p&gt;Now that we are building onto our stack of visited directories every time we &lt;code&gt;cd&lt;/code&gt; anywhere, we can use this as a browser history for the shell:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;function bd {
    if [ -z $1 ]; then
        n=1
    else
        n=$1
    fi
    pushd +$n &amp;gt; /dev/null
}

function fd {
    if [ -z $1 ]; then
        n=0
    else
        n=$[$1-1]
    fi
    pushd -$n &amp;gt; /dev/null
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;bd&lt;/code&gt; is for "back a directory" and &lt;code&gt;fd&lt;/code&gt; is for "forward a directory". We are still just using &lt;code&gt;pushd&lt;/code&gt; to manipulate the stack, but now we are using a different kind of argument for it. &lt;code&gt;pushd +n&lt;/code&gt; will rotate the stack backwards &lt;em&gt;n&lt;/em&gt; steps and change to that directory. We give &lt;em&gt;n&lt;/em&gt; a default value of 1 when no arguments are passed to &lt;code&gt;bd&lt;/code&gt;, and do &lt;code&gt;pushd +n&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For &lt;code&gt;fd&lt;/code&gt;, we rotate the other way. The default for &lt;em&gt;n&lt;/em&gt; is now 0 and we decrement the argument by 1 otherwise because &lt;code&gt;pushd -0&lt;/code&gt; refers to the bottom element of the stack. If we go forward before going backward, it doesn't care and will just rotate back to the first pushed directory (which is probably &lt;code&gt;~&lt;/code&gt;) and continue rotating from there, which is fine by me.&lt;/p&gt;

&lt;h2&gt;How it plays&lt;/h2&gt;

&lt;p&gt;So now I can go back and forward with &lt;code&gt;bd&lt;/code&gt; and &lt;code&gt;fd&lt;/code&gt; on their own, or do &lt;code&gt;bd 8&lt;/code&gt; to go back wherever I was eight directories ago and then maybe a little &lt;code&gt;fd 3&lt;/code&gt; to revise my search.&lt;/p&gt;

&lt;p&gt;Each shell gets its own history which just accumulates and accumulates. If I feel like keeping a Terminal window open for a few years then I can do &lt;code&gt;dirs -c&lt;/code&gt; to clear the stack. The way I have this set up, &lt;code&gt;cd&lt;/code&gt; without any arguments will swap back and forth between the current and last directory as &lt;code&gt;cd -&lt;/code&gt; would normally do, because that's how &lt;code&gt;pushd&lt;/code&gt; behaves when you type it by itself. Normally &lt;code&gt;cd&lt;/code&gt; by itself would be the equivalent of &lt;code&gt;cd ~&lt;/code&gt;, but I never used &lt;code&gt;cd&lt;/code&gt; like that in the first place so I'm not missing anything.&lt;/p&gt;

&lt;p&gt;There's obviously room to modify this formula and use this wonderful directory stack in different ways. Here is a &lt;a href="http://www.faqs.org/docs/bashman/bashref_73.html"&gt;straightforward reference for the directory stack commands in bash&lt;/a&gt;. There's also a few &lt;a href="http://www.faqs.org/docs/bashman/bashref_28.html"&gt;tilde expansions&lt;/a&gt; that reference the directory stack which some people might find useful.&lt;/p&gt;
          </content>  <feedburner:origLink>http://jmacaulay.net/2007/5/25/a-browser-history-for-the-command-line</feedburner:origLink></entry>
  <entry xml:base="http://jmacaulay.net/">
    <author>
      <name>James MacAulay</name>
    </author>
    <id>tag:jmacaulay.net,2007-05-05:24</id>
    <published>2007-05-05T19:12:00Z</published>
    <updated>2008-02-14T02:31:49Z</updated>
    <category term="harpy eagle" />
    <category term="monkey" />
    <category term="wikipedia find" />
    <link href="http://feeds.feedburner.com/~r/jmacaulay/~3/114475068/wikipedia-find-the-refined-nobility-of-the-harpy-eagle" rel="alternate" type="text/html" />
    <title>Wikipedia find: the refined nobility of the Harpy Eagle</title>
<content type="html">
            &lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Eagle#Species"&gt;&lt;img src="http://jmacaulay.net/assets/2007/5/5/harpy-eagle.png" alt="The powerful Harpy Eagle can easily grab a monkey weighing 5 kg and fly away with it."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Oh and besides monkeys, they also &lt;a href="http://en.wikipedia.org/wiki/American_Harpy_Eagle"&gt;tear apart &lt;em&gt;sloths&lt;/em&gt; on a regular basis&lt;/a&gt;, for crying out loud. When I ponder what pure evil might be, I think I will now invariably picture one of these bastards.&lt;/p&gt;
          </content>  <feedburner:origLink>http://jmacaulay.net/2007/5/5/wikipedia-find-the-refined-nobility-of-the-harpy-eagle</feedburner:origLink></entry>
  <entry xml:base="http://jmacaulay.net/">
    <author>
      <name>James MacAulay</name>
    </author>
    <id>tag:jmacaulay.net,2007-05-03:23</id>
    <published>2007-05-03T02:31:00Z</published>
    <updated>2008-02-14T02:31:40Z</updated>
    <category term="carleton" />
    <category term="jaded pixel" />
    <category term="me" />
    <category term="ogre" />
    <category term="rails" />
    <category term="ruby" />
    <category term="shopify" />
    <link href="http://feeds.feedburner.com/~r/jmacaulay/~3/113847987/my-bitchin-new-job" rel="alternate" type="text/html" />
    <title>My bitchin' new job</title>
<content type="html">
            &lt;p&gt;My exams are all done and I am now working full-time for &lt;a href="http://jadedpixel.com/" title="pixelsoup"&gt;jaded Pixel&lt;/a&gt;, developers of the incomparable &lt;a href="http://shopify.com/" title="Shopify"&gt;Shopify&lt;/a&gt;. I can't really think of a better place to work: I get to make money by programming with &lt;a href="http://www.ruby-lang.org/" title="Ruby"&gt;my&lt;/a&gt; &lt;a href="http://rubyonrails.org/" title="Rails"&gt;favourite&lt;/a&gt; &lt;a href="http://macromates.com/" title="TextMate"&gt;tools&lt;/a&gt;, working on a product which I love, on a team comprised of such a &lt;a href="http://jadedpixel.com/team/" title="The team"&gt;stellar group of co-workers&lt;/a&gt; I could almost &lt;em&gt;weep&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Oh, and my commute is a five minute walk.&lt;/p&gt;

&lt;p&gt;Yet another nice thing about this is that my wonderfully forward-thinking university is &lt;a href="http://www.carleton.ca/tim/" title="Technology Innovation Management at Carleton"&gt;taking care of much of my salary&lt;/a&gt;, specifically for the work that I'm doing on the various &lt;a href="http://www.activemerchant.org/" title="Active Merchant"&gt;open&lt;/a&gt;-&lt;a href="http://home.leetsoft.com/liquid" title="Liquid"&gt;source&lt;/a&gt; &lt;a href="http://home.leetsoft.com/opinion" title="Opinion"&gt;projects&lt;/a&gt; which jaded Pixel uses and maintains. &lt;/p&gt;

&lt;p&gt;I first met the jaded Pixel crew after installing &lt;a href="http://typosphere.org/" title="Typo"&gt;Typo&lt;/a&gt;, clicking through one of the default sidebar links to &lt;a href="http://blog.leetsoft.com/" title="Too-biased"&gt;Tobi's blog&lt;/a&gt;, and then scrolling down and seeing &lt;a href="http://blog.leetsoft.com/2005/12/7/ottawa-ruby-meetup" title="OGRE"&gt;this post&lt;/a&gt;. The post informed me that this Tobias fellow whose last name I wasn't sure how to pronounce did not live half-way around the world as I expected, but rather right here in Ottawa (and as I discovered shortly thereafter, within spitting distance of my apartment).&lt;/p&gt;

&lt;p&gt;So I started attending meetups for OGRE, the local Ruby users' group mentioned in said blog post, and ended up getting a short gig writing &lt;a href="http://help.shopify.com/" title="I basically did all the stuff in the left-hand column"&gt;help docs&lt;/a&gt; when Shopify officially launched almost a year ago. Now I'm back for the foreseeable future and doing a little bit of everything: back-end, front-end, user support, making &lt;a href="http://www.bridgehead.ca/en/ProductSearch.asp?SID=187686747099559088101939582211803216711472469198408236571202&amp;amp;amp;LangID=1&amp;amp;amp;ProductID=76" title="Ethiopian Limu"&gt;coffee&lt;/a&gt;, and stealing things from &lt;a href="http://tech.nologi.ca/" title="Clam!"&gt;Scott&lt;/a&gt;'s desk whenever possible. It rawks.&lt;/p&gt;
          </content>  <feedburner:origLink>http://jmacaulay.net/2007/5/3/my-bitchin-new-job</feedburner:origLink></entry>
  <entry xml:base="http://jmacaulay.net/">
    <author>
      <name>James MacAulay</name>
    </author>
    <id>tag:jmacaulay.net,2007-04-21:21</id>
    <published>2007-04-21T21:12:00Z</published>
    <updated>2008-02-14T02:31:33Z</updated>
    <category term="IM" />
    <category term="Microsoft" />
    <category term="UI" />
    <link href="http://feeds.feedburner.com/~r/jmacaulay/~3/110929272/microsoft-s-innovative-approach-to-user-security" rel="alternate" type="text/html" />
    <title>Microsoft's innovative approach to user security</title>
<content type="html">
            &lt;p&gt;&lt;em&gt;An excerpt out of my &lt;a href="http://adiumx.com/"&gt;Adium&lt;/a&gt; chat logs from a Thursday night chat over MSN. To set the stage: a number of jovially intoxicated barhoppers had just made their way loudly past my window…&lt;/em&gt;&lt;/p&gt;

&lt;ul class="conversation"&gt;
&lt;li&gt;&lt;span class="person1"&gt;James:&lt;/span&gt; hmm…screaming hooligans outside&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Could not send; a connection error occurred.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="person1"&gt;James:&lt;/span&gt; hmm…screaming hooligans outside&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Could not send; a connection error occurred.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="person1"&gt;James:&lt;/span&gt; you there?&lt;/li&gt;
&lt;li&gt;&lt;span class="person2"&gt;Caitlin:&lt;/span&gt; yeah?&lt;/li&gt;
&lt;li&gt;&lt;span class="person1"&gt;James:&lt;/span&gt; not letting me send a message a couple times&lt;/li&gt;
&lt;li&gt;&lt;span class="person1"&gt;James:&lt;/span&gt; hmm…screaming hooligans outside&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Could not send; a connection error occurred.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="person1"&gt;James:&lt;/span&gt; bah, it’s happening again…didn’t this happen before? maybe it was with someone else&lt;/li&gt;
&lt;li&gt;&lt;span class="person1"&gt;James:&lt;/span&gt; some random string of characters will cause a connection error&lt;/li&gt;
&lt;li&gt;&lt;span class="person1"&gt;James:&lt;/span&gt; screaming hooligans outside&lt;/li&gt;
&lt;li&gt;&lt;span class="person1"&gt;James:&lt;/span&gt; hmm…&lt;/li&gt;
&lt;li&gt;&lt;span class="person1"&gt;James:&lt;/span&gt; hmm… screaming hooligans outside&lt;/li&gt;
&lt;li&gt;&lt;span class="person1"&gt;James:&lt;/span&gt; hmm…screaming hooligans outside&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Could not send; a connection error occurred.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="person2"&gt;Caitlin:&lt;/span&gt; weird&lt;/li&gt;
&lt;li&gt;&lt;span class="person1"&gt;James:&lt;/span&gt; only does it when I remove the space between hmm… and screaming&lt;/li&gt;
&lt;li&gt;&lt;span class="person2"&gt;Caitlin:&lt;/span&gt; tell them to shut up&lt;/li&gt;
&lt;li&gt;&lt;span class="person1"&gt;James:&lt;/span&gt; .screaming&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Could not send; a connection error occurred.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="person1"&gt;James:&lt;/span&gt; .s&lt;/li&gt;
&lt;li&gt;&lt;span class="person1"&gt;James:&lt;/span&gt; .scre&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Could not send; a connection error occurred.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="person1"&gt;James:&lt;/span&gt; .sc&lt;/li&gt;
&lt;li&gt;&lt;span class="person1"&gt;James:&lt;/span&gt; .scr&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Could not send; a connection error occurred.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="person1"&gt;James:&lt;/span&gt; dot-s-c-r doesn’t work&lt;/li&gt;
&lt;li&gt;&lt;span class="person1"&gt;James:&lt;/span&gt; scr&lt;/li&gt;
&lt;li&gt;&lt;span class="person1"&gt;James:&lt;/span&gt; ..sc&lt;/li&gt;
&lt;li&gt;&lt;span class="person1"&gt;James:&lt;/span&gt; strange&lt;/li&gt;
&lt;li&gt;&lt;span class="person2"&gt;Caitlin:&lt;/span&gt; what’s wrong?&lt;/li&gt;
&lt;li&gt;&lt;span class="person1"&gt;James:&lt;/span&gt; nothing…just this string of characters being rejected by msn for whatever reason&lt;/li&gt;
&lt;li&gt;&lt;span class="person1"&gt;James:&lt;/span&gt; .scr&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Could not send; a connection error occurred.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="person1"&gt;James:&lt;/span&gt; try sending me [period]scr&lt;/li&gt;
&lt;li&gt;&lt;span class="person1"&gt;James:&lt;/span&gt; like . scr without the space&lt;/li&gt;
&lt;li&gt;&lt;span class="person1"&gt;James:&lt;/span&gt; .sca&lt;/li&gt;
&lt;li&gt;&lt;span class="person1"&gt;James:&lt;/span&gt; .scb&lt;/li&gt;
&lt;li&gt;&lt;span class="person1"&gt;James:&lt;/span&gt; .scc&lt;/li&gt;
&lt;li&gt;&lt;span class="person1"&gt;James:&lt;/span&gt; .scr&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Could not send; a connection error occurred.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="person1"&gt;James:&lt;/span&gt; .scd&lt;/li&gt;
&lt;li&gt;&lt;span class="person1"&gt;James:&lt;/span&gt; .sce&lt;/li&gt;
&lt;li&gt;&lt;span class="person1"&gt;James:&lt;/span&gt; .sar&lt;/li&gt;
&lt;li&gt;&lt;span class="person1"&gt;James:&lt;/span&gt; .bcr&lt;/li&gt;
&lt;li&gt;&lt;span class="person1"&gt;James:&lt;/span&gt; weird&lt;/li&gt;
&lt;li&gt;&lt;span class="person2"&gt;Caitlin:&lt;/span&gt; it’s gotta be your messenger&lt;/li&gt;
&lt;li&gt;&lt;span class="person1"&gt;James:&lt;/span&gt; did you send one to me?&lt;/li&gt;
&lt;li&gt;&lt;span class="person2"&gt;Caitlin:&lt;/span&gt; yup&lt;/li&gt;
&lt;li&gt;&lt;span class="person1"&gt;James:&lt;/span&gt; didn’t get it&lt;/li&gt;
&lt;li&gt;&lt;span class="person1"&gt;James:&lt;/span&gt; yeah I assume it’s my client &lt;em&gt;(Editor’s note: I’m sorry I doubted you, Adium.)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="person2"&gt;Caitlin:&lt;/span&gt; why were you trying to send it to me&lt;/li&gt;
&lt;li&gt;&lt;span class="person1"&gt;James:&lt;/span&gt; because I narrowed it down to that sequence of characters from my original message, which was “hmm…[no space]screaming hooligans outside”&lt;/li&gt;
&lt;li&gt;&lt;span class="person1"&gt;James:&lt;/span&gt; which gave me the initial connection error messages&lt;/li&gt;
&lt;li&gt;&lt;span class="person2"&gt;Caitlin:&lt;/span&gt; strange&lt;/li&gt;
&lt;li&gt;&lt;span class="person1"&gt;James:&lt;/span&gt; damn straight&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you haven’t guessed it yet, here is the &lt;a href="http://www.theregister.co.uk/2007/01/08/msn_bans_scroogle/"&gt;punchline&lt;/a&gt;, courtesy of Stu Tomlinson from the newly-renamed &lt;a href="http://www.pidgin.im/"&gt;Pidgin&lt;/a&gt; project (n&amp;eacute;e Gaim):&lt;/p&gt;

&lt;blockquote&gt;If you try to send a message containing any of the words “.pif”, “.scr”, “download.php” or “gallery.php” the message will be silently discarded. The official client from Microsoft will provide no indication to either the sender or recipient that the message didn’t go through.&lt;/blockquote&gt;

&lt;p&gt;(For those of you who might not know, .scr is the extension of Windows screen-saver files, which are basically just disguised .exe’s. This makes them a popular choice for those in the business of spreading worms and viruses and so forth.)&lt;/p&gt;

&lt;p&gt;I tried a bunch of “.scr” messages using Microsoft’s official messenger app for OS X instead of Adium, and it &lt;em&gt;did&lt;/em&gt; tell me they weren’t sent, but only after a long delay: I would send a bunch of the messages, and then twenty or thirty seconds later I would get the error messages for all of them. Regardless, MSN gives you no indication &lt;em&gt;why&lt;/em&gt; your message wasn’t sent, leaving people to wonder at the fickle gods of the internets for not letting them talk about screaming hooligans (or what-have-you).&lt;/p&gt;

&lt;p&gt;I don’t know how the MSN protocol works, but it seems pretty absurd that it would be designed in such a way that this kind of nightmarish hack would become necessary in the first place. What would be even scarier, of course, is if MSN actually &lt;em&gt;was&lt;/em&gt; a reasonably well-designed protocol, and Microsoft &lt;em&gt;freely chose&lt;/em&gt; to subject their users to this nonsense instead of implementing one of the multitude of obviously better solutions.&lt;/p&gt;
          </content>  <feedburner:origLink>http://jmacaulay.net/2007/4/21/microsoft-s-innovative-approach-to-user-security</feedburner:origLink></entry>
  <entry xml:base="http://jmacaulay.net/">
    <author>
      <name>James MacAulay</name>
    </author>
    <id>tag:jmacaulay.net,2007-03-19:18</id>
    <published>2007-03-19T19:19:00Z</published>
    <updated>2008-02-14T02:31:13Z</updated>
    <category term="logic puzzle" />
    <link href="http://feeds.feedburner.com/~r/jmacaulay/~3/102922576/blue-eyes" rel="alternate" type="text/html" />
    <title>Blue eyes</title>
<content type="html">
            &lt;p&gt;&lt;img src="http://farm1.static.flickr.com/135/344615181_2d30bd9bba_m.jpg" alt="eye" /&gt;&lt;/p&gt;

&lt;p&gt;One of my favourite webcomics is &lt;a href="http://xkcd.com"&gt;xkcd&lt;/a&gt; (“a webcomic of romance,
sarcasm, math, and language”). A while ago, the author posted the most satisfying logic puzzle I’ve ever mulled over. Take a minute to &lt;a href="http://xkcd.com/blue_eyes.html"&gt;read it&lt;/a&gt; before coming back.&lt;/p&gt;

&lt;p&gt;Intriguing, no? Depending on what kind of person you are, you might want to take a minute or a week trying to figure it out before either succeeding or wanting to just find the answer by any means necessary. I don’t have much patience for these things, so I didn’t wait long to read the &lt;a href="http://xkcd.com/solution.html"&gt;solution&lt;/a&gt;. Thankfully it was incredibly satisfying nonetheless.&lt;/p&gt;

&lt;p&gt;I absolutely love the follow-up questions &lt;a href="http://xkcd.com/about/"&gt;Randall&lt;/a&gt; provides. They are like little doorways into those strange and vast mindrealms of logic, highlighting all the ways that one can easily misunderstand the problem. If you’re having fun with all of this, there’s a fantastic amount of meaty discussion to chew on in &lt;a href="http://forums.xkcd.com/viewtopic.php?t=3"&gt;this xkcd forum thread&lt;/a&gt;. Once you get to the second page of the thread, you get into some really thought-provoking arguments suggesting that the solution may not be valid after all. I think I agree with the solution provided, but the process of peeling away the layers of superfluous information and getting to the crux of the issue is &lt;em&gt;really&lt;/em&gt; fun.&lt;/p&gt;
          </content>  <feedburner:origLink>http://jmacaulay.net/2007/3/19/blue-eyes</feedburner:origLink></entry>
  <entry xml:base="http://jmacaulay.net/">
    <author>
      <name>James MacAulay</name>
    </author>
    <id>tag:jmacaulay.net,2007-03-08:17</id>
    <published>2007-03-08T05:31:00Z</published>
    <updated>2008-02-14T02:31:03Z</updated>
    <category term="photography sex carleton" />
    <link href="http://feeds.feedburner.com/~r/jmacaulay/~3/100180805/guerilla-grafenbergology" rel="alternate" type="text/html" />
    <title>Guerilla GrÃ¤fenbergology</title>
<content type="html">
            &lt;p&gt;Last Saturday I saw a staging of the &lt;a href="http://en.wikipedia.org/wiki/Vagina_monologues"&gt;Vagina Monologues&lt;/a&gt; put on at Carleton, which a friend of mine was performing in. I thought it was great. They did a good job of expressing the main thesis of the piece. For those of you who don’t know, the main thesis is that vaginas are pretty frigging awesome and they should be treated as such.&lt;/p&gt;

&lt;p&gt;But the performances were just the first wave of the &lt;em&gt;vaginamania&lt;/em&gt; to come. This thoughtfully placed educational material was posted in the men’s washroom just outside &lt;a href="http://en.wikipedia.org/wiki/Carleton_University#Rooster.27s_Coffeehouse"&gt;Rooster’s&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.flickr.com/photo_zoom.gne?id=414304605&amp;amp;amp;size=l"&gt;&lt;img src="http://farm1.static.flickr.com/151/414304605_ac53cc57b6.jpg" alt="The female G-spot is no myth." /&gt;&lt;/a&gt;&lt;/p&gt;
          </content>  <feedburner:origLink>http://jmacaulay.net/2007/3/8/guerilla-grafenbergology</feedburner:origLink></entry>
  <entry xml:base="http://jmacaulay.net/">
    <author>
      <name>James MacAulay</name>
    </author>
    <id>tag:jmacaulay.net,2007-02-13:15</id>
    <published>2007-02-13T05:27:00Z</published>
    <updated>2008-02-14T02:30:53Z</updated>
    <category term="music rock link suggestion" />
    <link href="http://feeds.feedburner.com/~r/jmacaulay/~3/90130152/ss-cardiacs" rel="alternate" type="text/html" />
    <title>SS Cardiacs</title>
<content type="html">
            &lt;p&gt;I was recently reminded of &lt;a href="http://www.sscardiacs.com"&gt;this band called SS Cardiacs&lt;/a&gt;, which I know only because of a random CBC Radio 3 podcast that I listened to a year or so ago. This podcast contained a particularly ass-kicking track that I ended up listening to quite a bit over the period of a few weeks.&lt;/p&gt;

&lt;p&gt;Thanks to Radio 3’s resident pre-cogs and telepaths, they were able to have a track playing &lt;em&gt;from this very band&lt;/em&gt; as soon as I visited the &lt;a href="http://radio3.cbc.ca/"&gt;Radio 3 website&lt;/a&gt;. I happened to have another browser tab open at the time with the band’s label’s website and initially assumed that the music was coming from that page instead. Seriously, I think CBC has telepaths. People should investigate this.&lt;/p&gt;

&lt;p&gt;Anyways, thanks to Radio 3’s resident web developers and the fine job &lt;em&gt;they&lt;/em&gt; seem to be doing, I am able to provide you with a pleasant little link for you to &lt;strong&gt;hear that same kickass track&lt;/strong&gt; which introduced me to the band way back when:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://radio3.cbc.ca/play/band/SS-CARDIACS/Tell-Me-Again/"&gt;http://radio3.cbc.ca/play/band/SS-CARDIACS/Tell-Me-Again/&lt;/a&gt;&lt;/p&gt;
          </content>  <feedburner:origLink>http://jmacaulay.net/2007/2/13/ss-cardiacs</feedburner:origLink></entry>
  <entry xml:base="http://jmacaulay.net/">
    <author>
      <name>James MacAulay</name>
    </author>
    <id>tag:jmacaulay.net,2007-01-26:13</id>
    <published>2007-01-26T06:23:00Z</published>
    <updated>2008-02-14T02:30:44Z</updated>
    <category term="comic drawing wacom photoshop" />
    <link href="http://feeds.feedburner.com/~r/jmacaulay/~3/81788410/is-it-working" rel="alternate" type="text/html" />
    <title>Is it working?</title>
<content type="html">
            &lt;p&gt;&lt;a href="http://jmacaulay.net/assets/2007/1/26/isitworking.jpg"&gt;&lt;img src="http://jmacaulay.net/assets/2007/1/26/isitworking.jpg" alt="a short comic" /&gt;&lt;/a&gt;&lt;/p&gt;
          </content>  <feedburner:origLink>http://jmacaulay.net/2007/1/26/is-it-working</feedburner:origLink></entry>
  <entry xml:base="http://jmacaulay.net/">
    <author>
      <name>James MacAulay</name>
    </author>
    <id>tag:jmacaulay.net,2007-01-16:12</id>
    <published>2007-01-16T05:20:00Z</published>
    <updated>2008-02-14T02:30:37Z</updated>
    <category term="humour video nostalgia" />
    <link href="http://feeds.feedburner.com/~r/jmacaulay/~3/75896596/mr-overwijk-draws-a-perfect-circle" rel="alternate" type="text/html" />
    <title>Mr. Overwijk Draws a Perfect Circle</title>
<content type="html">
            &lt;p&gt;This guy taught me grade 12 math:&lt;/p&gt;

&lt;p&gt;&amp;lt;object height="350" width="425"&gt;
&amp;lt;param /&gt;
&amp;lt;/object&gt;&lt;/p&gt;

&lt;p&gt;A friend from high school passed the link my way just a minute ago. The funny thing is that when you &lt;a href="http://www.google.ca/search?q=Alexander+Overwijk"&gt;Google his name&lt;/a&gt; now, it’s all different copies and references to this suddenly popular video. Go Mr. Overwijk!&lt;/p&gt;
          </content>  <feedburner:origLink>http://jmacaulay.net/2007/1/16/mr-overwijk-draws-a-perfect-circle</feedburner:origLink></entry>
  <entry xml:base="http://jmacaulay.net/">
    <author>
      <name>James MacAulay</name>
    </author>
    <id>tag:jmacaulay.net,2006-12-25:10</id>
    <published>2006-12-25T23:24:00Z</published>
    <updated>2008-02-14T02:30:19Z</updated>
    <category term="art illustration drawing pen ink scan" />
    <link href="http://feeds.feedburner.com/~r/jmacaulay/~3/71207111/christmas-sketch" rel="alternate" type="text/html" />
    <title>Christmas sketch</title>
<content type="html">
            &lt;p&gt;&lt;img src="http://www.jmacaulay.net/assets/2006/12/25/2006-12-25.jpg" alt="woman" /&gt;&lt;/p&gt;
          </content>  <feedburner:origLink>http://jmacaulay.net/2006/12/25/christmas-sketch</feedburner:origLink></entry>
  <entry xml:base="http://jmacaulay.net/">
    <author>
      <name>James MacAulay</name>
    </author>
    <id>tag:jmacaulay.net,2006-12-11:8</id>
    <published>2006-12-11T07:37:00Z</published>
    <updated>2008-02-14T02:29:58Z</updated>
    <category term="keyboard shortcuts" />
    <category term="OS X" />
    <category term="tips" />
    <link href="http://feeds.feedburner.com/~r/jmacaulay/~3/71207112/dragging-and-dropping-with-ease" rel="alternate" type="text/html" />
    <title>Dragging and dropping with ease</title>
<content type="html">
            &lt;p&gt;&lt;img src="http://www.jmacaulay.net/assets/2006/12/11/option-drag.png" alt="OS X alias" /&gt;I have no idea how well-known this is, but I figured I’d better share this OS X tip because I have been pining for something like it &lt;em&gt;for ages&lt;/em&gt; without knowing it existed.&lt;/p&gt;

&lt;p&gt;Extended preamble: it’s been a little more than a year since switching to &lt;a href="http://www.penny-arcade.com/comic/2006/03/03"&gt;the other side&lt;/a&gt;, and during that time a particular nicety has gradually solidified in my mind as the one thing that I really miss about Windows (until tonight, that is): right-click-dragging. If you drag a file from point A to point B in Windows, but use the &lt;em&gt;right&lt;/em&gt; button to drag instead of the left, then you get a great mini-menu at the cursor wherever you drop the file. This menu lets you specify the nature of the drag, turning it into a copy, a move, or the creation of a shortcut. I use this &lt;em&gt;all the time&lt;/em&gt; when I’m on a Windows PC, because it is such an efficient and dare-I-say &lt;em&gt;elegant&lt;/em&gt; method of getting shit done.&lt;/p&gt;

&lt;p&gt;At least OS X has the same default left-click-drag behaviour: dragging between two mounted volumes produces a copy, and dragging within the same volume results in a move. This makes sense from an OS standpoint, because each of those operations is simpler (and therefore less error-prone) for the computer to perform in the respective context. It also makes sense from a user standpoint, because you usually don’t want too many copies of the same content on one drive, but between multiple drives you are probably intending to keep a copy on the original.&lt;/p&gt;

&lt;p&gt;No right-click-drag menu on a Mac, though. Not too surprising, since on most Macs the right mouse button is still a key &lt;em&gt;and&lt;/em&gt; a button. I actually don’t mind ctrl-clicking, and one reason is that I’m not forced to do it very often because context menus are not the central focus in OS X that they are in Windows.&lt;/p&gt;

&lt;p&gt;So that brings me to the great news: &lt;strong&gt;a right-click-drag menu would be completely redundant in OS X, because Apple has included something much nicer:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Drag the file to the target location, &lt;em&gt;while holding down any of these keys&lt;/em&gt;:
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Option&lt;/strong&gt; to perform a &lt;strong&gt;copy&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Command&lt;/strong&gt; to perform a &lt;strong&gt;move&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Option &lt;em&gt;and&lt;/em&gt; command&lt;/strong&gt; to &lt;strong&gt;create an alias&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Release the mouse button&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The mouse cursor will change appearance as you hold down the modifier keys to indicate a copy or alias operation. In fact you can change your mind mid-drag and switch up the keys whenever you want. The operation performed is only dependent on the keys being held when you release the mouse button.&lt;/p&gt;

&lt;p&gt;The resulting file will be named identically to the first, unless a copy or alias is being put in the same folder as the original (in which case the relevant suffix is appended).&lt;/p&gt;

&lt;p&gt;I came upon all this wonderful knowledge through a session of inspired experimentation: &lt;a href="http://www.tuaw.com/2006/12/07/wheres-your-dock/"&gt;this TUAW post&lt;/a&gt; reminded me about Apple’s great little &lt;a href="http://www.apple.com/pro/tips/"&gt;collection of random tips&lt;/a&gt;, which happens to contain &lt;a href="http://www.apple.com/pro/tips/copydelete.html"&gt;this tip about command-click-dragging between volumes&lt;/a&gt;, which led me to try out the other aforementioned key combinations.&lt;/p&gt;

&lt;p&gt;So is this as relieving to everyone else as it is to me?&lt;/p&gt;
          </content>  <feedburner:origLink>http://jmacaulay.net/2006/12/11/dragging-and-dropping-with-ease</feedburner:origLink></entry>
</feed>
