pernod has asked for the wisdom of the Perl Monks concerning the following question:

I am trying to create a hash of references for use in a factory-methodish subroutine. My idea is as follows:
my %constructors = ( "one" => \One->new, "two" => \Two->new ); sub factorish { my ( $type, @arguments ) = @_; my $consref = $constructors{ $type } or die "No handler for $type."; return $consref -> ( @arguments ); }

This does not compile, from the obvious reason that I don't have references in the hash. The reason I don't want to use

my %constructors = ( "one" => \&One::new, "two" => \&Two::new );

is that I will then have to explicitly fournish the package name in the factorish function, which defeats my cunning ploy of making an elegant function for choosing constructors.

A possible solution is to change the keys in the hash to the class name, and use this when calling the constructor:

my %constructors = ( "One" => \&One::new, "Two" => \&Two::new ); sub factorish { my ( $type, @arguments ) = @_; my $consref = $constructors{ $type } or die "No handler for $type."; return $consref -> ( $type, @arguments ); }

This is fine, but in cases where I don't know (nor care, for that matter) about the class name, this will not work. Am I trying something that is not possible, or is there a way around this?

pernod
--
Mischief. Mayhem. Soap.

Replies are listed 'Best First'.
Re: Storing references to constructors with context
by broquaint (Abbot) on Jul 10, 2003 at 15:39 UTC
    Or you could not bother with the references at all and just use a simple class method constructor e.g
    my %constructors = ( One => 'new', Two => 'new', ); sub factorish { my ( $type, @arguments ) = @_; die "No handler for $type." unless exists $constructors{ $type } and my $method = $constructors{ $type }; return $type->$method( @arguments ); }
    So the %constructors hash will consist of the class names and the method names of the constructors, simple as that :)
    HTH

    _________
    broquaint

Re: Storing references to constructors with context
by Jenda (Abbot) on Jul 10, 2003 at 21:04 UTC

    You want this:

    my %constructors = ( "one" => sub {One->new(@_)}, "two" => sub {Two->new(@_)} );

    Jenda
    Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.
       -- Rick Osborne

    Edit by castaway: Closed small tag in signature