我编写了以下模块但不确定如何引用“last”和“head”节点。以及将下一个节点的地址存储在前一节点的“{nextNode}”中。
我试图在存储时保存类的引用,但后来它抱怨:“不是List.pm中的HASH引用”;我理解为什么但不确定语法是怎样的。
如果我取消引用$ head和$ last($$ last-> {nextNode} = \ $ class),那么我认为它正在使用我班级的实际名称;列出而不是我想要的上一个对象。
package List;
my $head = undef;
my $last = undef;
sub new {
my $class = shift;
# init the head of the list
if ($head == undef) {
$head = \$class;
print "updated head to:$head", "\n";
}
$last = \$class;
$last->{nextNode} = \$class; # update previous node to point on this new one
print "updated last to:$last", "\n";
my $self = {};
$self->{value} = shift;
$self->{nextNode} = ""; # reset next to nothing since this node is last
return bless $self, $class;
}
谢谢你们
答案 0 :(得分:6)
您应该将$self
存储在任何地方,而不是\$class
。存储$ class只是存储类的名称,而不是对象本身。
此外,对于$self->{nextNode}
,我会存储undef
而不是空字符串。或者更好的是,根本不要创建它,并在检查它是否存在时使用exists
。
答案 1 :(得分:3)
你在想它。如果您使用数组作为列表而不是哈希,则无需担心 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会返回某些东西。 (是的,我知道它会返回列表中的项目数。)
其他三个功能或多或少相同。这里还有一些:
当前所需要做的就是存储当前值。使用相同的函数来设置和获取值。请注意,我的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;
怎么样?不,我说简单!)。 ; - )
答案 2 :(得分:0)
我只想发布我的最终工作版本以备记录和您的反馈/意见。 再次感谢!!
package List;
my $head = undef;
my $last = undef;
sub new {
my ($class, $val) = @_;
my $self = {};
# init the head of the list
if (!defined $head) {
$head = $self;
print "updated the head of the list ($head)" . "\n";
}
else {
$last->{nextNode} = $self; # update previous node to point on this new one
}
$last = $self; # this object is now the last one
$self->{value} = $val; # store the value
$self->{nextNode} = undef; # reset next to nothing since this node is last
return bless $self, $class;
}
sub setVal {
my ($class, $val) = @_;
$class->{value} = $val;
}
sub getVal {
my $class = shift;
print $class->{value};
}
sub getNext {
my $class = shift;
return $class->{nextNode};
}
# return true if this is the last node, otherwise false.
sub isLast {
my $class = shift;
return 1 if !defined $class->{nextNode};
return 0;
}
sub getLast {
return $last;
}
sub getHead {
return $head;
}
# looping through all the list and printing the values
sub showList {
my $node = $head; # set temp node to the head
while ( !$node->isLast() ) {
print $node->{value} . "\n";
$node = $node->{nextNode};
}
# printing last value. (should be defined but I check it just in case)
print $node->{value} . " (last)\n" if defined $node->{value};
}
1;
脚本:
my $n0 = new List(4);
my $n1 = new List(8);
my $n2 = new List(9);
my $n3 = new List(3);
my $n4 = new List(1);
my $n5 = new List(0);
my $n6 = new List(5);
print "\nShow list: \n";
$n2->showList(); # any object will print the list