Perl:使用子类中的常量实例化复杂数据结构
我有一个基类,它是用一个复杂的数据结构实例化的,有三位数的条目,所有条目都是常量。其中一些常量是特定于类的,应该用不同的常量实例化。我很难做到这一点。归结起来就是: tstbase.pm:Perl:使用子类中的常量实例化复杂数据结构,perl,constants,subclass,instantiation,Perl,Constants,Subclass,Instantiation,我有一个基类,它是用一个复杂的数据结构实例化的,有三位数的条目,所有条目都是常量。其中一些常量是特定于类的,应该用不同的常量实例化。我很难做到这一点。归结起来就是: tstbase.pm: package tstbase; my $THISCLASSCONSTANT = "baseconstant.2"; my %complexdatastructure = ( "attribute.1" => "baseconstant.1", "attribute.2" =>
package tstbase;
my $THISCLASSCONSTANT = "baseconstant.2";
my %complexdatastructure = (
"attribute.1" => "baseconstant.1",
"attribute.2" => $THISCLASSCONSTANT,
);
sub new {
my $class = shift;
my $self = { };
bless ($self, $class);
$self->_init( $THISCLASSCONSTANT );
return $self;
};
sub _init {
my $self = shift;
$THISCLASSCONSTANT = shift;
foreach (keys %complexdatastructure) {
$self->{$_} = $complexdatastructure{$_};
};
};
tstsubclass.pm:
package tstsubclass;
use parent "tstbase";
my $THISCLASSCONSTANT = "subclassconstant.2";
sub _init {
my $self = shift;
$self->SUPER::_init( $THISCLASSCONSTANT );
};
tst.pl:
#!/usr/bin/perl
use tstbase;
use tstsubclass;
my $baseobj = tstbase->new;
print "Testbase ".$baseobj->{"attribute.1"}." ".$baseobj->{"attribute.2"}."\n";
my $subobj = tstsubclass->new;
print "Testsubclass ".$subobj->{"attribute.1"}." ".$subobj->{"attribute.2"}."\n";
现在输出是
Testbase baseconstant.1 baseconstant.2
Testsubclass baseconstant.1 baseconstant.2
而我希望它是
Testbase baseconstant.1 baseconstant.2
Testsubclass baseconstant.1 subclassconstant.2
可能吗?我很乐意使用
sub THISCLASSCONSTANT = { "subclassconstant.2" }
如果有帮助的话。tstsubclass不应具有任何基本常量值。
现在,我用魔术字符串实例化这个类,并进行搜索和替换。它可以工作,但似乎不那么优雅和性能
非常感谢您的帮助。我以前问过这个问题(),但过度简化了示例,因此回答只能暗示可能的解决方案
谢谢,
Marcus最简单的方法是使用
%complexdatastructure
中的引用。
但请注意,执行此操作时,$thisclassconts
将在第一次调用tstsubclass->new
后更改
package tstbase;
my $THISCLASSCONSTANT = "baseconstant.2";
my %complexdatastructure = (
"attribute.1" => \ "baseconstant.1",
"attribute.2" => \ $THISCLASSCONSTANT,
);
sub new {
my $class = shift;
my $self = { };
bless ($self, $class);
$self->_init( $THISCLASSCONSTANT );
return $self;
};
sub _init {
my $self = shift;
$THISCLASSCONSTANT = shift;
foreach (keys %complexdatastructure) {
$self->{$_} = ${$complexdatastructure{$_}};
};
};
现在您的输出是所需的,但是如果您像这样更改新调用的顺序:
my $subobj = tstsubclass->new;
print "Testsubclass ".$subobj->{"attribute.1"}." ".$subobj->{"attribute.2"}."\n";
my $baseobj = tstbase->new;
print "Testbase ".$baseobj->{"attribute.1"}." ".$baseobj->{"attribute.2"}."\n";
您将获得:
Testsubclass baseconstant.1 subclassconstant.2
Testbase baseconstant.1 subclassconstant.2
您现在可以做的是编写“自己的”小local
(我不知道为什么正常的local
即使将$THISCLASSCONSTANT
的声明更改为我们的
,也不起作用)
将tstbase::_init
更改为:
sub _init {
my $self = shift;
my $oldconstant = $THISCLASSCONSTANT;
$THISCLASSCONSTANT = shift;
foreach (keys %complexdatastructure) {
$self->{$_} = ${$complexdatastructure{$_}};
};
$THISCLASSCONSTANT = $oldconstant;
};
现在我想你得到了你想要的。你从来没有使用过
$THISCLASSCONSTANT
!(您缺少了我的my
,因此您不小心用该名称重击了现有的var,而不是创建了一个新的var。)我们的目标是使用不带参数的“new”,并让类仅根据自身进行实例化。也许我不清楚您是否从未使用传递给\u init
的$thisclassconts
。这与new
无关。我想这是我的问题-我应该在哪里传递什么以实现所需的输出,同时避免更改tst.pl并避免将%complexDataStratstructure复制到tststsubClassThank,这显然是个难题。我在foreach循环中添加了一点代码,这样它既可以处理引用也可以处理非引用,这样我就不必更改模块中的所有%complexdatastructure-s:if(ref($complexdatastructure{$})){
$self->{$}=${$complexdatastructure{$};}else{$self->{${}=$complexdatastructure{$};};`如果你喜欢brefity,你也可以在循环中执行$self->{$}=ref${$}$}${$complexdatastructure{$}:$complexdatastructure{$};
(对不起,如果错了,在我的手机上).实际上我已经这么做了-在使用if then else多年后,我给了三元运算符另一个机会,这是我更改的代码之一。我还不确定它是否更易于阅读,但它确实更易于键入(尤其是在手机上^^)