James Edward Gray II wrote: > On Dec 3, 2006, at 12:04 AM, Joel VanderWerf wrote: > >> James Edward Gray II wrote: >>> On Dec 2, 2006, at 7:27 PM, Joel VanderWerf wrote: >>>> module Foo >>>> class Bar >>>> def self.new(arg) >>>> return super() if self != Foo::Bar >>> I don't believe that line does what you intend. Try using your code >>> with something like: >>> fb = Foo::Baz.new('baz') # => #<Foo::Baz:0x1e2ea0> >> >> It's a little funny to say "baz" twice, is your point? > > No. My point was that the original code forces the call to be made on > Foo::bar by returning nil otherwise. Your code created the object. Ah, I see. You are interpreting this line in the original code: module Foo class Bar def initialize(arg) return if self.class != Foo::Bar # <--- here as a way of preventing direct instantiation of subclasses (it doesn't actually do that, but maybe that's what was intended). If that was the OP's intent, then I suggest adding protected declarations to what I posted before--see below. The line return super() if self != Foo::Bar is necessary so that when Bar.new sees the "baz" case and calls Baz.new, which is implemented not in Baz but back up in Bar, the call can be handled by Object.new, which will create a Baz instance and call #initialize on it. Does that make sense? Here's the modified code: module Foo class Bar def self.new(arg) return super() if self != Foo::Bar case arg.downcase when 'baz' return Baz.new(arg) when 'zap' return Zap.new(arg) end end end class Baz < Bar class << self; protected :new; end end class Zap < Bar class << self; protected :new; end end end fb = Foo::Bar.new('baz') p fb # ==> #<Foo::Baz:0xb7d66c3c> Foo::Baz.new("baz") # fails -- vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407