Archive for September, 2008

Lone Star Ruby Conference 2008

Friday, September 26th, 2008

The videos are up for the recent Lone Star Ruby Conference 2008, and a lot of them look great. Rails Envy have compiled a short (21m) summary video of the talks which you can view or download here.

Just want to get downloading? Here’s a handy wget file so you can grab them all.

Song of the week – The Quickening

Thursday, September 25th, 2008

Continuing my run of one-man American power pop auteurs, here’s Roger Joseph Manning Jr. with The Quickening, the killer first track from his surprisingly excellent album Catnip Dynamite. Which is only available in Japan, a fact I am not sure what to make of.

Anyway, it’s another Queen-meets-ELO blast from the future past, and has a fucking synth solo, which basically guarantees I like it. Hope you do too.

The Quickening (mp3, 7MB)

No lyrics for this one – we’ve now dug so deep into obscurity that I cannot find them anywhere.

No kidding on the “excellent” comment, either – barring any surprises this album is a strong (top 3) contender for Album of the Year.

CouchDB session model for Rails

Friday, September 19th, 2008

Here’s my initial stab at a Rails Session model for CouchDB. The marshalling stuff is taken from the example SQLBypass class in the ActiveRecord code.

You’ll need a recent and trunk CouchDB, probably.

class CouchSession < Hash
  @ = CouchRest.database!('http://localhost:5984/sessions')
 
  attr_writer :data
 
  def self.find_by_session_id(session_id)
    self.new(@.get(session_id))
    rescue
    self.new(:id => session_id)
  end
 
  def self.marshal(data)   ActiveSupport::Base64.encode64(Marshal.dump(data)) if data end
  def self.unmarshal(data) Marshal.load(ActiveSupport::Base64.decode64(data)) if data end
 
  def initialize(attributes = {})
    self['_id'] = attributes['_id'] ||= attributes[:id]
    self['marshaled_data'] = attributes['marshaled_data'] ||= attributes[:marshalled_data]
    self['_rev'] = attributes['_rev'] if attributes['_rev']
  end
 
  def data
    unless 
      if self['marshaled_data']
        ,  = self.class.unmarshal(self['marshaled_data']) || {}, nil
      else
         = {}
      end
    end
    
  end
 
  def loaded?
    !! 
  end
 
  def session_id
    self['_id']
  end
 
  def save
    self['marshaled_data'] = self.class.marshal(data)
    self['data'] = data
    self['updated_at'] = Time.now
    save_record = @.save(self)
    self['_rev'] = save_record['rev']
  end
 
  def destroy
    @.delete(self['_id'])
  end
end

Nice and short – possibly the shortest Rails session class I have seen. The beauty of CouchRest/CouchDB! And we descend from hash so we can just save the object straight – after marshalling, of course. Cool, huh?

Note that I am actually writing the raw data as well as the marshalled data into the saved doc, for troubleshooting/interest purposes. Feel free to remove that.

Not pretty, but it works. Just save it like a normal model. You’ll need to put these into environment.rb:

config.action_controller.session_store = :active_record_store
CGI::Session::ActiveRecordStore.session_class = CouchSession

Note also that I have ignored any differentiation between the record ID and the session ID, negating the need for any special overrides in ApplicationController. However, the session IDs Rails generates are large and you might find them unattractive in CouchDB – it would be fairly simple to separate them, but then you’d need a new map view and an override. I feel it’s simpler to just use the Session ID as the doc ID and damn the torpedoes. YMMV.

Improvements? See something wrong with it? Let me know! ;-)

New Car Recommendations

Wednesday, September 17th, 2008

My friend recently asked me which new car she thought I should buy. I answered without hesitation – the Chery Amulet!

The Amulet has a lot of things going for it – stylish good looks, fuel economy, and its excellent build quality, but what I really like is its safety. The Chinese have really pulled out all the stops with this one – one look at the video below and you’ll see why, should an accident befall you, the Chery Amulet is the car to be in.

Assignment-compatible method_missing for Hash

Tuesday, September 16th, 2008

It was harder than I thought to write a useful method_missing class for Hash object, so I thought I’d share the fruit of my labours here.

class Hash
  def method_missing(m, *args, &block)
    method = m.to_s
    is_assignment = method[-1,1] == '='
    key = is_assignment ? method[0..-2] : method[0..-1]
    self[key] = args.first if args && is_assignment
    raise NoMethodError if !self[key]  
    return self[key]
  end
end

The difficulty lies in detecting and acting correctly in situations where we want to assign a value to the hash. Annoyingly, we have to go and actually check for an = which inexplicably gets attached to the end of the method if present.

Anyway, let’s see if it works:

>> hsh = {'ping' => 'pong'}
=> {"ping"=>"pong"}
>> hsh.ping
=> "pong"
>> hsh.ping2
NoMethodError: NoMethodError
        from /path/initializers/hacks.rb:31:in 'method_missing'
        from (irb):3
>> hsh.ping2 = "pong2"
=> "pong2"
>> hsh.ping2
=> "pong2"
>> hsh.keys
=> ["ping2", "ping"]

Yes, pretty basic, but I tried and failed to find anything that handled assignation that wasn’t a overblown nightmare or didn’t actually work so thought I’d share. As far as I can see this is the Simplest Thing That Can Possibly Work™ for this case, any improvements welcome.

