shenme has asked for the wisdom of the Perl Monks concerning the following question:
But I ran into a problem when trying to emulate a CGI.pm feature. Exporter allows you to group together related names for export, giving the set an export 'tag' name. You can then ask for only the groups of names that you really want, e.g.
CGI.pm permits a short-cut method to export the most useful of its tagged name sets, by asking for ":all". This collects together several export tag sets so thatuse Zowie qw( :phasers :masers :tasers !:water_pistols );
is equivalent to, but much shorter than, sayinguse CGI qw( :all );
use CGI qw( :html2 :html3 :netscape :form :cgi :internal );
But Exporter doesn't understand how to allow you to reference a tag set that contains further references to other tag sets.
I also really liked the CGI.pm idea of listing names for export only once. (Remember I've sworn off cut-n-paste) But Exporter requires that you list all exported names in @EXPORT or @EXPORT_OK. So names I've already listed in %EXPORT_TAGS would have to be duplicated to avoid errors.
It turns out that CGI.pm has quite a bit of magic to do these things. The few other common modules that do something similar also must use magic. And while now the Perl 5.8.x Exporter documentation mentions workarounds to get nearly the same effect, that code doesn't quite do everything I want.
I wanted to be able to
Here is some code for discussion:
package LISConst; use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); require Exporter; @ISA = qw(Exporter); $VERSION = '0.01'; @EXPORT = qw(); @EXPORT_OK = qw(); %EXPORT_TAGS = ( hdr_lens => [qw( LIS_TIF_HDR_LEN LIS_TIF_HDR_DATA_MAX LIS_PHY_HDR_LEN LIS_LR_HDR_LEN )], phyhdr_flags => [qw( . . . . )], lr_types => [qw( . . . . )], . . . . all => [qw( ? ? ? ? )], );
I've already listed names in the tag groups in %EXPORT_TAGS and I don't want to have to duplicate list them again in @EXPORT_OK. But Exporter will error with "LIS_TIF_HDR_LEN" is not exported by the LISConst module if I don't also get these names into @EXPORT_OK.
And what I really want for the ':all' tag set is
and end up with Exporter understanding that I'm exporting all the names within the referenced tag sets. Plus I'd like to be able use regular names mixed in with the set names.all => [qw( :hdr_lens :phyhdr_flags :lr_types )],
After looking at the various bits of library code plus the updated documentation in Perl 5.8.x I came up with this:
{ # Expand tag names into referenced name sets my %seen; $EXPORT_TAGS{all} = [ grep { !$seen{$_}++ } map { m/^:(.*)$/ ? @{$EXPORT_TAGS{$1}} : $_ } @{$EXPORT_TAGS{all}} ]; } { # Add tag set names not already listed into @EXPORT_OK my %seen; $seen{$_}++ foreach @EXPORT_OK; push @EXPORT_OK, grep { !$seen{$_}++ } @{$EXPORT_TAGS{$_}} foreach keys %EXPORT_TAGS; }
Have y'all seen other code like this, or perhaps a better (more insightful) solution to the problem? This seems to do what I want, but sure looks oogly.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: How to do "use Mumble ':all' " ala CGI.pm
by fergal (Chaplain) on Sep 20, 2004 at 09:35 UTC | |
by shenme (Priest) on Sep 20, 2004 at 13:31 UTC | |
|
Re: How to do "use Mumble ':all' " ala CGI.pm
by Zaxo (Archbishop) on Sep 20, 2004 at 05:06 UTC | |
by shenme (Priest) on Sep 20, 2004 at 05:13 UTC | |
by Zaxo (Archbishop) on Sep 20, 2004 at 05:45 UTC | |
|
Re: How to do "use Mumble ':all' " ala CGI.pm
by ikegami (Patriarch) on Sep 20, 2004 at 05:14 UTC | |
by ikegami (Patriarch) on Sep 20, 2004 at 05:55 UTC | |
|
Re: How to do "use Mumble ':all' " ala CGI.pm
by ysth (Canon) on Sep 20, 2004 at 06:39 UTC | |
by shenme (Priest) on Sep 20, 2004 at 06:46 UTC |