为什么我的包没有在`@EXPORT`中导出名称?

问题描述 投票:0回答:1

我想通过自动加载函数提供一些特殊常量。 基本上创建函数工作正常,但代码将允许为常量创建any名称,而不是特定的允许集合。

所以我尝试通过从生成包中导出名称来限制名称。

不幸的是,包导出时根本没有注意到,我没有看到错误。

演示代码是这样的:

#!/usr/bin/perl
use warnings;
use strict;

# Tell Perl module is loaded already (fake)
sub UNIVERSAL::_fake_load($)
{
    my $pkg = $_[0];

    # Tell Perl module is loaded already
    $INC{join('/', split(/::/, $pkg)) . '.pm'} = 1;
}

package MAGIC_STUFF;

our (@EXPORT, @ISA, $VERSION);

BEGIN {
    use Exporter;
    $Exporter::Verbose = 1;
    $VERSION = 'v0.0.0';                # for version checking
    @ISA = qw(Exporter);
    @EXPORT = qw(abra ka dabra);        # exported by default
}

use AutoLoader;

sub AUTOLOAD {
    use vars qw($AUTOLOAD);
    my ($sub_name, @args) = ($AUTOLOAD, @_);
    no strict 'refs';

    *$sub_name = sub { "$sub_name defined for (" . join(',', @args). ")" };
    goto &$sub_name;                    # return from AUTOLOAD
}

sub import
{
    print "import: ", join(' ', @_), "\n";
    Exporter::import(@_);
}

BEGIN {
    $DB::single = 1;
    foreach (@EXPORT) {
        eval "sub $_;";
    }
    __PACKAGE__->_fake_load();
}

1;

package main;


use MAGIC_STUFF;
#MAGIC_STUFF->import(1,2,3);

print MAGIC_STUFF::joe(7), "\n";
print ka(3), "\n";

在调试它时,我基本上看到了这一点:

> perl -d test.pl

Loading DB routines from perl5db.pl version 1.39_10
Editor support available.

Enter h or 'h h' for help, or 'man perldebug' for more help.

MAGIC_STUFF::CODE(0x16d17b0)(test.pl:45):
45:         foreach (@EXPORT) {
#...
  DB<1> n
MAGIC_STUFF::CODE(0x16d17b0)(test.pl:46):
46:             eval "sub $_;";
  DB<1> n
MAGIC_STUFF::CODE(0x16d17b0)(test.pl:46):
46:             eval "sub $_;";
  DB<1> n
MAGIC_STUFF::CODE(0x16d17b0)(test.pl:46):
46:             eval "sub $_;";
  DB<1> n
MAGIC_STUFF::CODE(0x16d17b0)(test.pl:48):
48:         __PACKAGE__->_fake_load();
  DB<1> n
import: MAGIC_STUFF
Importing into MAGIC_STUFF from MAGIC_STUFF: abra, dabra, ka at test.pl line 40.
        MAGIC_STUFF::import('MAGIC_STUFF') called at test.pl line 56
        main::BEGIN() called at test.pl line 56
        eval {...} called at test.pl line 56
MAGIC_STUFF::(test.pl:16):      our (@EXPORT, @ISA, $VERSION);
  DB<1> n
MAGIC_STUFF::(test.pl:51):      1;
  DB<1> n
main::(test.pl:59):     print MAGIC_STUFF::joe(7), "\n";
  DB<1> n
MAGIC_STUFF::joe defined for (7)
main::(test.pl:60):     print ka(3), "\n";
  DB<1>
Undefined subroutine &main::ka called at test.pl line 60.
 at test.pl line 60.
Debugged program terminated.  Use q to quit or R to restart,

foreach
循环试图解决问题,但没有帮助。

最令我困惑的是

从 MAGIC_STUFF 导入 MAGIC_STUFF

不应该导入到

main
吗?

perl autoload
1个回答
1
投票

Exporter::import
导出到其调用者(您的
MAGIC_STUFF::import
),因此您要导出到
MAGIC_STUFF
命名空间。

一个简单的修复方法是使用

goto
MAGIC_STUFF::import
的原始调用者传递给
Exporter::import

sub import
{
    print "import: ", join(' ', @_), "\n";
    goto &Exporter::import;
}
© www.soinside.com 2019 - 2024. All rights reserved.