Perl:对基类和子类使用公共构造函数

Perl:对基类和子类使用公共构造函数,perl,class,constructor,shared,Perl,Class,Constructor,Shared,我试图初始化基类和子类,而不必复制构造函数。这就是我得到的: tstbase.pm: package tstbase; use Exporter qw(import); our @EXPORT = qw(&new); my %config = ( "class" => "tstbase", ); sub new { my $class = shift; my $self; $self->{"name"} = $config{"class"};

我试图初始化基类和子类,而不必复制构造函数。这就是我得到的:

tstbase.pm:

package tstbase;
use Exporter qw(import);
our @EXPORT = qw(&new);
my %config = (
    "class" => "tstbase",
);

sub new {
    my $class = shift;
    my $self;
    $self->{"name"} = $config{"class"};
    bless ($self, $class);
    return $self;
};
1;
tstsubclass.pm:

package tstsubclass;
use tstbase;
my %config = (
  "class" => "tstsubclass",
);
1;
tst.pl:

#!/usr/bin/perl
use tstsubclass;

my $baseobj = tstbase->new;
print "Testbase ".$baseobj->{"name"}."\n";
my $subobj = tstsubclass->new;
print "Testsubclass ".$subobj->{"name"}."\n";
tst.pl的输出是

Testbase tstbase
Testsubclass tstbase
但是我在找

Testbase tstbase
Testsubclass tstsubclass
当我将“sub-new{..}”例程复制到tstsubclass.pm时,我会得到它。有没有办法避免这种开销?我尝试了我的%config/我们的%config和导出%config的所有组合,但没有成功

非常感谢您的帮助

最好的,
Marcus

您的构造函数是继承的,因此工作正常。不起作用的是使用了
%config
,它分别存在于每个包中。因为您正在调用基类中定义的构造函数,所以使用了该版本的
%config
。在您的特定情况下,配置散列是不必要的,因为您可以使用传递给构造函数的
$class
变量初始化
name
成员:

sub new {
    my $class = shift;
    my $self = { };     # initialize the object as a reference to an empty hash
    $self->{"name"} = $class;
    bless ($self, $class);
    return $self;
};
这将起作用(尽管这是不必要的;您始终可以使用
Scalar::Util::brized
)获取对象的类)

但更普遍的问题似乎是关于如何在继承的构造函数中使用特定于类的配置信息。一种方法是使用单独的初始化步骤,该步骤可以在子类中重写

package tstbase;

# we don't use Exporter for OO code; exporting methods is highly counterproductive.
# we should also turn on strict and warnings.
use strict;
use warnings;

my %config = (
    "class" => "tstbase",
);

sub new {
    my $class = shift;
    my $self;
    bless $self, $class;
    $self->_init( %config );
    return $self;
};

sub _init { 
    my $self = shift;
    my %args = @_;
    $self->{name} = $args{class};
}

1;
然后:

package tstsubclass;
use parent 'tstbase';   # we have to say what class we're extending

my %config = (
  "class" => "tstsubclass",
);

sub _init { 
    my $self = shift;
    $self->SUPER::_init( %config );
}

1;
在这种情况下,子类的
\u init
方法将被父类中的构造函数调用,该构造函数调用父类的
\u init
方法,但传递其本地
%config


处理这个问题的一个更简单的方法是使用mixin或Moose角色

您的构造函数是继承的,因此工作正常。不起作用的是使用了
%config
,它分别存在于每个包中。因为您正在调用基类中定义的构造函数,所以使用了该版本的
%config
。在您的特定情况下,配置散列是不必要的,因为您可以使用传递给构造函数的
$class
变量初始化
name
成员:

sub new {
    my $class = shift;
    my $self = { };     # initialize the object as a reference to an empty hash
    $self->{"name"} = $class;
    bless ($self, $class);
    return $self;
};
这将起作用(尽管这是不必要的;您始终可以使用
Scalar::Util::brized
)获取对象的类)

但更普遍的问题似乎是关于如何在继承的构造函数中使用特定于类的配置信息。一种方法是使用单独的初始化步骤,该步骤可以在子类中重写

package tstbase;

# we don't use Exporter for OO code; exporting methods is highly counterproductive.
# we should also turn on strict and warnings.
use strict;
use warnings;

my %config = (
    "class" => "tstbase",
);

sub new {
    my $class = shift;
    my $self;
    bless $self, $class;
    $self->_init( %config );
    return $self;
};

sub _init { 
    my $self = shift;
    my %args = @_;
    $self->{name} = $args{class};
}

