16

I have this piece of code that I'm trying to get my head around, I don't even know if its syntactically correct (part of the exercise I guess!)

%{$records}

What do the curly braces signify? I've seen the same case but with a @ operator used instead of the $ if that makes a difference.

Thanks guys!

4

3 回答 3

13

perlref 文档的“使用参考”部分解释了这一点。

2.将标识符(或标识符链)作为变量或子例程名称的一部分放在任何地方,都可以用返回正确类型引用的 BLOCK 替换标识符。换句话说,前面的例子可以这样写:

   $bar = ${$scalarref};
   push(@{$arrayref}, $filename);
   ${$arrayref}[0] = "January";
   ${$hashref}{"KEY"} = "VALUE";
   &{$coderef}(1,2,3);
   $globref->print("output\n"); # iff IO::Handle is loaded

在您的情况下,$records必须是对哈希的引用(因为最外层%),{$records}是返回引用并%{$records}给出原始哈希的块。

花括号围绕一个真正的块。实际上,您可以将上面的代码替换为

%{ if ($records) { $records } else { $default_records } }

但是,正如文档前面所指出的,即使是您问题中的较短版本也可以简化。

1.将标识符(或标识符链)作为变量或子例程名称的一部分放在任何地方,都可以将标识符替换为包含正确类型引用的简单标量变量:

   $bar = $$scalarref;
   push(@$arrayref, $filename);
   $$arrayref[0] = "January";
   $$hashref{"KEY"} = "VALUE";
   &$coderef(1,2,3);
   print $globref "output\n";

因为$records是一个简单的标量,%$records是底层的散列。

相反,如果$records是对数组的引用,则取消引用它的语法是@$recordsor @{$records}

于 2013-02-16T17:03:59.673 回答
9

与许多 Unix shell 一样,Perl 允许使用大括号来分隔变量标识符,因此my ${scalar}my $scalar. 这很有用,例如,将变量的值插入字符串时,何时"$scalartext"查找具有标识符的变量scalartext,何时预期是$scalar.'text'。取而代之的是,您可以编写"${scalar}text"以获得正确的结果。

Perl 将接受变量标识符或返回对大括号内变量的引用的表达式,因此%{$hashref}%$hashref. 请注意,字符串是不可接受的,因为它被视为符号引用,在 下是错误的strict 'refs',所以${'scalar'}这里是错误的。

在您的情况下,%{$records}与 相同%$records,有些人更喜欢它,因为它使取消引用变得清晰。它表示散列引用$records所指的散列。

于 2013-02-16T15:33:37.167 回答
5

这是您取消引用引用的方式。

请参阅perldoc perlref

像往常一样%or@说明你想要什么样的数据(“哈希”或“数组”)。

后面是一个 {},该块返回对适当数据类型的引用。

所以:%{$records}接受一个包含对哈希的引用的标量 ( $records),并返回一个哈希。

于 2013-02-16T15:07:40.027 回答