Sundar R
Sundar R

Reputation: 14705

Giving alternate name to a module in Perl

Is it possible in Perl to assign a new name to a module for use within our code?

My purpose is: some of my clients want .xls files (Spreadsheet::Excel) and others .xlsx (Excel::Writer::XLSX). Since both the modules share most of their API, I'd like to be able to set that option once at the beginning of the project some place and then forget about it, which would also make it easy to change it in the future. It could also perhaps used for things like Mouse/Moose changes.

Upvotes: 4

Views: 192

Answers (2)

cjm
cjm

Reputation: 62109

It appears that all you really want is to be able to call class methods (like new) on a class whose name is determined at runtime. That's actually quite simple:

my $spreadsheet_class = 'Spreadsheet::Excel';
my $sheet = $spreadsheet_class->new;

When you call a method on a scalar variable that contains a string, Perl treats it as a class method on the package of that name. No fancy symbol table hacks required, and it works just fine under use strict.

Upvotes: 6

amon
amon

Reputation: 57640

You can alias the package stash of a class to a new name:

use strict; use warnings; use feature 'say';

package Foo;
sub new { bless [] => shift }
sub hi  { say "hi from Foo" }

package main;

# Alias the package to a new name:
local *F:: = *Foo::;  # it could make sense to drop the "local"

# make an objects
my $f = F->new;

# say hi!
say $f;
$f->hi;

Output:

Foo=ARRAY(0x9fa877c)
hi from Foo

Another solution would be to dynamically subclass the package you want.

use strict; use warnings; use feature 'say';

package Foo;
sub new { bless [] => shift }
sub hi  { say "hi from Foo" }

package Whatever;
# no contents

package main;

# let Whatever inherit from Foo:
# note that I assign, instead of `push` or `unshift` to guarantee single inheritance
@Whatever::ISA = 'Foo'; 

# make an objects
my $w = Whatever->new;

# say hi!
say $w;
$w->hi;

Output:

Whatever=ARRAY(0x9740758)
hi from Foo

Both of these solutions work at runtime and are very flexible. The 2nd solution relies on less magic, and seems cleaner. However, there is a chance that a module tests for ref($obj) eq 'Foo' instead of the correct blessed $obj and $obj->isa('Foo'), which may cause breakage.

Upvotes: 6

Related Questions