我是Perl的新手,我对其变量范围的工作原理感到困惑。 我正在尝试从MySQL查询的结果创建一个Hashes数组。
以下代码按预期使用不使用使用严格
my %hash = ();
while (my %hash = %{$qhand->fetchrow_hashref()} ) {
push(@results, {%hash});
}
但启用严格时会产生以下错误:
不能在[filename]第XX行(while语句的行)中使用未定义的值作为HASH引用。
有人可以告诉我,我做错了什么,严格的相应规则是什么,我是炫耀?
答案 0 :(得分:8)
您违反了strict的refs
部分。当您尝试使用非引用值作为引用时,Perl想要创建一个“符号引用”,这通常不是您想要的,尽管它默默地继续程序(可能不是“工作”,而是继续)。通过启用限制,您可以捕获这些情况。
在你的例子和Jonathan的回答中,看起来你正在做很多杂技来撤销哈希引用,只是为了让它们再次成为哈希引用。您是否有理由不将其作为哈希引用?
while( my $href = $qhand->fetchrow_hashref ) {
push @results, $href;
}
而且,如果您只想将所有结果作为哈希引用,那么有一个DBI方法,以便您可以跳过while
循环:
my $results_array_ref = $qhand->fetchall_arrayref( {} );
答案 1 :(得分:3)
这是一个运行时错误(在脚本工作一段时间后),而不是编译时错误,不是吗?
在将散列引用转换为散列之前,您需要检查从$qhand->fetchrow_hashref()
(来自Perl DBI)返回的散列引用是否有效。如果没有其他要提取的行,则会返回undef
,而您无法将undef
转换为%hash
。
你也不想要两个名为%hash
的哈希 - 无论是在循环中还是不在循环中,而不是两者。
while (my $href = $qhand->fetchrow_hashref())
{
my %hash = %{$href};
push(@results, {%hash});
}
答案 2 :(得分:1)
我遇到了同样的问题,所以这是我实施的解决方案。
my %rtn;
my $hr = $handle->fetchrow_hashref;
if($hr)
{
do
{
%rtn=%{$hr};
...snip...
...snip...
$hr = $handle->fetchrow_hashref;
}
while ($hr);
}
将标量($ hr)设置为预期引用($ handle-> fetchrow_hashref)以在循环之前和转换之前(%{})测试null(if($ hr)),然后完成之后该引用获取下一个。一旦它在下一个打破循环的提取调用中结束为null,你就不用担心了。
答案 3 :(得分:-7)
我不是Perl专家,但它可能是函数调用$qhand->fetchrow_hashref()
上的转换。
如果此函数已经返回哈希,为什么不跳过强制转换?