Is there a way to fully qualify a subroutine with the package name in a variable but without using eval?
This is possible with OO programming, where a long class name can be replaced with a variable:
my $class = 'Very::Long::Class::Name';
$class->method;
I want to do a similar thing for non-OO subroutines, so I can add clarity to the program by fully qualifying the sub name but still keep the call to a manageable length (and without sprinkling eval everywhere). Doing this:
my $pkg = 'Very::Long::Package::Name';
$pkg::sub;
obviously doesn't work, since
$pkg::sub refers to the global variable
$sub in the
pkg namespace.
I've considered the following options (example code below):
- Fully qualify the sub call, forget about the variable
This is the standard, I guess.
- Call the sub as a method (even though it isn't one)
This seems like a Bad Idea. Also, the contents of @_ will change depending on whether it is called as a sub or as a method (in which case the class name will be the first parameter).
- Assemble the call into a string, then use eval
Eww. This may achieve the primary goal, but it really clutters things up.
- Create a reference to the sub itself (not the package)
I don't mind doing it this way, but it requires a separate ref for every sub from the same package. I'd rather create a ref (or something) to the package so I only have one variable, then append the appropriate sub name as required.
- Import the subs into the caller's namespace, forget about fully qualifying it
This is how I'm doing it now, but the more subs I import the harder it becomes to keep track of where they are all from (hence the desire to use fully qualified names).
use strict;
use warnings;
{
package very::long::packagename;
sub foo
{
print '[', join( '][', @_ ), "]\n";
return "from sub foo\n";
}
}
{
package pkg;
our $foo = "foovar\n";
}
{
package bar;
# this refers to $foo in package 'pkg'
print $pkg::foo; # foovar
# fully qualified sub call
very::long::packagename::foo( 'param' ); # [param]
# create a ref to a fully qualified sub
my $subfoo_ref = \&very::long::packagename::foo;
print $subfoo_ref->( 'param' ); # from sub foo
$subfoo_ref->( 'param' ); # [param]
# call the sub as a method
my $pkg = 'very::long::packagename';
$pkg->foo( 'param' ); # [very::long::packagename][param]
# stringify the call, use eval
my $func_str = $pkg . "::foo( 'param' );";
eval $func_str; # [param]
}
Are there other ways of doing this that are not listed above? Comments regarding best practices are also appreciated.
Thanks!
Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
Read Where should I post X? if you're not absolutely sure you're posting in the right place.
Please read these before you post! —
Posts may use any of the Perl Monks Approved HTML tags:
- a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
| |
For: |
|
Use: |
| & | | & |
| < | | < |
| > | | > |
| [ | | [ |
| ] | | ] |
Link using PerlMonks shortcuts! What shortcuts can I use for linking?
See Writeup Formatting Tips and other pages linked from there for more info.