Also note that we are standardising on hash keys being strings here. If you want to use that code with Symbol keys (popular in Rails), you’d have to extend it a bit. I had actually been under the impression that symbols and strings in hashes were going to be considered equal in Ruby 1.9 but apparently just in comparison, not access.

Another useful addition might be a hash of “acceptable” keys and their types as a class variable, which you’d feed with a DataMapper-style list of properties for the class. Check any inserts against that and you’ve got basic validations, sans the 20,000 lines of impenetrable black box magic of the popular mega-libraries.

One more thing: obviously I would not recommend actually putting this on Hash proper. Monkeypatching such a basic class is asking for trouble. Instead, create a new class descending from Hash, create your objects in that, and use it from there.

UPDATE: looks to be a decent library for doing something similar if you don’t trust my hacks or if you prefer a gem. Personally a gem has to do something pretty fucking special for me to require it these days but you might prefer otherwise. It’s too big for me and tries to do too much, most of which I don’t want. But, it’s a *lot* smaller than going for a full AR object or something.

On another note, something to bear in mind is that method_missing is slow. Using it to look inside a hash is about 5 times slower than accessing the key directly. That probably doesn’t matter, but it might pay to think twice before putting a method_missing call inside a loop that’s going to run a lot.

1,000,00 lookups (in seconds):

string hash: 1.041939
symbol hash: 0.699153
method missing hash: 4.645116

UPDATE 2: I’m a sucker for writing these little mini-benchmarks. The above was this code:

  def self.test
    count = 0
    hsh = {'ping' => "PONG"}
    time = Time.now
    1_000_000.times do
      count += 1 if hsh['ping'] == "PONG"
    end
    puts "string hash: " + (Time.now - time).to_s
    count = 0
    hsh = {:ping => "PONG"}
    time = Time.now
    1_000_000.times do
      count += 1 if hsh[:ping] == "PONG"
    end
    puts "symbol hash: " + (Time.now - time).to_s
    count = 0
    chsh = CouchHash.new # monkeypatched hash ; )
    chsh['ping'] = "PONG"
    time = Time.now
    1_000_000.times do
      count += 1 if chsh.ping == "PONG"
    end
    puts "method missing hash: " + (Time.now - time).to_s
 
  end

Note the speed. Not *that* bad. I thought about posting the code, as I always do, but thought “guh, I’m not posting that ugly crap. I can clean that up” .. so did. But the only way I could think of to trigger the different lookup methods was via an eval(), and what that did to the results is instructive.

  def self.test
    hsh = CouchHash.new
    hsh['ping'] = hsh[:ping] = "PONG"
    tests = ["['ping']", "[:ping]", ".ping"]
    tests.each do |call|
      time = Time.now
      1_000_000.times do
        raise if !(eval("hsh" + call) == "PONG")
      end
      puts call + ': ' + (Time.now - time).to_s
    end
  end

Wow, doesn’t that look better! Well, one thing doesn’t look better .. the results:

['ping']: 6.494104
[:ping]: 5.557214
.ping: 9.39655

Woah. The eval slowed us down by a factor of 10 in the case of the symbol lookup. Lesson: don’t use eval. Especially in combination with method_missing!!

Song of the Week – Whiskey & Speed

Tuesday, September 16th, 2008

Running about 6 months late with the new music here, but this one has to go up, better late than never. From Josh Fix, who basically sounds exactly like Freddie Mercury, comes yet another bombastic rock production – I can’t tell whether I like the actual song, or I’m just ecstatic that someone, somewhere, is still making music like this.

As anyone who knows me could attest, I’ve been incredibly down on American music for the last .. well, decade. After a brief explosion of creativity in the early 90s, the mainstream sound has degenerated into endless derivative Creed/Maroon 5 sound-alikes; not my taste at all. Some of the hiphop has been good, but that too started to sound awfully formulaic and most of the innovation has been in the production. There’s no dance output worth the space on one’s iPod and the “alternative” is anything but. Local bands might sound great to the drunken punters at a bar in Boston but don’t cut it compared to the global and historical corpus.

So I’m still down on American music, but like all things American, the average is low but the peaks are high, and one thing that America does seem to do well is produce these “auteur” types who get all depressed, get hepped up on goofballs, go hide in their house for a few years and then come out with some self-produced opus which happens to be fucking amazing. These albums are inevitably one-offs and the artists never live up to their debut. I’m thinking Bryan Scary, Jonny Polonsky, and now Josh Fix. There are probably more; they’re hard to find. My tastes seem to be so dissimilar to the US “music media” that they’re useless for finding new music; I have to rely on “carpet bombing”, serendipity and “guided randomness” in locating new music in an opaque market. Anyway.

This song starts like Radiohead circa “Iron Lung” (ie the last time I liked them), turns into Queen meets ELO, all made in LA in 2008. Awesome. Lyrics after the jump.

Josh Fix – Whiskey & Speed (mp3, 14.5M)

(more…)

Remove genres and iTunes Store links in iTunes 8

Thursday, September 11th, 2008

Open terminal and execute:

defaults write com.apple.iTunes show-store-arrow-links -bool FALSE 
defaults write com.apple.itunes show-genre-when-browsing -bool FALSE

Then restart iTunes.

Really annoying changes there Apple. Especially overwriting previously selected preferences to not show these features – then removing the preferences themselves. Probably only a matter of time before they remove the ability to disable them at all.

An open source replacement for iTunes, cloning the interface but without the crap, can not come soon enough.