Archive for the 'Programming' Category

Posted on February 14, 2006 at 9:43 pm

Have you ever wanted to pass a block to an ActiveRecord model in order to pre-filter results?

module ActiveRecord
  class Base
    class < < self
      alias_method :find_without_filter, :find
      def find(*args)
        records = find_without_filter(*args)
        if block_given?
          filtered = []
          records.each do |record|
            filtered << record if yield(record)
          end
          filtered
        else
          records
        end
      end
    end
  end
end

This is a quick and dirty hack of a plugin, but it does the trick. I’m far from satisfied though. Soliciting opinions from those in the know. Email me.

Posted on January 5, 2006 at 6:40 pm

So, you’re developing Ruby on Rails apps on your shiny Mac and you want to get Growl notifications when your rake tasks are complete. Below, I will illustrate a fairly simple way to get Growl notifications when the test_units and test_functional tasks are complete. This method can be easily extended to any of the other tasks as well.

Prerequisites

  • Growl is installed and running.
  • The RubyCocoa framework is installed.
  • You also need a copy of the Ruby binding from the Growl source distribution. Go to the Growl Developer Downloads page and download the latest tarball or bzball. Extract the files and grab a copy of Growl.rb from the Bindings/ruby directory.

Integration with Rails

First, copy the Growl.rb file that you extracted from the Growl source into your Rails application’s lib directory. Name it growl.rb (all lowercase).

Next, create a new file called growl_notifications.rake in your Rails application’s lib/tasks directory. Copy and paste the following code into this file:

task :test_units do
  task_notifier 'Rake Task', 'Unit testing has completed.'
end

task :test_functional do |t|
  task_notifier 'Rake Task', 'Functional testing has completed.'
end

def task_notifier(title, message)
  begin
    require 'growl'
    n = GrowlNotifier.new('Rake',['RakeTask'],nil)
    n.register()
    n.notify('RakeTask', title, message)
  rescue
  end
end

Growl’s Ruby bindings allow you, among other things, to customize the icon that is displayed in the notification. Take a peek inside the growl.rb file for details.

I would like to extend this further to show the results from the tests in the notification message body. The results are part of a TestResult object, but I’m not sure if there is a way to get at this object by the time I create the notification. If you how I can do this, please let me know!

Posted on December 23, 2005 at 2:40 pm

I’ve found two implementations of the enhanced Soundex algorithm for Ruby. The first is written by Mike Stok, and is a port of his Perl implementation:

def soundex(string)
  copy = string.upcase.tr '^A-Z', ''
  return nil if copy.empty?
  first_letter = copy[0, 1]
  copy.tr_s! 'AEHIOUWYBFPVCGJKQSXZDTLMNR', '00000000111122222222334556'
  copy.sub!(/^(.)\1*/, '').gsub!(/0/, '')
  "#{first_letter}#{copy.ljust(3,"0")}"
end

The other is written by Michael Neumann and is available at the Ruby Application Archive.

I would recommend using Mike Stok’s implementation unless you need to be able to pass in an array. It’s twice as fast as the one at the RAA site. Both algorithms tested over 10,000 iterations:

                user        system    total    real
stok soundex:  0.290000   0.010000   0.300000 (  0.350133)
 raa soundex:  0.600000   0.010000   0.610000 (  0.708554)
Posted on at 1:06 pm

Ioan, Mica, and I went out for happy hour the other night and some how we got onto the topic of searching for names in a database when you weren’t sure of the spelling. This is a pretty easy thing to do using soundex, which is a simple and fairly effective algorithm.

If you aren’t familiar with soundex, then you might want to read up on this wikipedia article before going any further.

There are a couple of different variations of the soundex algorithm, so if you are going to use it you need to be aware of the differences. The original version discards vowels before removing duplicate letters, and the newer enhanced version of the algorithm removes the duplicated before discarding vowels. This has the effect that some names will have a different soundex code depending on which version of the algorithm is used.

Lets look at a couple of examples on the command line using PHP and MySQL (PHP uses the enhanced soundex algorithm and MySQL uses the original):

php -r "echo soundex('nemo');"
N500
mysql
mysql> select soundex("nemo");
+-----------------+
| soundex("nemo") |
+-----------------+
| N000            |
+-----------------+
1 row in set (0.02 sec)

As we can see, these return different results, so we can’t use them interchangeably. Since we need MySQL’s help here, we’re going to have to do the entire comparison in MySQL. MySQL supports a special SOUNDS LIKE sytax which is the same as saying SOUNDEX(expression1) = SOUNDEX(expression2).

PHP and MySQL

$name = "nemo";
$sql = "SELECT * FROM customers ";
$sql .= "WHERE first_name SOUNDS LIKE '{$name}'";
$result = mysql_query($sql);

Ruby on Rails
While we’re at it let’s look at how to do it in Rails with an ActiveRecord model. Assuming we have a Customer model:

name = "nemo"
customers = Customer.find_all :conditions => ["first_name SOUNDS LIKE ?", name]

Really simple, but helpful stuff.

Posted on November 28, 2005 at 1:57 pm

A couple of weeks ago, I hosted a 2.5 hour interactive presentation on Ruby and Ruby on Rails. The purpose of the presentation was to show the various ways in which Rails can improve our ability to build complex applications with small agile teams rather than large hierarchical teams.

There are 30 slides in the presentation, which I interspersed with live demonstrations in which we drilled down into some of the technologies and methodologies. The first section of slides is a quick intro to Ruby, which I borrowed heavily/outright copied from the Get to the Point! slides by Ryan Platt and John W. Long.

The slides are available in two flavors: