Monkeypatching For Robots

Posted on July 16, 2008

Even though Jeff Atwood believes that monkeypatching will lead to the apocalypse, I’ve discovered three cases where it has proven to be most useful.

Case 1: Dynamically Patching a Plug-in

Let’s face it. The Ruby on Rails wiki is littered with a cadre of unmaintained plugins. One example is file_column. Attachment_fu pretty much replaces this, but for whatever reason, the project that I’m working on is using the old warhorse of file upload packages. Recently, I’ve noticed several problems with file_column. The biggest issue is that it was written pre-Leopard So, file_column doesn’t support the new way of calling OS X’s file command. Combining monkeypatching with the Rails alias_method_chain allows us to patch the underlying code with minimal effort. And, keeping the dynamic patch separate, means that updating the plugin will not overwrite the patch.

# Rails lib/project_system.rb
module FileColumn
  def get_content_type_with_leopard_rules(fallback=nil)
    if not RUBY_PLATFORM.eql?('universal-darwin9.0')
      return get_content_type_for_leopard_without_apple_rules
    end
    if options[:file_exec]
      begin
        content_type = `#{@options[:file_exec]} -bI "#{@local_file_path}"`.chomp
        content_type = fallback unless $?.success?
        content_type.gsub!(/;.+$/,"") if content_type
        content_type
      rescue
        fallback
      end
    else
      fallback
    end
  end
  alias_method_chain :get_content_type, :leopard_rules
end



Case 2: Adding a Feature to a Plug-in

I’m a total Unix snob. Upper-case filenames injure what’s left of my dwindling sanity. File_column recklessly allows the user’s filenames to be saved directly to the filesystem. This has the side-effect of dumping a flagon full of mime-type detection FAIL when you view the files that have been uploaded to the server. Think of users uploading images named me.jpeg, me.JPG and me.Jpeg. Inconsistent capitalization is clearly evil and has to be sanitized before it gets to our precious disks. Using a monkeypatch with alias_method_chain, you can override file_column’s sanitize_filename method to convert the filename to lowercase.

# Rails lib/project_system.rb
module FileColumn
  class << self
    def sanitize_filename_with_downcase_rules(filename)
      self.sanitize_filename_without_downcase_rules(filename).downcase.gsub(/\.jpeg$/,'jpg')
    end
    alias_method_chain :sanitize_filename, :downcase_rules
  end
end



Case 3: Overriding a Native Ruby Class to Facilitate Symbol#to_proc Abuses

Ever since reading Reg Braithwaite’s (1..100).inject(&:+) post, I’ve been mystified and rather infatuated with Rails’ Symbol#to_proc method (which, incidentally, was only possible through Rails’ monkeypatch to the Ruby Symbol class).

Recently, I wrote a method to detect whether any one checkbox or radio button had been selected on a HTML form. This would serve as a form validation, but was complicated due to the fact that radio button values are arbitrary strings and checkbox values are posted as “0″ and “1″. The radio button values had to be converted to boolean by the controller, but ActiveRecord’s value_to_boolean method does not support this. Monkeypatching came to the rescue yet again and allowed me to override Object in an inject-friendly way.

# Rails lib/project_system.rb
class Object
  def selected?
    return true if self and self.is_a?(String) and self.include?('location')
    ActiveRecord::ConnectionAdapters::Column.value_to_boolean(self)
  end
end

Rather than writing a massive case statement or nested if/elsifs, we can just write the following in a model.

# Rails app/models/model_name.rb
def selected_place?
  places.collect(&:selected?).inject(&:|)
  # Logically, the same as places.collect(&:selected?).any?
end

The preceding loop calls our new Object selected? method on each of the location_types column, and the inject ORs all the data together.

I don’t really understand why Jeff is writing these slime pieces on monkeypatching. Jeff’s logic is equivalent to reasoning that driving should be outlawed because cars are dangerous. However, just because a few people drive drunk doesn’t mean that no one should drive! Oddly, I would get behind a law to make drunken monkeypatching a felony.

Muir Woods Panorama

Posted on April 09, 2007

I went out to Muir Woods in Mill Valley, California today and snapped this six shot, 165-degree panorama with my trusty Canon SD500. You can view the full-size version of this and all of my other panoramas here.


Little Feat / Meg’s B-day Celebration Gallery Now Online

Posted on November 28, 2005

I just uploaded another gallery on the old server today. I moved back to Gallery v1.51 because Gallery v2 had two deal-breaker problems: (1) RSS feeds didn’t work, and (2) The title fields were limited. Why? I think me and Bumper are going to reimplement Gallery in Ruby on Rails and RMagick over Christmas break. Keep watching this space for more information.

Gallery2

Posted on November 04, 2005

Gallery 1.51 ended up making me so mad that I installed Gallery2 today. It’s new and shiny and uses MySQL. I changed the link on the left panel to point to the gallery2 site, however, I think I need to leave my old gallery running at the original URL due to the fact that I have hardcoded links on involution.com and livejournal pointint to it… You can view the new gallery here.

Emma Long Gallery Online

Posted on September 25, 2005

And, here’s a gallery from Emma Long City Park’s Turkey Creek Trail. I managed to snap a macro shot of a little frog and a snake heedlessly slithering through the grass. A pretty good 2.75 mile trail if you ask me, and it’s like right across the street from my apartment.

Brushy Creek Gallery Up

Posted on September 25, 2005

I just put up a gallery of pics from Brushy Creek Park in Round Rock.

Mount Bonnell PTAssembler Panorama

Posted on July 16, 2005

I took a pretty good panoramic shot from the peak of Mount Bonnell. Visibility wasn’t optimal as I took the shot on one of those 101 degree afternoons last week. This is a five shot assembled panorama of seven megapixel shots from my Canon SD500. Enjoy.

Lightning Pictures

Posted on May 30, 2005

I took some sweet pictures of the lightning storm last night using burst-mode and 15-second exposures on my Canon SD500. I also learned about “Stitch Assist” mode which should help a lot with my PTAssembler work.

Guajolote Ranch

Posted on May 16, 2005

I took a trip out to the old Guajolote Ranch in Skidmore, Texas this weekend for a little fun in the sun. Of coure, there’s a mega gallery of pictures and videos online from the ATV Ridin’ / Pongo Pete Chasin’ Extravaganza. The whole trip was the exact opposite of pants.

Palo Duro and Caprock Canyon Pictures / Satellite Maps

Posted on May 12, 2005

I ambled out to old Palo Duro State Park last weekend. I added something like 237 images to my gallery. Also, I experimented around with some open sauce to “stitch” multiple images together from my camera. I used Max Lyons’ PTAssembler to do the stitching in conjunction with Enblend, AutoPano, and Panotools. All of this software makes stitching very easy, but I did have some color issues with my shots. I think that this was perhaps due to the fact that my camera was not in “manual” mode. Two of the shots turned out very well though, and I’m working with a local photolab to get them printed. In addition to the pictures and panoramas, I created three new satellite maps with GPS overlay tracks. I created these for Palo Duro Canyon, a Caprock Canyon, and one from downtown Austin last night.