问题:
我有一个数据结构,类似于以下内容:
$foo = [
{
bar => "baz",
},
];
我想在此数据结构中嵌入代码,将另一个hashref添加到foo
列表中,以便最终结果如下:
$foo = [
{
bar => "baz",
},
{
new => "new",
},
];
可能的解决方案:
1:我最初的直觉是使用eval
$foo = [
{
bar => "baz",
},
eval { return {
new => "new",
}},
];
2: @Sputnik向我指出perlref。 "制作参考 - > 4"部分帮我提出了另一种可能的解决方案
$foo = [
{
bar => "baz",
},
&{ sub{ return {
new => "new",
}}},
];
问题:
1.这两种解决方案是否相同?
2.如果它们不相同,每个的利弊是什么?
3.还有其他解决方案吗?
4.如果还有其他解决方案,与上述解决方案相比,它们的优点和缺点是什么?
答案 0 :(得分:1)
push @{ $array_ref }, { new => "new" };
我认为您应该阅读有关参考的文档:
http://perldoc.perl.org/perlreftut.html
http://perldoc.perl.org/perlref.html
<强>样本强>:
use strict; use warnings;
my $foo = [
{
bar => "baz",
},
];
push @{ $foo }, { new => "new" };
use Data::Dumper;
print Dumper $foo;
<强>输出强>
$VAR1 = [
{
'bar' => 'baz'
},
{
'new' => 'new'
}
];
答案 1 :(得分:1)
这是do BLOCK
的用途:
$foo = [
{
bar => "baz",
},
do {
+{
new => "new",
},
},
];
为了记录,解决方案之间的区别是:
do BLOCK
只占用一个块并将其转换为表达式。它是最快/最便宜的解决方案,副作用最少。eval BLOCK
捕获块抛出的任何异常并抛弃它们。除非您之后要检查例外情况,否则通常不安全使用。sub { CODE }->()
是真正的代码参考;因此,它更昂贵(一个完整的函数调用与一个块),当然还有更多的代码。&{sub { CODE }}()
与上一项相同;它更昂贵,更难阅读。通常,像这样的堆叠嵌套分隔符往往需要花费更多精力才能解码。&{sub { CODE }}
是一个函数调用,但与前两个不同,它不会设置新的参数。相反,@_
内的CODE
仍设置为来电者的参数。如果你没有命名它们,你可以在表达式中访问你的参数,但最好避免它,因为&foo
通常是一种非常危险的函数调用方式。关于最后一点的详细说明:&foo
看起来像是在没有参数的情况下调用foo
。它不是。相反,它会调用foo
,同时将@_
别名留给来电者的参数。这意味着如果foo
使用标准模式来解包其函数参数:
sub foo {
my $arg1 = shift;
my $arg2 = shift;
...
}
并且调用者通过@_
访问其参数:
sub bar {
print $_[0], "\n";
&foo;
print $_[0], "\n";
}
对foo
的调用会修改bar
的参数,因此此函数会打印bar
的第一个和第三个参数(假设{{ 1}}只有两个参数)。
所以永远不要使用foo
来调用函数;它总是值得明确:
&foo
或
foo();
如果您希望 foo(\@_);
修改您的参数。