Perl:使用子类中的常量实例化复杂数据结构

时间:2013-10-12 08:20:58

标签: perl constants subclass instantiation

我有一个基类,它使用复杂的数据结构进行实例化,其中包含三位数的条目,所有这些都是常量。其中一些常量是特定于类的,应该使用不同的常量进行实例化。我无法实现这一目标。归结为:

tstbase.pm:

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不应具有任何baseconstant值。 现在我用魔术字符串实例化该类并进行搜索&更换。它有效,但看起来不那么优雅和高效。

非常感谢任何帮助。我之前已经问过这个问题(Perl: Using common constructor for base and subclass),但过度简化了这个例子,因此响应只能暗示可能的解决方案。

谢谢, 马库斯

1 个答案:

答案 0 :(得分:0)

最简单的方法是使用%complexdatastructure中的引用。 但请注意,执行此操作后,$THISCLASSCONSTANT将在第一次调用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的声明也不起作用到our

将您的tstbase::_init更改为:

sub _init {
    my $self = shift;
    my $oldconstant = $THISCLASSCONSTANT;
    $THISCLASSCONSTANT = shift;
    foreach (keys %complexdatastructure) {
        $self->{$_} = ${$complexdatastructure{$_}};
    };
    $THISCLASSCONSTANT = $oldconstant;
};

现在我觉得你有你想要的东西。