所以我正在谈论我的Moosey业务,我认为在我使用数字的地方使用常数可能会很好,以明确这些数字的含义或以后更改
所以在父类中我添加了标准的'use constant'
package Parent;
use constant {
NO_LEVEL => 0,
MY_LEVEL => 1,
YOUR_LEVEL => 2,
};
package Child;
extends 'Parent';
#just to demonstrate that child can or cannot access the constant
sub printMyLevel{
print MY_LEVEL;
}
但是子类不知道父级中设置的常量!卫生署!
我猜我必须做一些Moose魔法才能让它正常工作,或完全不同。我在这个问题上的搜索没有得出任何结果= /
答案 0 :(得分:11)
常量是子程序。
{
package Parent;
use Moose;
use namespace::autoclean;
use constant {
NO_LEVEL => 0,
MY_LEVEL => 1,
YOUR_LEVEL => 2,
};
__PACKAGE__->meta->make_immutable;
};
{
package Child;
use Moose;
use namespace::autoclean;
extends 'Parent';
sub printMyLevel {
my $self = shift;
my $class = ref $self;
print $class->MY_LEVEL;
}
__PACKAGE__->meta->make_immutable;
}
package main;
my $child = Child->new;
$child->printMyLevel;
请记住,常量是具有空原型的子程序。 perl
利用此功能在编译期间内联它们。但是,方法调用忽略了原型,因此不会内联以这种方式访问的可继承常量。
答案 1 :(得分:6)
这实际上是在documentation中提到的,如果只是传递:
“常量属于它们所定义的包。要引用另一个包中定义的常量,请指定完整的包名称,如
Some::Package::CONSTANT
中所示。常量可以由模块导出,也可以调用作为类或实例方法,即Some::Package->CONSTANT
或$obj->CONSTANT
,其中$obj
是Some::Package
的实例。子类可以定义自己的常量来覆盖它们中的那些基类。“
答案 2 :(得分:4)
将它们称为方法。
sub printMyLevel{
my ( $self, ) = $_;
print $self->MY_LEVEL;
}
答案 3 :(得分:4)
由于常量是子例程,并且你可以通过调用它们来获得继承,因为 bit已经被覆盖到了死亡,这里有一些不同的东西。
如果您知道自己只使用单个文件,则可以使用词法常量来桥接包:
package Parent;
our ($NO_LEVEL, $MY_LEVEL, $YOUR_LEVEL);
*NO_LEVEL = \0; # this split declaration installs aliases to numbers
*MY_LEVEL = \1; # into the lexicals. since numbers are constants
*YOUR_LEVEL = \2; # to perl, the aliased names are also constants
package Child;
# just to demonstrate that anything below can access the constants
sub printAll {
print "$NO_LEVEL $MY_LEVEL $YOUR_LEVEL\n";
}
Child->printAll; # 0 1 2
eval {$NO_LEVEL = 3} or print "error: $@\n";
# error: Modification of a read-only value attempted at ...
如果在分配常量时不需要perl死掉,our
声明会变得更简单(可能是my
):
our ($NO_LEVEL, $MY_LEVEL, $YOUR_LEVEL) = (0, 1, 2);
你可以恢复恒定的性质,同时仍然使用简洁的语法,但有一点魔力:
my $constant = sub {Internals::SvREADONLY($_[$_], 1) for 0 .. $#_};
package Parent;
$constant->(our ($NO_LEVEL, $MY_LEVEL, $YOUR_LEVEL) = (0, 1, 2));
package Child;
# just to demonstrate that anything below can access the constants
sub printAll {
print "$NO_LEVEL $MY_LEVEL $YOUR_LEVEL\n"; # interpolates :)
}
Child->printAll; # 0 1 2
eval {$NO_LEVEL = 3} or print "error: $@\n";
# error: Modification of a read-only value attempted at ...
您当然可以省略$constant
coderef并内联魔术:
package Parent;
Internals::SvREADONLY($_, 1)
for our ($NO_LEVEL, $MY_LEVEL, $YOUR_LEVEL) = (0, 1, 2);
答案 4 :(得分:2)
继承会影响方法调用($x->m
),句点。