One more suggestion that allows handling of other arguments besides the 
class selection:

   module Foo
      class Bar
         def self.new(kind, *args)
            return super(*args) if self != Foo::Bar
            case kind.downcase
               when 'baz'
                  return Baz.new(kind, *args)
               when 'zap'
                  return Zap.new(kind, *args)
            end
         end
      end

      class Baz < Bar
         class << self; protected :new; end
         def initialize(*args)
            @args = args
         end
      end

      class Zap < Bar
         class << self; protected :new; end
      end
   end

   fb = Foo::Bar.new('baz', "arg1", 2, [3])
   p fb # ==> #<Foo::Baz:0xb7d5b9b8 @args=["arg1", 2, [3]]>

-- 
       vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407