views:

284

answers:

2

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?

+12  A: 

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.

moritz
+11  A: 

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.

Axeman
Well really you did the same thing is moritz except specified the if statement, right? I mean, if I put if (@_ ~~ ':oldmode') {carp 'blah';} in his it would be the same right?
Frew

related questions