Reputation: 3151
Created a Perl Module:
use ElectricCommander;
use strict;
use warnings;
package EC;
sub new
{
my $class = shift;
my $server = shift;
my $self = {};
bless( $self, $class );
$self->{EC} = ElectricCommander->new($server);
$self->{EC}->login("user", "password");
return $self;
}
1;
In script, is there a way to call the methods which are in ElectricCommander module? e.g, getJobStatus is present in ElectricCommander, can I do something like below?
use EC;
$obj = EC->new("myserver");
$obj->getJobDetails("1234");
Upvotes: 1
Views: 813
Reputation: 66873
Composition seems suitable here: add methods to EC
to dispatch to the other class's methods.
For instance
package EC;
use strict;
use warnings;
use ElectricCommander;
sub new {
...
$self->{EC} = ElectricCommander->new($server);
...
}
sub getJobDetails {
my ($self, @args) = @_;
$self->{EC}->getJobDetails(@args);
}
and you can call
use EC;
my $ec_obj = EC->new(...);
$ec_obj->getJobDetails(...);
You can also instantiate ElectricCommander
as class data instead of in new
so that its object is constructed once, when EC
is use
d. This is a design choice, whether you want EC
instances to each have its own ElectricCommander
object, constructed as they need it, or whether one object fits all EC
objects' needs.
If EC
were to truly extend ElectricCommander
– to use most of its methods, override some and add more – then you could have it inherit from (subclass) the ElectricCommander
.
Most of the time when you run into a need to use a class in another you want composition, sketched above, where a class uses capabilities of another (has-a relationship). Inheritance is suitable when you are building a carefully thought-out hierarchy of classes, where the parent lays down more general or abstract behaviors while its subclasses mostly specialize it (is-a relationship).
Upvotes: 1
Reputation: 385496
Simply add the following to the EC
package:
sub getJobDetails { shift->{EC}->getJobDetails(@_) }
If you have multiple methods of the kind, you can use build the wrappers dynamically.
BEGIN {
for my $method_name (qw( getJobDetails ... )) {
my $local_method = sub { shift->{EC}->$method_name(@_) };
no strict qw( refs );
*$method_name = $local_method;
}
}
You could even redirect all calls to methods that don't exist in EC
as follows:
use Carp qw( croak );
sub AUTOLOAD {
my $method_name = our $AUTOLOAD;
$method_name =~ s/^.*:://s;
return if $method_name eq 'DESTROY';
my $remote_method = $_[0]->can($method_name)
or croak(sprintf("Can't locate object method \"%s\" via package \"%s\"", $method_name, ref($_[0])));
my $local_method = sub { shift->{EC}->$remote_method(@_) };
no strict qw( refs );
*$method_name = $local_method;
goto &$method_name;
}
Upvotes: 1
Reputation: 85757
The easiest way to make all methods of ElectricCommander
available to instances of EC
is to make EC
a subclass of ElectricCommander
:
package EC;
use strict;
use warnings;
use parent 'ElectricCommander';
sub new
{
my $class = shift;
my $self = $class->SUPER::new(@_);
$self->login("user", "password");
return $self;
}
1;
Now
use EC;
my $obj = EC->new("myserver");
$obj->getJobDetails("1234");
should Just Work(tm).
Upvotes: 1