尝试使用map和grep来解决这个问题,任何想法都错了吗?我一直在接受 当我尝试打印新哈希的值时,不能使用字符串(“10”)作为HASH参考,而“严格参考”错误
sub scrub_hash{
my($self,$hash_ref) = @_;
my $scrubbed_hash = map { defined $hash_ref->{$_} ? ($_ => $hash_ref->{$_}) : () } keys %{$hash_ref};
print STDERR "[scrub]". $_."\n" for values %{$scrubbed_hash};
}
在这里使用 ...
my $params_hash = $cgi->Vars();
my $scrubbed = $self->scrub_empty_params($params_hash) if $self->is_hash($params_hash);
在这种情况下,通过帖子提交表单时未定义的参数仍然显示为key1 =& key2 =所以scrub将关闭em
答案 0 :(得分:6)
在这一行:
my $scrubbed_hash = map { defined $hash_ref->{$_} ? ($_ => $hash_ref->{$_}) : () } keys %{$hash_ref};
您正在将map
的列表分配到标量$scrubbed_hash
。标量上下文中的map
将返回列表中元素的数量(10)。
不是分配给标量,而是分配复数哈希:
sub scrub_hash{
my($self,$hash_ref) = @_;
my %scrubbed_hash = map { defined $hash_ref->{$_} ? ($_ => $hash_ref->{$_}) : () } keys %{$hash_ref};
print STDERR "[scrub]". $_."\n" for values %scrubbed_hash;
}
如果你真的想为$scrubbed_hash
使用标量,你需要用{map {...} args}
包装map语句,这将在列表中构造一个匿名哈希。
要过滤掉适当的元素,您可以使用delete
函数:
my %hash = (foo => 1, bar => undef, baz => 2);
defined $hash{$_} or delete $hash{$_} for keys %hash;
print join ', ' => keys %hash; # foo, baz
根据更新:
scrub_empty_params
方法应如下所示:
sub scrub_empty_params {
my ($self, $hash) = @_;
{map {defined $$hash{$_} ? ($_ => $$hash{$_}) : ()} keys %$hash}
}
如果这对您不起作用,则可能是您的值已定义,但长度为0。
sub scrub_empty_params {
my ($self, $hash) = @_;
{map {(defined $$hash{$_} and length $$hash{$_}) ? ($_ => $$hash{$_}) : ()} keys %$hash}
}
您可能希望通过创建返回已过滤哈希的其他->Vars()
方法从API中删除一些样板:
sub clean_vars {
my ($self) = @_;
$self->scrub_empty_params($self->Vars)
}
答案 1 :(得分:2)
试试这个:
my %scrubbed_hash = map { $_ => $hash_ref->{ $_ } } grep { defined $hash_ref->{$_} } keys %{$hash_ref};