如何在子例程中取消引用散列并像在调用例程中一样对其进行处理?
How can I dereference a hash in a subroutine an work on it like in the calling routine?
我有一个 perl 例程,它从 .csv 文件中生成散列。应在子例程中检查这些值。
所以我有一个散列 %my_values
并调用子例程 check (\%my_values)
:
sub read_csv {
...
# key: headline entry
# value: the value in the current row
%my_hash;
...
my ($has_error, $err_msg) = check (\%my_hash);
}
sub check {
my($hash_ref) = @_;
%my_hash = %$hash_ref;
# Get the artikel number of the article
$my_hash {'article_number'} = get_artnr($my_hash {'article'});
if (not $my_hash{'article_number'}) {
return 1, "Article $my_hash{'article'} not found!";
}
# check price (I'm in germany, there must be a conversation from ',' to '.')
$my_hash {'price'} =~ s/,/./;
if (not $my_hash{'price'} =~ m/^\d+(\.\d+)?$/) {
return 1, "Invalid format of price";
}
return 0, "";
}
起初,这似乎工作正常。但后来我意识到,价格格式既没有改变,也没有密钥 article_number
可用。
直接在参考上工作使其成为:
# In this case, it works!
sub check {
my($hash_ref) = @_;
# Get the artikel number of the article
$hash_ref->{'article_number'} = get_artnr($hash_ref->{'article'});
if (not $hash_ref->{'article_number'}) {
return 1, "Article $hash_ref->{'article'} not found!";
}
# check price (I'm in germany, there must be a conversation from ',' to '.')
$hash_ref->{'price'} =~ s/,/./;
if (not $hash_ref->{'price'} =~ m/^\d+(\.\d+)?$/) {
return 1, "Invalid format of price";
}
return 0, "";
}
所以我认为 %my_hash = %$hash_ref;
复制引用而不是取消引用。
如何在子例程中取消引用散列并像在调用例程中一样对其进行处理?
这是一个使用 5.26 中引入的名为 refaliasing introduced in Perl 5.22 (optionally combined with the declared_refs 的新功能的示例)
use v5.26;
use warnings; # IMPORTANT: this line must come before "use experimental"
use strict;
use feature qw(say);
use experimental qw(declared_refs refaliasing);
{ # <-- introduce scope to avoid leaking lexical variables into subs below
my %hash = (a=>1, b=>2);
check(\%hash);
say "Value of 'a' key is now: ", $hash{a};
}
sub check {
my (\%hash) = @_;
$hash{a} = 3;
}
输出:
Value of 'a' key is now: 3
或者您可以使用 arrow operator:
sub check {
my ($hash) = @_;
$hash->{a} = 3;
}
我有一个 perl 例程,它从 .csv 文件中生成散列。应在子例程中检查这些值。
所以我有一个散列 %my_values
并调用子例程 check (\%my_values)
:
sub read_csv {
...
# key: headline entry
# value: the value in the current row
%my_hash;
...
my ($has_error, $err_msg) = check (\%my_hash);
}
sub check {
my($hash_ref) = @_;
%my_hash = %$hash_ref;
# Get the artikel number of the article
$my_hash {'article_number'} = get_artnr($my_hash {'article'});
if (not $my_hash{'article_number'}) {
return 1, "Article $my_hash{'article'} not found!";
}
# check price (I'm in germany, there must be a conversation from ',' to '.')
$my_hash {'price'} =~ s/,/./;
if (not $my_hash{'price'} =~ m/^\d+(\.\d+)?$/) {
return 1, "Invalid format of price";
}
return 0, "";
}
起初,这似乎工作正常。但后来我意识到,价格格式既没有改变,也没有密钥 article_number
可用。
直接在参考上工作使其成为:
# In this case, it works!
sub check {
my($hash_ref) = @_;
# Get the artikel number of the article
$hash_ref->{'article_number'} = get_artnr($hash_ref->{'article'});
if (not $hash_ref->{'article_number'}) {
return 1, "Article $hash_ref->{'article'} not found!";
}
# check price (I'm in germany, there must be a conversation from ',' to '.')
$hash_ref->{'price'} =~ s/,/./;
if (not $hash_ref->{'price'} =~ m/^\d+(\.\d+)?$/) {
return 1, "Invalid format of price";
}
return 0, "";
}
所以我认为 %my_hash = %$hash_ref;
复制引用而不是取消引用。
如何在子例程中取消引用散列并像在调用例程中一样对其进行处理?
这是一个使用 5.26 中引入的名为 refaliasing introduced in Perl 5.22 (optionally combined with the declared_refs 的新功能的示例)
use v5.26;
use warnings; # IMPORTANT: this line must come before "use experimental"
use strict;
use feature qw(say);
use experimental qw(declared_refs refaliasing);
{ # <-- introduce scope to avoid leaking lexical variables into subs below
my %hash = (a=>1, b=>2);
check(\%hash);
say "Value of 'a' key is now: ", $hash{a};
}
sub check {
my (\%hash) = @_;
$hash{a} = 3;
}
输出:
Value of 'a' key is now: 3
或者您可以使用 arrow operator:
sub check {
my ($hash) = @_;
$hash->{a} = 3;
}