From: Robert Klemme Date: 2006-12-03T22:00:10+09:00 Subject: Re: Factory pattern, abstract base class Daniel Berger wrote: > Hi all, > > I'm trying to setup an abstract base class as a factory for its > subclasses. The below code fails, as it always returns an instance of > Foo::Bar instead of one of its subclasses. > > module Foo > class Bar > def initialize(arg) > return if self.class != Foo::Bar > case arg.downcase > when 'baz' > return Baz.new(arg) > when 'zap' > return Zap.new(arg) > end > end > end > > class Baz < Bar > end > > class Zap < Bar > end > end > > fb = Foo::Bar.new('baz') > p fb # Returns Foo::Bar, but I want Foo::Baz > > Perhaps my whole approach is wrong. What is the proper way to achieve > what I'm after (without resorting to making Bar a module)? I am more inclined to question your approach than not. After all, if you know the class name (even if it is lowercase) you can use that directly to create instances - even if you do the crude "eval(foo).new" (using const_get is probably better anyway). My question for you is, what are you eventually trying to achieve? If you want to be able to use some kind of tag as a shortcut for the class to use for instance creation then using a Hash with class instances will be serving you well. module Foo CLASSES = {} def self.create(tag, *args,&bl) CLASSES[tag].new(*args,&bl) end class Bar CLASSES["baz"] = self end end Foo.create "baz" Whether you need that create method and the module at all is probably a different question. Kind regards robert