Galaxy
Galaxy

Reputation: 2012

How can I call a Perl class with a shorter name?

I am writing a Perl module Galaxy::SGE::MakeJobSH with OO.

I want to use MakeJobSH->new() instead of Galaxy::SGE::MakeJobSH->new(), or some other shortnames. How can I do that?

Upvotes: 9

Views: 1565

Answers (5)

Hynek -Pichi- Vychodil
Hynek -Pichi- Vychodil

Reputation: 26121

It is almost exactly same approach as aliased but using standard Perl module:

use constant MakeJobSH => 'Galaxy::SGE::MakeJobSH';
my $job = MakeJobSH->new();

Upvotes: 1

brian d foy
brian d foy

Reputation: 132832

I don't bother with aliasing. I think it's the wrong way to go. If you're just looking for less to type, it might be the answer (but is a new dependency more benefit than risk?). I don't like the idea of tricking a maintenance programmer by hiding the real name from him since the aliasing happens a long way away from its use and there's no indication that what looks like a class name isn't a real class.

I'm mostly looking for easy subclassing, so I let the class decide for itself which module will implement a part.

For instance, I might start with a class that wants to use Foo to handle part of the job. I know that I might want to subclass Foo later, so I don't hard-code it:

 package Foo::Bar;

 sub foo_class { 'Foo' }

 sub new {
      ....
      eval "require $self->foo_class";
      $self->foo_class->do_something;
      }

In the application, I choose to use 'Foo::Bar':

 #!perl
 use Foo::Bar;

 my $obj = Foo::Bar->new();

Later, I need to specialise Foo, so I create a subclass overrides the parts I need:

 package Foo::Bar::Baz;
 use parent 'Foo::Bar';

 sub foo_class { 'Local::Foo::SomeFeature' }

 1;

Another application uses almost all of the same stuff, but with the small tweak:

 #!perl
 use Foo::Bar::Baz;

 my $obj = Foo::Bar::Baz->new();

You can also do a similar thing at the application level if you want to write one program and let users choose the class through configuration.

Upvotes: 3

ysth
ysth

Reputation: 98398

aliased works well when you want to only affect calls from packages that explicitly request the aliasing. If you want global aliasing of one namespace to another, use Package::Alias instead.

Upvotes: 1

cjm
cjm

Reputation: 62109

You can suggest that your users use the aliased module to load yours:

use aliased 'Galaxy::SGE::MakeJobSH';
my $job = MakeJobSH->new();

Or you could export your class name in a variable named $MakeJobSH;

use Galaxy::SGE::MakeJobSH;  # Assume this exports $MakeJobSH = 'Galaxy::SGE::MakeJobSH';
my $job = $MakeJobSH->new();

Or you could export a MakeJobSH function that returns your class name:

use Galaxy::SGE::MakeJobSH;  # Assume this exports the MakeJobSH function
my $job = MakeJobSH->new();

I'm not sure this is all that great an idea, though. People don't usually have to type the class name all that often.

Here's what you'd do in your class for the last two options:

package Galaxy::SGE::MakeJobSH;

use Exporter 'import';
our @EXPORT = qw(MakeJobSH $MakeJobSH);

our $MakeJobSH = __PACKAGE__;
sub MakeJobSH () { __PACKAGE__ };

Of course, you'd probably want to pick just one of those methods. I've just combined them to avoid duplicating examples.

Upvotes: 12

Galaxy
Galaxy

Reputation: 2012

Thanks cjm.

I just choose to inline aliased.

require Exporter;

our @ISA = qw(Exporter);
our @EXPORT = qw(MakeJobSH);

sub MakeJobSH() {return 'Galaxy::SGE::MakeJobSH';}

Upvotes: 2

Related Questions