好.我在尝试继承任何子类的父类中设置的常量时遇到问题.
#!/usr/bin/perl
use strict;
use warnings;
package Car;
use Exporter qw( import );
our @EXPORT_OK = ( 'WHEELS', 'WINGS' );
use constant WHEELS => 4;
use constant WINGS => 0;
sub new {
my ( $class, %args ) = @_;
my $self = {
doors => $args{doors},
colour => $args{colour},
wheels => WHEELS,
wings => WINGS,
};
bless $self, $class;
return $self;
}
package Car::Sports;
use base qw( Car );
sub new {
my ( $class, %args ) = @_;
my $self = {
doors => $args{doors},
engine => $args{engine},
wheels => WHEELS,
wings => WINGS,
};
bless $self, $class;
return $self;
}
package main;
my $obj = Car->new( doors => 4, colour => "red" );
print Dumper $obj;
my $obj2 = Car::Sports->new( doors => 5, engine => "V8" );
print Dumper $obj2;
__END__
Run Code Online (Sandbox Code Playgroud)
错误是:
Bareword "WHEELS" not allowed while "strict subs" in use at ./t.pl line 30.
Bareword "WINGS" not allowed while "strict subs" in use at ./t.pl line 30.
Execution of ./t.pl aborted due to compilation errors.
Run Code Online (Sandbox Code Playgroud)
现在,我没有做过一些研究而没有来这里发帖.我明白一个选择就是use Car qw( WHEELS WINGS)进入Car::Sports.但是,如果我这样做,我会收到以下错误,因为这些类都在同一个文件中内联:
Can't locate Car.pm in @INC
Run Code Online (Sandbox Code Playgroud)
出于各种原因,我需要将我的包保存在一个文件中.有没有解决的办法?由于常量基本上只是subs,为什么我必须导入它们,而对于普通方法则不一样?
最后,我也知道我可以这样做:
package Car::Sports;
use base qw( Car );
sub new {
my ( $class, %args ) = @_;
my $self = {
doors => $args{doors},
engine => $args{engine},
wheels => Car::WHEELS,
wings => Car::WINGS,
};
bless $self, $class;
return $self;
}
Run Code Online (Sandbox Code Playgroud)
它很好......但我有许多类,并希望使常量的继承更通用,必须明确地命名父类(有时它不仅仅是父类,而是祖父母).
非常感谢任何指针!
干杯
一种解决方法是包括该行
package Car::Sports; use base qw( Car ); Car->import(qw(WHEELS WINGS));
与使用在该印记Car::Sports的构造函数:
...
wheels => &WHEELS,
wings => &WINGS,
...
Run Code Online (Sandbox Code Playgroud)
您的Car类@EXPORTS_OK直到运行时才定义其列表.这些符号是必需的,因为Car::Sports构造函数在编译时被解析,并且编译器不知道命名空间中应该有符号WHEELS和WINGS符号Car::Sports.
避免这些印记的唯一方法是Car在编译时定义导出:
package Car;
our @EXPORT_OK;
BEGIN {@EXPORT_OK = qw(WHEELS WINGS)} # set at compile not run time
...
package Car::Sports;
use base qw(Car);
BEGIN {Car->import('WHEELS','WINGS')} # import before c'tor is parsed
Run Code Online (Sandbox Code Playgroud)
您还可以通过Car在自己的Car.pm文件中定义类来避免这些阴谋.然后你会说
use Car qw(WHEELS WINGS);
Run Code Online (Sandbox Code Playgroud)
并且Car.pm文件中的所有内容都将在编译时解析,并且该Exporter::import方法(由调用触发Car::import)将自动运行并将所需的符号导入当前的命名空间.