Perl 如何从基本模块导入全局变量?
我创建了一个带有全局变量$a和$B的模块Foo::Prototype。我想要一个包Foo::Bar,它使用Foo::Prototype作为基础来导入全局变量$a和$B。我想不出怎么做 我知道使用全局变量通常不是一个好的实践,但在这种情况下,我想使用它们 代码如下所示:Perl 如何从基本模块导入全局变量?,perl,inheritance,export,Perl,Inheritance,Export,我创建了一个带有全局变量$a和$B的模块Foo::Prototype。我想要一个包Foo::Bar,它使用Foo::Prototype作为基础来导入全局变量$a和$B。我想不出怎么做 我知道使用全局变量通常不是一个好的实践,但在这种情况下,我想使用它们 代码如下所示: package Foo:Prototype; my ($A, $B); our @EXPORT = qw($A $B); sub new { [...] $A = 1; $B = 2; } 1; pa
package Foo:Prototype;
my ($A, $B);
our @EXPORT = qw($A $B);
sub new {
[...]
$A = 1;
$B = 2;
}
1;
package Foo:Bar;
use base Foo:Prototype qw($A $B);
sub test {
print $A, "\n";
print $B, "\n";
}
1;
# test.pl
Foo:Bar->new();
Foo:Bar->test();
编辑:
package T;
use strict;
use warnings;
use base 'Exporter';
our ($A, $B);
our @EXPORT = qw($A $B);
sub new {
$A = 1;
$B = 2;
}
"EOF T.pm"
package U;
use strict;
use warnings;
use base 'T';
use T;
sub test {
my $self = shift;
print "$_\n" for $A, $B;
}
"EOF U.pm"
#!/usr/perl/bin
use strict;
use warnings;
use U;
U->new;
U->test;
C:\Temp> t.pl
1
2
我想让编写Foo::Prototype的子类对其他人来说尽可能紧凑。与其写$self->{A}->foo(),我宁愿让人们写$A->foo()
new
my
声明的变量无法导出。因此,我使用our
声明了$A
和$B
package T;
use strict;
use warnings;
use base 'Exporter';
our ($A, $B);
our @EXPORT = qw($A $B);
sub new {
$A = 1;
$B = 2;
}
"EOF T.pm"
package U;
use strict;
use warnings;
use base 'T';
use T;
sub test {
my $self = shift;
print "$_\n" for $A, $B;
}
"EOF U.pm"
#!/usr/perl/bin
use strict;
use warnings;
use U;
U->new;
U->test;
C:\Temp> t.pl
1
2
U.pm:
package T;
use strict;
use warnings;
use base 'Exporter';
our ($A, $B);
our @EXPORT = qw($A $B);
sub new {
$A = 1;
$B = 2;
}
"EOF T.pm"
package U;
use strict;
use warnings;
use base 'T';
use T;
sub test {
my $self = shift;
print "$_\n" for $A, $B;
}
"EOF U.pm"
#!/usr/perl/bin
use strict;
use warnings;
use U;
U->new;
U->test;
C:\Temp> t.pl
1
2
t.pl:
package T;
use strict;
use warnings;
use base 'Exporter';
our ($A, $B);
our @EXPORT = qw($A $B);
sub new {
$A = 1;
$B = 2;
}
"EOF T.pm"
package U;
use strict;
use warnings;
use base 'T';
use T;
sub test {
my $self = shift;
print "$_\n" for $A, $B;
}
"EOF U.pm"
#!/usr/perl/bin
use strict;
use warnings;
use U;
U->new;
U->test;
C:\Temp> t.pl
1
2
诀窍是不必导出变量。这是一种非常糟糕的编程方式
也许有更好的方法来完成你想做的事情。您只需告诉我们您为什么要这样做。根据您的编辑,
$A
和$B
将用于调用上的方法
因此,我假设它们是作为基类的类数据存储的单例对象
如果将它们作为变量公开,它们很容易被更改,并且可能会出现各种问题
为什么不使用访问器呢
package Foo::Proto;
my $A;
my $B;
sub A {
return $A;
}
sub B {
return $B;
}
package Foo::Child;
our @ISA= qw(Foo::Prototype);
sub test {
my $self = shift;
$self->A->blah();
# Or if I am doing many things with A, and want to type less:
my $A = $self->A;
$A->blah();
}
package Foo::Kid;
our @ISA= qw(Foo::Prototype);
# If you will never change $A in the prototype, you could do this:
my $A = __PACKAGE__->A;
sub test {
$A->blah();
}
但这一切似乎都是胡闹
为了在我的代码中解决这个问题,我将使用Moose,然后创建一个角色来引入与a和B相关的方法
my $m = Foo::Mooseling->new();
$m->test_A();
$m->test_B();
BEGIN { # This is going to be $A, I needed something to call $A->foo on.
package Thing1;
sub new { bless {}, __PACKAGE__; }
sub foo { print __PACKAGE__."::foo()\n"; }
sub blah { print __PACKAGE__."::blah()\n"; }
}
BEGIN { # This is going to be B. It is not interesting either.
package Thing2;
sub new { bless {}, __PACKAGE__; }
sub bar { print __PACKAGE__."::bar()\n"; }
sub bluh { print __PACKAGE__."::bluh()\n"; }
}
# This is the interesting part:
BEGIN { # This ROLE will provide A and B methods to any objects that include it.
package Foo::ProtoMoose;
use Moose::Role;
has 'A' => (
is => 'ro',
isa => 'Thing1',
handles => [qw( foo blah )], # Delegate calls to foo and blah for consuming object to this A.
default => sub { Thing1->new(); }, # Create a Thing1 to be A.
);
has 'B' => (
is => 'ro',
isa => 'Thing2',
handles => [qw( bar bluh )],
default => sub { Thing2->new(); },
);
}
BEGIN { # This method consumes the ProtoMoose Role.
package Foo::Mooseling;
use Moose;
with 'Foo::ProtoMoose';
sub test_A {
my $class = shift;
$class->foo;
$class->blah;
}
sub test_B {
my $class = shift;
$class->bar;
$class->bluh;
}
}
如果你想让Thing1和Thing2成为单例,那么就使用。好答案。你含蓄地报道了它,但我要强调的是,Exporter不会导出词汇。@SinanÜnür:这是一篇老文章,我已经有一段时间没有讨论过导出了。你能解释一下为什么
使用T
在U.pm中将其用作基础后是必需的?@vol7ron Correction:For$a
和$B
要导出到包U
。我不打算使用它,但我很感兴趣,希望base
默认情况下能够处理导入。有趣。@vol7ron base:在编译时与基类建立ISA关系。