你想多了。如果您为列表使用数组而不是哈希,则无需担心head和last。数组的头是$array[0]
,最后一个成员是$array[-1]
。简单易做。
这是定义列表的快速标准类定义。我只定义了一个构造函数(新的子例程)和一个方法(列表)。
package Local::List;
sub new {
my $class = shift;
my $self = {};
bless $self, $class;
$self->list([]);
}
sub list {
my $self = shift;
my $list_ref = shift;
if (ref $list_ref ne "ARRAY) {
return;
}
if (defined $list_ref) {
$self->{LIST} = $list_ref;
}
if wantarray {
return $self->{LIST};
}
}
第一件事:使用其他人使用的相同标准名称。用于构造函数new
。当我尝试查看有关如何使用您的类的文档时,我可以搜索new一词并知道这就是我创建类对象的方式。此外,使用变量名和. 这就是其他人所做的,所以很容易知道发生了什么。$class
$self
请注意,在我的new
子例程中,传递的第一项是类的名称,而传递给我的其他子例程的第一项是对我的类对象的引用(即$self
)。这可能是关于类的最难理解的事情。
请注意new
,我立即创建我的$self
并祝福它。这样,我可以调用我的其他子例程(我的方法)来为我进行设置。这样,我的构造函数不知道我的类的结构。这有很多优点:
- 当(不是如果)我修改我的类时,我不必修改构造函数。
- 我的构造函数总是与我的所有方法同步。
- 当我开始定义类时,我不必知道我的类对象的结构。我可以开始编写我的课程,而不必担心所有关于它如何工作的肮脏细节。
请注意,list
子例程(或方法)可以设置列表或返回列表。如果您使用相同的子例程来设置或获取值,会容易得多。同样在您的方法子例程中,当您的方法函数返回错误时,请使用空白返回。否则,总是返回一些东西。这使得测试方法是否失败变得容易。
让我们看看您可能想要的其他一些方法。让我们拥有所有四个标准列表函数:
这是一个例子:
sub push {
my $self = shift;
my $member = shift;
if (not defined $member) {
return;
}
my $list_ref = $self->list;
my $return = push @{ $list_ref }, $member;
$self->list($list_ref);
return $return;
}
哇,这很简单。请注意,pop
不知道我的班级是什么样的。它使用该list
方法来检索列表引用。然后它使用内置push
方法将成员推送到列表中。我保存该返回值,这就是我将返回的值。我什至不确定push
返回的是什么。我所知道的是,如果 push 成功,它会返回一些东西。(是的,我知道它返回列表中的项目数)。
其他三个功能大致相同。这里还有一些:
您需要为current做的就是存储当前值。使用相同的函数来设置和获取值。请注意,我的list
方法或我的push
方法,或我的new
构造函数知道或关心您如何存储它。next
我们的和previous
方法也不行。他们需要做的就是增加或减少 的值并使用方法子例程current
将其存储回来:current
sub next {
my $self = shift
my @list = $self->list; #Returns a list;
my $current = $self->current;
my $list_size = $#list;
if ($current eq $list_size) {
return; #Can't return a value after the end of the list!
}
$current++; #Increment the value;
my $value = $list[$current]; #I'll return this
$self->current($current) #Store the new current
return $value;
}
而且,现在是您问题的基础:获取列表的最后一个值和头值。这是最后一个
sub last {
my $self = shift;
my $list_ref = $self->list;
return ${ $list_ref }[-1];
}
快速复制和粘贴会让我头疼:
sub head {
my $self = shift;
my $list_ref = $self->list;
return ${ $list_ref }[0];
}
就是这样!你所做的一切担心都是徒劳的。
对不起,很长的帖子。我只是想强调 Perl 中的面向对象编程并不是那么棘手,只要您遵循一些简单的指导原则。
(简单?use Moose;
不,我说简单!)。;-)