shemp has asked for the wisdom of the Perl Monks concerning the following question:

Sorry if the title is not quite appropriate, i dont even know how to properly name what i am asking.

When using a module in a script, CGI.pm for what im specifically working on, function sets can be imported with a use statement such as:
use CGI qw(:form);
...or other funciton sets, etc

I would like to access a list of what functions were explicitly imported. I have my own class that is derived from CGI.pm, which messes with form param names (among other things), and i want to write an AUTOLOAD into my class that intercepts calls to the :form functions, and do certain things before passing them on to CGI.

This will help me immensely. Unfortunately, i know virtually nothing about the mechanisms used for this sort of thing.

Thanks much

Update: I cheated in my own way, and created an autoload that doesnt bother checking the method name, but determines what to do by the param list (using named params)

sub AUTOLOAD { my $self = shift @_; (my $method = $AUTOLOAD) =~ s/.*:://; return if $method eq "DESTROY"; if ( ! (@_ % 2) ) { my %args = @_; if ( exists($args{-page}) && exists($args{-param}) ) { # appears to be a form element creation call to CGI $args{-name} = $self->CreateRawFieldName(-page => $args{ +-page}, -param => $args{ +-param}); delete $args{-page}; delete $args{-param}; my $parent_call = 'SUPER::' . $method; return $self->$parent_call(%args); } } }
Not exactly what i wanted to do, but it works for my purposes, it just feels unclean.

Replies are listed 'Best First'.
Re: Imported symbol names
by gellyfish (Monsignor) on Jul 08, 2004 at 15:55 UTC

    The cheating way of doing this is to observe the symbols table of package main before and after importing the symbols for ':form' :

    use CGI; + my %symbols; + for my $foo ( keys %main:: ) { $symbols{$foo} = 1; } + CGI::import 'CGI',':form'; + for my $foo ( grep !exists $symbols{$_} , keys %main:: ) { print $foo,"\n"; }

    /J\

Re: Imported symbol names
by dragonchild (Archbishop) on Jul 08, 2004 at 17:21 UTC
    There's a few ways, depending on how much syntactic sugar you want to have.
    1. If you have CGI::MyChild and you can have your users actually do
      use CGI::MyChild qw(:form);
      then you can write your own import() function that will see what is actually being imported. (Look at the source for Exporter to get a feel of what to do.) You can then intercept the importation and have the link to your function be there instead.
    2. If you want to be really slick, you can allow your users to do
      use CGI qw( :form ); use CGI::MessWithForms;
      And, in your import() function, you can see what functions are in %::main and mess with them. Alternately, you could overload the functions in the CGI namespace, but you need to take care with that.

    Personally, I'd recommend subclassing CGI and require that everyone create an instance of your class. *shrugs* But, that's just me.

    ------
    We are the carpenters and bricklayers of the Information Age.

    Then there are Damian modules.... *sigh* ... that's not about being less-lazy -- that's about being on some really good drugs -- you know, there is no spoon. - flyingmoose

    I shouldn't have to say this, but any code, unless otherwise stated, is untested

      Any possibility that i could do:
      package CGI::MyChild; use base qw(CGI); use CGI qw(:form);
      and import directly, so the programs using it dont have to add the qw(:form)

      I am a bit over my head on this, havent played symbols games like this very much :)
        You're confusing yourself. How are you going to allow your users to use this? Will they use the OO interface, the procedural interface, or will you allow them to use both? The easiest thing on you is to allow one or the other. The OO interface is easiest and the procedural isn't too difficult, once you see it done once. Doing them both is going to be more trouble than it's worth, IMHO.

        ------
        We are the carpenters and bricklayers of the Information Age.

        Then there are Damian modules.... *sigh* ... that's not about being less-lazy -- that's about being on some really good drugs -- you know, there is no spoon. - flyingmoose

        I shouldn't have to say this, but any code, unless otherwise stated, is untested

Re: Imported symbol names
by shemp (Deacon) on Jul 08, 2004 at 18:16 UTC
    Ok so i found a way to do it, but it doesnt seem very clean - i really need to get a better handle on Exporter, etc.

    So here it is:
    my @functions = @{ $CGI::EXPORT_TAGS{':form'} };
    Update:
    Here is the final code that does what i want. Still testing, but i feel good about this working!
    BEGIN { no strict 'refs'; foreach my $function_name ( @{ $CGI::EXPORT_TAGS{':form'}} ) { *{$function_name} = sub { my $self = shift @_; my %args = @_; if ( exists($args{-page}) && exists($args{-param}) ) { $args{-name} = $self->CreateRawFieldName( -page => $args{-page}, -param => $args{-param} ); delete $args{-page}; delete $args{-param}; } my $parent_call = 'SUPER::' . $function_name; return $self->$parent_call(%args); } } use strict; }