1;
然后:

package tstsubclass;
use parent 'tstbase';   # we have to say what class we're extending

my %config = (
  "class" => "tstsubclass",
);

sub _init { 
    my $self = shift;
    $self->SUPER::_init( %config );
}

1;
在这种情况下,子类的
\u init
方法将被父类中的构造函数调用,该构造函数调用父类的
\u init
方法,但传递其本地
%config


处理这个问题的一个更简单的方法是使用mixin或Moose角色

您的构造函数是继承的,因此工作正常。不起作用的是使用了
%config
,它分别存在于每个包中。因为您正在调用基类中定义的构造函数,所以使用了该版本的
%config
。在您的特定情况下,配置散列是不必要的,因为您可以使用传递给构造函数的
$class
变量初始化
name
成员:

sub new {
    my $class = shift;
    my $self = { };     # initialize the object as a reference to an empty hash
    $self->{"name"} = $class;
    bless ($self, $class);
    return $self;
};
这将起作用(尽管这是不必要的;您始终可以使用
Scalar::Util::brized
)获取对象的类)

但更普遍的问题似乎是关于如何在继承的构造函数中使用特定于类的配置信息。一种方法是使用单独的初始化步骤,该步骤可以在子类中重写

package tstbase;

# we don't use Exporter for OO code; exporting methods is highly counterproductive.
# we should also turn on strict and warnings.
use strict;
use warnings;

my %config = (
    "class" => "tstbase",
);

sub new {
    my $class = shift;
    my $self;
    bless $self, $class;
    $self->_init( %config );
    return $self;
};

sub _init { 
    my $self = shift;
    my %args = @_;
    $self->{name} = $args{class};
}

1;
然后:

package tstsubclass;
use parent 'tstbase';   # we have to say what class we're extending

my %config = (
  "class" => "tstsubclass",
);

sub _init { 
    my $self = shift;
    $self->SUPER::_init( %config );
}

1;
在这种情况下,子类的
\u init
方法将被父类中的构造函数调用,该构造函数调用父类的
\u init
方法,但传递其本地
%config


处理这个问题的一个更简单的方法是使用mixin或Moose角色

您的构造函数是继承的,因此工作正常。不起作用的是使用了
%config
,它分别存在于每个包中。因为您正在调用基类中定义的构造函数,所以使用了该版本的
%config
。在您的特定情况下,配置散列是不必要的,因为您可以使用传递给构造函数的
$class
变量初始化
name
成员:

sub new {
    my $class = shift;
    my $self = { };     # initialize the object as a reference to an empty hash
    $self->{"name"} = $class;
    bless ($self, $class);
    return $self;
};
这将起作用(尽管这是不必要的;您始终可以使用
Scalar::Util::brized
)获取对象的类)

但更普遍的问题似乎是关于如何在继承的构造函数中使用特定于类的配置信息。一种方法是使用单独的初始化步骤,该步骤可以在子类中重写

package tstbase;

# we don't use Exporter for OO code; exporting methods is highly counterproductive.
# we should also turn on strict and warnings.
use strict;
use warnings;

my %config = (
    "class" => "tstbase",
);

sub new {
    my $class = shift;
    my $self;
    bless $self, $class;
    $self->_init( %config );
    return $self;
};

sub _init { 
    my $self = shift;
    my %args = @_;
    $self->{name} = $args{class};
}

1;
然后:

package tstsubclass;
use parent 'tstbase';   # we have to say what class we're extending

my %config = (
  "class" => "tstsubclass",
);

sub _init { 
    my $self = shift;
    $self->SUPER::_init( %config );
}

1;
在这种情况下,子类的
\u init
方法将被父类中的构造函数调用,该构造函数调用父类的
\u init
方法,但传递其本地
%config


处理这个问题的一个更简单的方法是使用mixin或Moose角色

谢谢你的快速回复!正如您可能怀疑的那样,我的目标不是访问类名,而是执行一些复杂的类属性初始化——我刚刚发布了一个简化的示例。原始类构造函数有80行代码。我将检查这种方法是否能解决我的问题。无论如何,你解决了这个问题,所以竖起大拇指!谢谢你的快速回复!正如您可能怀疑的那样,我的目标不是访问类名,而是执行一些复杂的类属性初始化——我刚刚发布了一个简化的示例。原始类构造函数有80行代码。我将检查这种方法是否能解决我的问题。无论如何,你解决了这个问题,所以竖起大拇指!比