Domanda più interessante. Il problema, penso, sta nel fatto che Exporter.pm non ha abilitato gli avvertimenti. Ecco un semplice insieme di file che illustra il comportamento che hai descritto:
Foo.pm:
package Foo;
use base 'Exporter';
our @EXPORT = qw(Baz);
sub Baz {
print "Hello from Foo::Baz\n";
}
Bar.pm:
package Bar;
use base 'Exporter';
our @EXPORT = qw(Baz);
sub Baz {
print "Hi from Bar::Baz\n";
}
import-redefine.pl:
use strict;
use warnings;
use Foo;
use Bar;
Baz();
esempio:
C:\Users\Lona\Desktop\pm>perl import-redefine.pl
Hi from Bar::Baz
invertire la use
dichiarazioni, come segue:
use strict;
use warnings;
use Bar;
use Foo;
Baz();
ed eseguire di nuovo:
C:\Users\Lona\Desktop\pm>perl import-redefine.pl
Hello from Foo::Baz
mi è venuta in mente la seguente soluzione, che ridefinisce il metodo di default import
di Exporter.pm:
BEGIN {
require Exporter; # We'll need Exporter.pm loaded.
my $old_import = \&Exporter::import; # Save copy of original Exporter::import.
no strict 'refs'; # We'll be using some hacks that will
no warnings 'redefine'; # raise errors and warnings. Suppress those.
*Exporter::import = sub { # Our enhancement of Exporter::import.
use Carp;
my $pkg = shift;
my $callpkg = caller($Exporter::ExportLevel + 1);
my @exports = @_ > 0 # Which subs to export?
? @_ # Those provided as 'use MODULE' arguments...
: @{"$pkg\::EXPORT"} # Or thosedefined in the module's @EXPORT?
;
foreach my $sub (@exports) { # For each of the exportees...
if (exists ${"$callpkg\::"}{$sub}) { # ... check if it exists...
carp "Subroutine $callpkg\::$sub redefined by import"; # and throw a warning if needed.
}
$old_import->($pkg, @_); # Call the original Exporter::import.
}
}
}
Per utilizzare questo, ma da qualche parte nel file di script principale, sopra il use MODULE
dichiarazioni:
use strict;
use warnings;
BEGIN {
require Exporter; # We'll need Exporter.pm loaded.
my $old_import = \&Exporter::import; # Save copy of original Exporter::import.
no strict 'refs'; # We'll be using some hacks that will
no warnings 'redefine'; # raise errors and warnings. Suppress those.
*Exporter::import = sub { # Our enhancement of Exporter::import.
use Carp;
my $pkg = shift;
my $callpkg = caller($Exporter::ExportLevel + 1);
my @exports = @_ > 0 # Which subs to export?
? @_ # Those provided as 'use MODULE' arguments...
: @{"$pkg\::EXPORT"} # Or thosedefined in the module's @EXPORT?
;
foreach my $sub (@exports) { # For each of the exportees...
if (exists ${"$callpkg\::"}{$sub}) { # ... check if it exists...
carp "Subroutine $callpkg\::$sub redefined by import"; # and throw a warning if needed.
}
$old_import->($pkg, @_); # Call the original Exporter::import.
}
}
}
use Foo;
use Bar;
Baz();
ed eseguirlo:
C: \ Users \ Lona \ Desktop \ pm> perl import-redefine.pl
Subroutine main::Baz redefined by import at import-redefine.pl line 21.
main::__ANON__("Bar") called at import-redefine.pl line 30
main::BEGIN() called at import-redefine.pl line 30
eval {...} called at import-redefine.pl line 30
Hi from Bar::Baz
Wow - grande e dettagliata risposta. Onestamente, speravo in qualcosa di più semplice, ad esempio "usa warnins" exported_functions "o soo, ma sembra che non sia una cosa facile. Grazie. – kobame