perl - 导出后变量仍然不可见

标签 perl scope package exporter

我正在开发一个简单的 Perl 模块来创建和验证音符并查找等价音符。我在模块中存储包含所有有效注释的数组引用,然后将其导出,以便 Note.pm 模块可以查看哪些注释有效,并在创建 时对照列表进行检查注意对象。

问题是,无论我如何尝试,导出的 $VALID_NOTES 数组引用在 Note.pm 中都不可见!我已阅读 Exporter 上的文档大约一千次,回顾了我的大量使用 Exporter 的旧 Perl 模块,我只是无法弄清楚这里出了什么问题......

这是代码:

test.pl

use strict;
use warnings;
use Music;

my $m = Music->new();

my $note = $m->note('C');

print $note;

音乐.pm

package Music;

use Moose;
use Note;

use Exporter qw(import);
our @EXPORT_OK = qw($VALID_NOTES);

no warnings 'qw';

# Valid notes
# Enharmonic notes are in preferred (most common) order:
#     Natural -> Sharp -> Flat -> Double Sharp -> Double Flat
our $VALID_NOTES = [
    [ qw(C B#        Dbb) ],
    [ qw(  C# Db B##    ) ],
    [ qw(D       C## Ebb) ],
    [ qw(  D# Eb     Fbb) ],
    [ qw(E    Fb D##    ) ],
    [ qw(F E#        Gbb) ],
    [ qw(  F# Gb E##    ) ],
    [ qw(G       F## Abb) ],
    [ qw(  G# Ab        ) ],
    [ qw(A       G## Bbb) ],
    [ qw(  A# Bb     Cbb) ],
    [ qw(B    Cb A##    ) ],
];

sub note {
    my $self = shift;
    my $name = shift;
    return Note->new(name => $name);
}

__PACKAGE__->meta->make_immutable;

Note.pm

package Note;

use Moose;
use Music qw($VALID_NOTES);
use experimental 'smartmatch';

has 'name'  => (is => 'ro', isa => 'Str', required => 1);
has 'index' => (is => 'ro', isa => 'Int', lazy => 1, builder => '_get_index');

# Overload stringification
use overload fallback => 1, '""' => sub { shift->name() };

sub BUILD {
    my $self = shift;
    if (!grep { $self ~~ @{$VALID_NOTES->[$_]} } 0..$#{$VALID_NOTES}) {
        die "Invalid note: '$self'\n";
    }
}

sub _get_index {
    my $self = shift;
    my ($index) = grep { $self ~~ @{$VALID_NOTES->[$_]} } 0..$#{$VALID_NOTES};
    return $index;
}

sub enharmonic_notes {
    my $self = shift;
    my $index = $self->index();
    return map { Note->new($_) } @{$VALID_NOTES->[$index]};
}

__PACKAGE__->meta->make_immutable;

当我运行代码时,我得到以下输出:

Global symbol "$VALID_NOTES" requires explicit package name at Note.pm line 15.
Global symbol "$VALID_NOTES" requires explicit package name at Note.pm line 15.
Global symbol "$VALID_NOTES" requires explicit package name at Note.pm line 22.
Global symbol "$VALID_NOTES" requires explicit package name at Note.pm line 22.
Global symbol "$VALID_NOTES" requires explicit package name at Note.pm line 29.

最佳答案

Music.pm中,在加载注意之前在BEGIN block 中填充@EXPORT_OK:

package Music;
use Moose;
our @EXPORT_OK;
BEGIN { @EXPORT_OK = qw($VALID_NOTES) }
use Exporter qw(import);
use Note;

关于perl - 导出后变量仍然不可见,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46732743/

相关文章:

javascript - 为什么我的表单发布函数会打开我的 .pl 文件而不是执行它?

mysql - 兼容 mysql 插入的 Perl 格式数组元素

php - 可变变量的意外行为

c++ - C 使用文件中定义的变量

R: 安装包时 unloadNamespace(package) 的问题

java - 如何告诉 Maven 构建一个可执行的 jar

linux - 使用 Perl 的多个 Oracle 版本

perl - 如何在 Perl 中将文件句柄指向 STDOUT(或另一个文件句柄)?

java - 访问函数内部的变量

r - 从 Github 安装的软件包是否需要 Rtools?