Perl:循环中的变量使用相同的内存位置,导致覆盖问题
当我读取文件时,第一个输出块出现在循环中。第二个是在第二个循环中,我检查数组,看看是否所有的变量都是正确的,而不是正确的。 所以我发现的问题是$curr_person不会收到一个新的内存位置,即使它超出范围或被称为新的person;并将与$people[0]等共享内存位置。这样一来,$curr_person中的任何内容都会覆盖people中的所有元素 有没有一种方法可以让$curr_person在循环的每次迭代中获得一个新的内存位置 谢谢 人员类别:Perl:循环中的变量使用相同的内存位置,导致覆盖问题,perl,Perl,当我读取文件时,第一个输出块出现在循环中。第二个是在第二个循环中,我检查数组,看看是否所有的变量都是正确的,而不是正确的。 所以我发现的问题是$curr_person不会收到一个新的内存位置,即使它超出范围或被称为新的person;并将与$people[0]等共享内存位置。这样一来,$curr_person中的任何内容都会覆盖people中的所有元素 有没有一种方法可以让$curr_person在循环的每次迭代中获得一个新的内存位置 谢谢 人员类别: $VAR1 = 'K'; $VAR2 = '
$VAR1 = 'K';
$VAR2 = 'M';
$VAR3 = '4th St';
$VAR4 = 'New York';
$VAR5 = 'NY';
$VAR6 = '10001';
K M
4th St
New York, NY 10001
$VAR1 = 'C';
$VAR2 = 'G';
$VAR3 = '3 Fifth Ave';
$VAR4 = 'New York';
$VAR5 = 'NY';
$VAR6 = '10003';
C G
3 Fifth Ave
New York, NY 10003
C G
3 Fifth Ave
New York, NY 10003
C G
3 Fifth Ave
New York, NY 10003
$VAR1 = bless( do{\(my $o = 'Person')}, 'Person' );
$VAR2 = bless( do{\(my $o = 'Person')}, 'Person' );
这是我有史以来第一个非练习(5行)Perl项目,我仍在努力理解Perl中OOP的语法。您需要的答案已经在注释中了:Person构造函数每次都必须返回相同的实例,因此,
@people
数组中的每一项都是指向同一实例的指针,当您更新一个实例时,您就是在更新所有实例
向我们显示Person::new
的代码
以后:
谢谢你的密码。结果我猜错了:并不是每次构造函数都返回相同的实例。问题在于您的数据存储:每个不同的Person实例都使用相同的变量集(在package Person;
下的my
声明),因此正如您已经体验到的,当您更新一个Person
时,您已经更新了所有变量
找一本教程或教科书,上面有一个带有get和set方法的类的示例,并特别注意每个实例如何将其数据(名字、姓氏等)与所有其他实例分开。方法将invocant作为第一个参数。invocant是在对象上调用时的对象:
package Person;
use strict;
use warnings;
my $first_name;
my $last_name;
my $street_address;
my $town;
my $state;
my $zip_code;
my $unique_id;
sub new
{
my $instance = shift;
bless \$instance, "Person";
}
或在该类上调用时的类名(作为普通字符串):
$person->foo(); # $_[0] is Person object
通常的new
方法如下所示:
Person->foo(); # $_[0] is "Person" string
第一个参数是类名。我们祝福进入那个类(不一定是Person
!),这样我们的类就可以被继承,新的方法就可以被重用
在其他方法中,我们使用对象中的字段(它只是一个特殊的hashref)来存储数据——但不是全局变量或词法变量
# Usage: Person->new(first_name => "Fred", last_name => "Flintstone")
sub new {
my ($class, %args) = @_;
# process arguments
bless \%args => $class;
}
等等。这是你真正应该阅读的解释
因为编写新的
和访问器是重复的和枯燥的,所以人们提出了智能对象框架,使处理对象更具表现力。最重要的是。然后我们可以写:
sub first_name {
my $self = shift;
if (@_) { # if there are args
$self->{first_name} = shift;
}
return $self->{first_name};
}
您的代码很好(可以改进,但没有错)。您可以通过
0+$curr\u person
获取对象ID,除非它重载–但每次都应该不同。似乎Person
类中有一个bug。你能展示一下代码吗(比如构造器)?看起来它可能使用了容易出错的“由内而外对象”模式。在Person类中的新子例程中看起来有些奇怪,比如总是返回同一个实例。Data::Dumper
输出看起来像是使用bless\$class
祝福对象,而不是使用bless$hashref,$class
。在中编辑。不过我不知道该怎么修。
sub first_name {
my $self = shift;
if (@_) { # if there are args
$self->{first_name} = shift;
}
return $self->{first_name};
}
package Person;
use Moose; # this is now a Moose class
# declare attributes with `has`:
has first_name => (
is => 'rw', # this is now a read-write attribute
)
...
has street_address => ( is => 'rw');
has town => ( is => 'rw');
has state => ( is => 'rw');
has zip_code => ( is => 'rw');
...
# new is autogenerated!
# a normal method
sub get_full_address {
my ($self) = @_;
return sprintf "%s\n%s, %s %s",
$self->street_address, $self->town, $self->state, $self->zip_code;
}