Perl:循环中的变量使用相同的内存位置,导致覆盖问题

Perl:循环中的变量使用相同的内存位置,导致覆盖问题,perl,Perl,当我读取文件时,第一个输出块出现在循环中。第二个是在第二个循环中,我检查数组,看看是否所有的变量都是正确的,而不是正确的。 所以我发现的问题是$curr_person不会收到一个新的内存位置,即使它超出范围或被称为新的person;并将与$people[0]等共享内存位置。这样一来,$curr_person中的任何内容都会覆盖people中的所有元素 有没有一种方法可以让$curr_person在循环的每次迭代中获得一个新的内存位置 谢谢 人员类别: $VAR1 = 'K'; $VAR2 = '

当我读取文件时,第一个输出块出现在循环中。第二个是在第二个循环中,我检查数组,看看是否所有的变量都是正确的,而不是正确的。 所以我发现的问题是$curr_person不会收到一个新的内存位置,即使它超出范围或被称为新的person;并将与$people[0]等共享内存位置。这样一来,$curr_person中的任何内容都会覆盖people中的所有元素

有没有一种方法可以让$curr_person在循环的每次迭代中获得一个新的内存位置

谢谢

人员类别:

$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;
}