Perl - 具有修改后数据的新哈希项,源自另一个条目的馈线哈希,破坏了第一个条目
Perl - New Hash item with modified data, sourced from a feeder hash that sourced another entry, clobbers the first entry
我正在尝试添加一个哈希条目和一个新的、更新的哈希条目,它们来自相同的馈线哈希和原始数据。
但是,当我更新第二个条目的数据时...它破坏了原始条目...即使该数据没有更改...它只能更改,因为两者都是从相同的馈线哈希条目。
这是我为测试此问题而创建的测试程序中的示例子例程 - 它使用 Tk 进行输出...
sub hash_issue {
my %feeder = ();
my %global = ();
my %personal = ();
my $key = 'John';
my $new_key = 'Johnathan';
$feeder{$key}{First_Name} = 'John';
$feeder{$key}{Last_Name} = '';
$feeder{$key}{Address} = '123 Main Street';
$feeder{$key}{City} = 'Springfield';
$feeder{$key}{State} = '';
$feeder{$key}{Zip} = '';
$feeder{$key}{Is_Registered} = 0;
$global{$key} = $feeder{$key};
$main->Output->Append("First Name = $global{$key}{First_Name} Last Name = $global{$key}{Last_Name} Address = $global{$key}{Address} Registered = $global{$key}{Is_Registered}\r\n");
$global{$new_key} = $feeder{$key};
$global{$new_key}{First_Name} = $new_key;
$global{$new_key}{Is_Registered} = 1;
$main->Output->Append("First Name = $global{$key}{First_Name} Last Name = $global{$key}{Last_Name} Address = $global{$key}{Address} Registered = $global{$key}{Is_Registered}\r\n");
$main->Output->Append("First Name = $global{$new_key}{First_Name} Last Name = $global{$new_key}{Last_Name} Address = $global{$new_key}{Address} Registered = $global{$new_key}{Is_Registered}\r\n");
}
这是输出...
名字 = John 姓氏 = 地址 = 123 Main Street Registered = 0
名字 = Johnathan 姓氏 = 地址 = 123 Main Street Registered = 1
名字 = Johnathan 姓氏 = 地址 = 123 Main Street Registered = 1
(添加了额外的行以清理 post...)
我如何修改它以防止破坏原始条目...REAL 代码包含更多子散列键。
你的问题就在这里
$global{$new_key} = $feeder{$key};
这只是复制一个参考。如果你想要一个实际的副本,你需要克隆你的数据。
use Clone qw( clone );
$global{$new_key} = clone( $feeder{$key} );
请调查以下代码片段是否符合您的问题。
根据您的描述,我的理解是您尝试使用哈希 %feeder
值的副本创建新哈希 %global
(以 $new_key
作为键),然后更改一些其中的值。
注意:%global
变量在子程序中的声明有些混乱
use strict;
use warnings;
use feature 'say';
hash_issue();
sub hash_issue {
my(%feeder, %global);
my $key = 'John';
my $new_key = 'Johnathan';
my @fields = (
'First_Name',
'Last_Name',
'Address',
'City',
'State',
'Zip',
'Is_Registered'
);
my @values = (
'John',
'',
'123 Main Street',
'Springfield',
'',
'',
0
);
@{$feeder{$key}}{@fields} = @values;
@{$global{$new_key}}{@fields} = @{$feeder{$key}}{@fields};
speak_out($key, \%feeder);
speak_out($new_key, \%global);
$global{$new_key}{First_Name} = $new_key;
$global{$new_key}{Is_Registered} = 1;
speak_out($new_key, \%global);
}
sub speak_out {
my $key = shift;
my $data = shift;
say "
Key = $key
------------------------------------
First Name = $data->{$key}{First_Name}
Last Name = $data->{$key}{Last_Name}
Address = $data->{$key}{Address}
Registered = $data->{$key}{Is_Registered}
";
}
输出
Key = John
------------------------------------
First Name = John
Last Name =
Address = 123 Main Street
Registered = 0
Key = Johnathan
------------------------------------
First Name = John
Last Name =
Address = 123 Main Street
Registered = 0
Key = Johnathan
------------------------------------
First Name = Johnathan
Last Name =
Address = 123 Main Street
Registered = 1
我正在尝试添加一个哈希条目和一个新的、更新的哈希条目,它们来自相同的馈线哈希和原始数据。
但是,当我更新第二个条目的数据时...它破坏了原始条目...即使该数据没有更改...它只能更改,因为两者都是从相同的馈线哈希条目。
这是我为测试此问题而创建的测试程序中的示例子例程 - 它使用 Tk 进行输出...
sub hash_issue {
my %feeder = ();
my %global = ();
my %personal = ();
my $key = 'John';
my $new_key = 'Johnathan';
$feeder{$key}{First_Name} = 'John';
$feeder{$key}{Last_Name} = '';
$feeder{$key}{Address} = '123 Main Street';
$feeder{$key}{City} = 'Springfield';
$feeder{$key}{State} = '';
$feeder{$key}{Zip} = '';
$feeder{$key}{Is_Registered} = 0;
$global{$key} = $feeder{$key};
$main->Output->Append("First Name = $global{$key}{First_Name} Last Name = $global{$key}{Last_Name} Address = $global{$key}{Address} Registered = $global{$key}{Is_Registered}\r\n");
$global{$new_key} = $feeder{$key};
$global{$new_key}{First_Name} = $new_key;
$global{$new_key}{Is_Registered} = 1;
$main->Output->Append("First Name = $global{$key}{First_Name} Last Name = $global{$key}{Last_Name} Address = $global{$key}{Address} Registered = $global{$key}{Is_Registered}\r\n");
$main->Output->Append("First Name = $global{$new_key}{First_Name} Last Name = $global{$new_key}{Last_Name} Address = $global{$new_key}{Address} Registered = $global{$new_key}{Is_Registered}\r\n");
}
这是输出...
名字 = John 姓氏 = 地址 = 123 Main Street Registered = 0
名字 = Johnathan 姓氏 = 地址 = 123 Main Street Registered = 1
名字 = Johnathan 姓氏 = 地址 = 123 Main Street Registered = 1
(添加了额外的行以清理 post...)
我如何修改它以防止破坏原始条目...REAL 代码包含更多子散列键。
你的问题就在这里
$global{$new_key} = $feeder{$key};
这只是复制一个参考。如果你想要一个实际的副本,你需要克隆你的数据。
use Clone qw( clone );
$global{$new_key} = clone( $feeder{$key} );
请调查以下代码片段是否符合您的问题。
根据您的描述,我的理解是您尝试使用哈希 %feeder
值的副本创建新哈希 %global
(以 $new_key
作为键),然后更改一些其中的值。
注意:%global
变量在子程序中的声明有些混乱
use strict;
use warnings;
use feature 'say';
hash_issue();
sub hash_issue {
my(%feeder, %global);
my $key = 'John';
my $new_key = 'Johnathan';
my @fields = (
'First_Name',
'Last_Name',
'Address',
'City',
'State',
'Zip',
'Is_Registered'
);
my @values = (
'John',
'',
'123 Main Street',
'Springfield',
'',
'',
0
);
@{$feeder{$key}}{@fields} = @values;
@{$global{$new_key}}{@fields} = @{$feeder{$key}}{@fields};
speak_out($key, \%feeder);
speak_out($new_key, \%global);
$global{$new_key}{First_Name} = $new_key;
$global{$new_key}{Is_Registered} = 1;
speak_out($new_key, \%global);
}
sub speak_out {
my $key = shift;
my $data = shift;
say "
Key = $key
------------------------------------
First Name = $data->{$key}{First_Name}
Last Name = $data->{$key}{Last_Name}
Address = $data->{$key}{Address}
Registered = $data->{$key}{Is_Registered}
";
}
输出
Key = John
------------------------------------
First Name = John
Last Name =
Address = 123 Main Street
Registered = 0
Key = Johnathan
------------------------------------
First Name = John
Last Name =
Address = 123 Main Street
Registered = 0
Key = Johnathan
------------------------------------
First Name = Johnathan
Last Name =
Address = 123 Main Street
Registered = 1