Returning an instance from a different class from new


(Jos Backus) #1

[For some reason I am no longer subscribed to ruby-talk and I don’t get any
mail back from the ctl address, which is why I have to use my provider’s
crappy newsserver :-(]

How do I make the following return Bar instead of Foo?

class Foo
def initialize(sel)
case sel
when "1"
return Bar.new
when "2"
return Baz.new
end
end
end

class Bar < Foo
def initialize
self
end
end

class Baz < Foo
def initialize
self
end
end

o = Foo.new(“1”)
p o.type

Thanks,
Jos

···


Jos Backus / /// Santa Clara, CA
_/ _/ _/
/ ///
_/ _/ _/ /
jos@catnook.com // //
/ use Std::Disclaimer;


(Joel VanderWerf) #2

Jos Backus wrote:

[For some reason I am no longer subscribed to ruby-talk and I don’t get any
mail back from the ctl address, which is why I have to use my provider’s
crappy newsserver :-(]

How do I make the following return Bar instead of Foo?

class Foo
def initialize(sel)
def self.new(sel=nil)
case sel
when "1"
return Bar.new
when "2"
return Baz.new
when nil
super()

···
end

end
end

class Bar < Foo
def initialize
self
end
end

class Baz < Foo
def initialize
self
end
end

o = Foo.new(“1”)
p o.type


(Alan Chen) #3

I would recommend breaking out the functionality in
Foo’s initialize into a factory function.

module FooFactory
def build(sel)
case sel
when "1"
return Bar.new
when "2"
return Baz.new
end
end

class Foo

end

class Bar < Foo

end
end

o = FooFactory.build(‘1’)
p o.type

···

On Fri, Jun 07, 2002 at 04:53:23AM +0900, Jos Backus wrote:

[For some reason I am no longer subscribed to ruby-talk and I don’t get any
mail back from the ctl address, which is why I have to use my provider’s
crappy newsserver :-(]

How do I make the following return Bar instead of Foo?

class Foo
def initialize(sel)
case sel
when "1"
return Bar.new
when "2"
return Baz.new
end
end
end

class Bar < Foo
def initialize
self
end
end

class Baz < Foo
def initialize
self
end
end

o = Foo.new(“1”)
p o.type

Thanks,
Jos


Alan Chen
Digikata LLC


(Jos Backus) #4

In article 3CFFC36E.DDC654F9@path.berkeley.edu,

Jos Backus wrote:

[For some reason I am no longer subscribed to ruby-talk and I don’t get any
mail back from the ctl address, which is why I have to use my provider’s
crappy newsserver :-(]

How do I make the following return Bar instead of Foo?

[clever mods deleted]

Thanks, but this depends on the Bar and Baz initializers to not have other
arguments. What if I want to pass in extra arguments as in the example below?

The way I understand this works is that you override the Foo new class method.
Foo.new(“1”) causes Bar.new to be called with sel == nil, which causes super()
(i.e. Foo.new) to be called. super() returns and then Bar.new returns and then
Foo.new returns with the new object created by Bar.new. Does that make sense?

(Btw, the app is a script to {un,}subscribe myself from different mailing
lists run by different types of mailing list managers.)

class Foo
def initialize(sel, f)
@f = f
end
def self.new(sel=nil)
case sel
when "1"
return Bar.new
when "2"
return Baz.new
when nil
super()
end
end
end

class Bar < Foo
end

class Baz < Foo
end

o = Foo.new(“1”, “field”)
p o.type
lizzy:~/mail/setup% ruby k
k:23:in `new’: wrong # of arguments(2 for 1) (ArgumentError)
from k:23

···

Joel VanderWerf vjoel@PATH.Berkeley.EDU wrote:

Jos Backus / /// Santa Clara, CA
_/ _/ _/
/ ///
_/ _/ _/ /
jos@catnook.com // //
/ use Std::Disclaimer;


(Jos Backus) #5

In article 20020606205418.GA4313@digikata.com,

I would recommend breaking out the functionality in
Foo’s initialize into a factory function.

Thanks, I understand this example (I think):

module FooFactory
def build(sel, field)
case sel
when "1"
return Bar.new(field)
when "2"
return Baz.new(field)
end
end
end

include FooFactory

class Foo
attr_accessor :field
def initialize(field)
@field = field
end
end

class Bar < Foo
def initialize(field)
super
end
end

class Baz < Foo
def initialize(field)
super
end
end

o = FooFactory.build(‘1’, “field1”)
p o.type, o.field
o = FooFactory.build(‘2’, “field2”)
p o.type, o.field

···

Alan Chen alan@digikata.com wrote:


Jos Backus / /// Santa Clara, CA
_/ _/ _/
/ ///
_/ _/ _/ /
jos@catnook.com // //
/ use Std::Disclaimer;


(Alan Chen) #6

BTW, if you change the signature of build to

def self.build(sel,field)

you can eliminate the need to do the “include FooFactory”

···

On Fri, Jun 07, 2002 at 08:33:34AM +0900, Jos Backus wrote:

Thanks, I understand this example (I think):

module FooFactory
def build(sel, field)
case sel
when "1"
return Bar.new(field)
when "2"
return Baz.new(field)
end
end
end

include FooFactory


Alan Chen
Digikata LLC


(Jos Backus) #7

In article 20020607005906.GA6618@digikata.com,

···

Alan Chen alan@digikata.com wrote:

module FooFactory
def build(sel, field)

BTW, if you change the signature of build to

def self.build(sel,field)

you can eliminate the need to do the “include FooFactory”

Yes, that works, but why? self.type prints as “Module”.

Thanks,
Jos

Jos Backus / /// Santa Clara, CA
_/ _/ _/
/ ///
_/ _/ _/ /
jos@catnook.com // //
/ use Std::Disclaimer;