试图用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};
}
Run Code Online (Sandbox Code Playgroud)
在这里用...
my $params_hash = $cgi->Vars();
my $scrubbed = $self->scrub_empty_params($params_hash) if $self->is_hash($params_hash);
Run Code Online (Sandbox Code Playgroud)
在这种情况下,通过邮件提交表单时未定义的参数仍然显示为key1 =&key2 =所以scrub需要关闭em
在这一行:
my $scrubbed_hash = map { defined $hash_ref->{$_} ? ($_ => $hash_ref->{$_}) : () } keys %{$hash_ref};
Run Code Online (Sandbox Code Playgroud)
您正在将标记分配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;
}
Run Code Online (Sandbox Code Playgroud)
如果你真的想使用标量,$scrubbed_hash
你将需要包装map语句,用{map {...} args}
它来构造列表中的匿名哈希.
要过滤掉适当的元素,您可以使用以下delete
函数:
my %hash = (foo => 1, bar => undef, baz => 2);
defined $hash{$_} or delete $hash{$_} for keys %hash;
print join ', ' => keys %hash; # foo, baz
Run Code Online (Sandbox Code Playgroud)
每次更新:
该scrub_empty_params
方法应如下所示:
sub scrub_empty_params {
my ($self, $hash) = @_;
{map {defined $$hash{$_} ? ($_ => $$hash{$_}) : ()} keys %$hash}
}
Run Code Online (Sandbox Code Playgroud)
如果这对您不起作用,则可能是您的值已定义,但长度为0.
sub scrub_empty_params {
my ($self, $hash) = @_;
{map {(defined $$hash{$_} and length $$hash{$_}) ? ($_ => $$hash{$_}) : ()} keys %$hash}
}
Run Code Online (Sandbox Code Playgroud)
您可能希望通过创建->Vars()
返回过滤哈希的其他方法从API中删除一些样板:
sub clean_vars {
my ($self) = @_;
$self->scrub_empty_params($self->Vars)
}
Run Code Online (Sandbox Code Playgroud)