我有一个像这样的基类:
package MyClass;
use vars qw/$ME list of vars/;
use Exporter;
@ISA = qw/Exporter/;
@EXPORT_OK = qw/ many variables & functions/;
%EXPORT_TAGS = (all => \@EXPORT_OK );
sub my_method {
}
sub other_methods etc {
}
--- more code---
我想继承MyClass
,但仅限于一种方法。
package MySubclass;
use MyClass;
use vars qw/@ISA/;
@ISA = 'MyClass';
sub my_method {
--- new method
}
我希望像原来的MySubclass
一样调用此MyClass
,并且仍然可以访问Exporter
中的所有变量和函数。但是,我在从原始类Exporter
获取MyClass
变量时遇到问题,无法正确导出。我是否需要在子类内再次运行Exporter
?这似乎是多余的,不清楚。
示例文件:
#!/usr/bin/perl
use MySubclass qw/$ME/;
-- rest of code
但是当我尝试导入$ME
变量时出现编译错误。有什么建议吗?
答案 0 :(得分:8)
您应该通过方法访问所有内容。忘记传递变量。
您遇到语法错误,因为您遇到语法错误:
use MySubclass /$ME/; # syntax error - that's the match operator
你想要一个清单:
use MySubclass qw/$ME/;
然而,不要这样做。通过方法提供对这些数据的访问。由于您将继承这些方法,因此您不需要(也不应该使用)Exporter:
package MyClass;
BEGIN {
my $ME;
sub get_me { $ME }
sub set_me { $ME = shift }
}
现在您的子类只是:
package MySubclass;
use parent( MyClass );
sub my_method { ... }
如果您需要分享许多变量,有各种模块可以自动处理访问者详细信息。
答案 1 :(得分:4)
通常,OO Perl和Exporter通常是分开的,而不是将它们混合在一起。这是其中一个原因。
就像布莱恩所说的那样,如果你把所有的垃圾都拿出来,把它变成类属性/方法,你将会更容易让它在第一时间开始工作并在将来进一步扩展它。并彻底摆脱出口商。一个简单的事实是,你想要它的方式要求你导入和重新导出所有东西应该是一个很大的,闪烁的线索,这可能是一个更好的方法(即,一种不涉及出口商的方式)。 / p>
答案 2 :(得分:3)
您实际上并未真正从MySubclass
继承MyClass
- MySubClass
是 MyClass
的用户。你正在做的是覆盖MyClass
的一些行为,但是如果你认为这是继承,你只会迷惑自己,因为它不是(例如:你的构造函数在哪里?)我无法'弄清楚你要做什么,直到我忽略了代码做的所有内容,然后阅读你想要发生的事情的描述。
好的,所以你有一个导入一些符号的类 - 一些函数和一些变量:
package MyClass;
use strict;
use warnings;
use Exporter 'import'; # gives you Exporter's import() method directly
our @EXPORT_OK = qw/ many variables & functions/;
our %EXPORT_TAGS = (all => \@EXPORT_OK );
our ($ME, $list, $of, $vars);
sub my_func {
}
sub other_func {
}
1;
然后你来写一个从MyClass导入所有的类,再次将它全部导出,但是将一个函数换成另一个函数:
package MyBetterclass;
use strict;
use warnings;
use Exporter 'import'; # gives you Exporter's import() method directly
our @EXPORT_OK = qw/ many variables & functions /;
our %EXPORT_TAGS = (all => \@EXPORT_OK );
use MyClass ':all';
sub my_func {
# new definition
}
1;
就是这样!请注意,我启用了严格的检查和警告,并更改了实际功能的“方法”的名称。
另外,我没有使用use vars
(documentation说它已经过时了,所以如果你仍然想要在不理解其机制的情况下使用它,这将是一个大红旗。)
答案 3 :(得分:0)
# use setters and getters the Perl's way
#
# ---------------------------------------
# return a field's value
# ---------------------------------------
sub get {
my $self = shift;
my $name = shift;
return $self->{ $name };
} #eof sub get
#
# ---------------------------------------
# set a field's value
# ---------------------------------------
sub set {
my $self = shift;
my $name = shift;
my $value = shift;
$self->{ $name } = $value;
}
#eof sub set
#
# ---------------------------------------
# return the fields of this obj instance
# ---------------------------------------
sub dumpFields {
my $self = shift;
my $strFields = ();
foreach my $key ( keys %$self ) {
$strFields .= "$key = $self->{$key}\n";
}
return $strFields;
} #eof sub dumpFields