Archive for the '/dev/ruby' Category

Class Objects from Strings

Or "Let the code write the code".

One of the beauties of Rails is that the "convention over configuration" mandate means that not just program execution but program implementation are extremely predictable. This is very handy when you'd prefer to have your code write the code, as I needed to this afternoon when I wanted to call the same function on a bunch of different classes who's names were available for the operation as an array of strings.

I first started out by spending far too much time mucking around with eval() but that felt kludgy and I've never liked using eval() in any language - I'm naturally gun-shy when it comes to arbitrary code execution. I may know all the code paths into that point today but what about six months from now? Will I always remember never to pass user data through there accidentally?

A little more reading of the Kernel module and the Module class revealed a much cooler and ultimately much simpler way to implement the same functionality: const_get().

In a nutshell:

RUBY:
  1. begin
  2.   the_obj = Kernel.const_get( ( activity.model_name ).camelcase )
  3.   activity_events = the_obj.find( :all )
  4. rescue
  5.   the_obj = nil
  6. end

Much nicer but still not as nice as I'd like since I've had to wrap it in the begin / rescue block. For reasons unexplained const_defined? always returns false when used in here.

Note: Some googling afterwards showed up this very nice example by Matt Biddulph in which he used const_get() to walk the ActiveRecord models and create OmniGraffle diagrams of their relationships. That's a nice mash-up.

No Comments »

chris on March 15th 2007 in /dev/rails, /dev/ruby

Converting Seconds to Timeclock Display

This seems like functionality that should already be built into a Ruby class (Time?) or a Rails helper but I couldn't find it. This simply converts a chunk of seconds into hh:mm:ss display:

RUBY:
  1. time_str = [ seconds / 3600, seconds / 60 % 60, seconds % 60].map { |t| t.to_s.rjust( 2, '0' ) }.join( ':' )

which outputs 02:44:13.

What I'm really looking for is a conversion from seconds into the likes of

1 day, 8 hours, 44 minutes, 11 seconds

similar to what the Rails DateHelper does with distance_of_time_in_words. If you know of such a thing, please point me to it.

No Comments »

chris on March 14th 2007 in /dev/rails, /dev/ruby