bobf has asked for the wisdom of the Perl Monks concerning the following question:
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:
obviously doesn't work, since $pkg::sub refers to the global variable $sub in the pkg namespace.my $pkg = 'Very::Long::Package::Name'; $pkg::sub;
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!
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: Alternative ways to fully qualify subroutine names
by idsfa (Vicar) on Feb 04, 2006 at 20:56 UTC | |
by bobf (Monsignor) on Feb 04, 2006 at 22:54 UTC | |
Re: Alternative ways to fully qualify subroutine names
by ikegami (Patriarch) on Feb 04, 2006 at 20:34 UTC | |
Re: Alternative ways to fully qualify subroutine names
by Tanktalus (Canon) on Feb 04, 2006 at 20:59 UTC | |
Re: Alternative ways to fully qualify subroutine names
by dakkar (Hermit) on Feb 05, 2006 at 14:26 UTC |
Back to
Seekers of Perl Wisdom