How can I get Perl to give a warning message when a certain package/tag is imported?
Question
I have a package that I just made and I have an "old-mode" that basically makes it work like it worked before: importing everything into the current namespace. One of the nice things about having this as a package is that we no longer have to do that. Anyway, what I would like to do is have it so that whenever anyone does:
use Foo qw(:oldmode);
I throw a warning that this is deprecated and that they should either import only what they need or just access functions with Foo->fun();
Any ideas on how to do this?
Solution
Well, as you specifically state that you want to alarm in the cases of use Mod qw<:oldmode>;
This works better:
package Foo;
use base qw<Exporter>;
use Carp qw<carp>;
...
sub import {
#if ( grep { $_ eq ':oldmode' } @_ ) { # Perl 5.8
if ( @_ ~~ ':oldmode' ) { # Perl 5.10
carp( 'import called with :oldmode!' );
}
goto &{Exporter->can( 'import' )};
}
Thanks to Frew, for mentioning the Perl 5.10 smart match syntax. I'm learning all the ways to work Perl 5.10 into my code.
Note: the standard way to use exporter in an import sub is to either manipulate $Exporter::ExportLevel
or to call Foo->export_to_level( 1, @_ );
But I like the way above. It's quicker and, I think, simpler.
OTHER TIPS
You write your own sub import
in package Foo
that will get called with the parameter list from use Foo
.
An example:
package Foo;
use Exporter;
sub import {
warn "called with paramters '@_'";
# do the real import work
goto &{Exporter->can('import')};
}
So in sub import
you can search the argument list for the deprecated tag, and then throw a warning.
Update: As Axeman points out, you should call goto &{Exporter->can('import')}
. This form of goto replaces the current subroutine call on the stack, preserving the current arguments (if any). That's needed because Exporter's import() method will export to its caller's namespace.