Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change

Re: Inheritance: parent class determine which child class to use?

by GrandFather (Sage)
on Jul 30, 2012 at 20:35 UTC ( #984514=note: print w/replies, xml ) Need Help??

in reply to Inheritance: parent class determine which child class to use?

You are looking something rather like the (appropriately, given the example) factory pattern. The "method" used to create an instance is the factory.

The following is based on Moritz' sample, cleaned up and tested: :-)

use strict; use warnings; package Car; my %carByType; sub new { my ($class, %opts) = @_; return bless \%opts, $class; } sub factory { my (%opts) = @_; die "Don't know how to make a new car" if !exists $opts{name} || !exists $carByType{$opts{name}}; $carByType{$opts{name}}->new(%opts); } sub describe { my ($self) = @_; my ($make) = ref ($self) =~ m/^Car::(.*)/; print "$make $self->{name}\n"; } sub REGISTER_TYPE { my ($type, $name) = @_; $carByType{$name} = $type; } package Car::BMW; our @ISA = qw/Car/; Car::BMW->REGISTER_TYPE('Z1'); Car::BMW->REGISTER_TYPE('Z3'); package main; my $z1 = Car::factory(name => 'Z1'); $z1->describe();


True laziness is hard work

Replies are listed 'Best First'.
Re^2: Inheritance: parent class determine which child class to use?
by fbicknel (Beadle) on Jul 31, 2012 at 14:05 UTC

    Thanks! I made some modifications and used the idea. Mine turned out something like:

    1 package Local::Multipath; ... 45 my %mpByType; 46 47 sub new { 48 my ($class, %opts) = @_; 49 return bless \%opts, $class; 50 } 51 52 sub factory { 53 my (%opts) = @_; 54 croak ("Missing parameters!") unless exists $opts{co}; 55 my $type = _whichType; 56 my $module = "Local::Multipath::$type"; 57 { 58 eval "use $module"; 59 } 60 croak "Failed to load module $module: $@\n" if $@; 61 $mpByType{$type}->new (%opts); 62 } 63 64 sub REGISTER_TYPE { 65 my ($type) = @_; 66 my ($name) = $type =~ m/Multipath::(.*)/; 67 $mpByType{$name} = $type; 68 }
    1 package Local::Multipath::DMMP; 2 use strict; 3 use warnings; ... 7 8 REGISTER_TYPE Local::Multipath::DMMP; ...
    ... somewhere else in code land ...
    my $mp = Local::Multipath::factory (co => $conf);

    The _whichType function returns 'DMMP' or 'Powerpath' after sniffing around for what we actually have.

    It's nearly the same as what you suggested, but I didn't need the added 'type' attribute in this case, so simpler.

    I could almost get away without the REGISTER_TYPE, but it has the added appeal of not having to hard code the things Multipath can handle. Just add a new module like the DMMP module shown to add new capabilities;

    Thanks for the suggestion: perfect synergy.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://984514]
[Discipulus]: robotart

How do I use this? | Other CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (8)
As of 2017-05-23 10:58 GMT
Find Nodes?
    Voting Booth?