Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Calling a class constructor as a function on input arguments

by princepawn (Parson)
on Jul 21, 2000 at 18:15 UTC ( #23581=perlquestion: print w/ replies, xml ) Need Help??
princepawn has asked for the wisdom of the Perl Monks concerning the following question:

Often one knows beforehand which subclass of base class in which to initialize one's method. However, in my case, I want to call a constructor as a function of the operating system that I am on. My first thought was to use a hash keyed on operating system name and store a reference to the new of each class as the value, ie:
%constructor = ( 'MSWin32' => \&FTP::Session::Win32->new, 'HPUX' => \&FTP::Session::HPUX->new )
Which brings up an additional question: since I am using an arrow in the above code instead of ::, will the first argument to the new be the package name? And will it only pass arguments if I had used ::? Thanks for any help guys.

Comment on Calling a class constructor as a function on input arguments
Select or Download Code
Re: Calling a class constructor as a function on input arguments
by cwest (Friar) on Jul 21, 2000 at 18:26 UTC
    I need more info about the context of the code you're going to write.

    However, here's a possible solution:

    my $os = eval "\\&FTP::Session::${^O}->new"; my %constor = ( $^O => $os );
    I'm pretty sure that's what you're looking for.

    Yes, the first argument is the package name, that's why constructors could look like this:

    sub new { bless {}, shift }; # which is equivalent to this sub new { my $class = shift @_; my $self = {}; my $ref = bless $self, $class; return $ref; } # Bless could actually be: bless {}, 'Package::Name';
    Enjoy!
    --
    Casey
    
Re: Calling a class constructor as a function on input arguments
by tye (Cardinal) on Jul 21, 2000 at 18:41 UTC

    This sounds like a job for anonymous subs:

    my %constructor= { MSWin32 => sub { FTP::Session::Win32->new( @_ ) }, HPUX => sub { FTP::Session::HPUX->new( @_ ) }, } my $ctor= $constructor{$^O}; die "No constructor for $^O" if ! $ctor; my $session= $ctor->( ... ); # Old Perl requires: $session= &$ctor( ... );

    The next best thing is UNIVERSAL::can(), which returns a reference to a named method. But then you need to cache each class name so that you can pass that in to the sub that you got a reference to:

    my %class= { MSWin32 => "FTP::Session::Win32", HPUX => "FTP::Session::HPUX", } my %constructor= { MSWin32 => FTP::Session::Win32->can("new"), HPUX => FTP::Session::HPUX->can( "new" ), } my $ctor= $constructor{$^O}; die "No constructor for $^O" if ! $ctor; my $session= $ctor->( $class{$^O}, ... ); # Old Perl requires: $session= &$ctor( $class{$^O}, ... );

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://23581]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (16)
As of 2015-07-06 13:35 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (74 votes), past polls