Perl语法详细信息-列出有或没有参数的上下文?
这项工作:Perl语法详细信息-列出有或没有参数的上下文?,perl,Perl,这项工作: my $r = someSubroutine( map { ( 0 => $_ ) } @hosts) 这不起作用,导致语法错误: my $r = someSubroutine( map { 0 => $_ } @hosts) 我想我理解的是,映射后的{}相当于一个闭包或匿名子例程 但是如果我在一个普通子例程的末尾放一个“值,value”,它将返回这些值的列表。如果我对映射使用这种简洁性,这是一个语法错误。这在映射的perldoc中描述: 简而言之,您应该使用pare
my $r = someSubroutine( map { ( 0 => $_ ) } @hosts)
这不起作用,导致语法错误:
my $r = someSubroutine( map { 0 => $_ } @hosts)
我想我理解的是,映射后的{}
相当于一个闭包或匿名子例程
但是如果我在一个普通子例程的末尾放一个“
值,value
”,它将返回这些值的列表。如果我对映射使用这种简洁性,这是一个语法错误。这在映射的perldoc中描述:
简而言之,您应该使用parens或+
-symbol这样的小助手,以便perl能够正确解析{…}
构造:
my $r = someSubroutine( map { + 0 => $_ } @hosts)
首先,这是一个非常奇怪的说法。map
生成的列表如下所示
0, $hosts[0], 0, $hosts[1], 0, $hosts[2], ...
因此,分配给散列是没有用的,因为它与
my %hash = (0 => $hosts[-1])
map
将接受块(您正在使用的)或简单表达式作为其第一个参数。这里的问题是,{0=>$\}
看起来非常像一个带有单个元素的匿名散列,这是一个表达式,这就是解析器猜测的结果。表达式后面第二个参数之前需要逗号,但是当perl在map{0=>$\u}@hosts
中到达右大括号时,它找不到逗号,因此它必须抛出语法错误,因为它太远了,无法回溯到左大括号,而采用一个块
是这样说的
{
同时启动散列引用和块,因此map{…
可以是map BLOCK LIST或map EXPR,LIST的开始。因为Perl不提前查找结束的}
它必须根据在之后找到的内容猜测它正在处理的是哪一个{
。通常它是正确的,但如果它不正确,它就不会意识到有什么问题,直到它到达}
并遇到缺少的(或意外的)逗号。语法错误将在}
附近报告,但您需要更改附近的内容{
例如使用一元+
或分号给Perl一些帮助
解决方法是根据您的发现消除歧义。这些方法中的任何一种都会起作用
map +( 0 => $_ ), @hosts
map(( 0 => $_ ), @hosts)
map { +0 => $_ } @hosts
map { ( 0 => $_ ) } @hosts
map { ; 0 => $_ } @hosts
map
有两种语法:
map BLOCK LIST e.g. map { f() } g()
map EXPR, LIST e.g. map f(), g()
当Perl遇到map
时,它需要确定使用了哪种语法。假设map
之后的第一个标记是{
。这是块的开始,对吗?等等!表达式也可以以{
开始
my $hash_ref = { key => 'val' };
语法是不明确的。Perl必须“猜测”您正在使用的语法。Perl会提前查看下一个标记以帮助猜测,但有时它会错误地猜测。这就是其中之一
以下是这方面的标准解决方法:
map {; ... } LIST # Force Perl to recognize the curly as the start of a BLOCK
map +{ ... }, LIST # Force Perl to recognize the curly as the start of a hash constructor
;
不能是哈希构造函数的一部分,因此{
只能启动一个块
+
必须启动一个EXPR(而不是一个块)。在这种情况下,它是一个只会提供帮助的操作符
比如说,
map {; +{ $row->{id} => $row->{val} } } @rows
Borodin:toolic是正确的:my map是子例程的输入,而不是标量。如果它在标量上下文中,这将是正确的,但不是。它实际上是这样的:`184 my$r=$self->sql_语句(185'插入到项目_站点(项目_id,主机名)值'186.join(',','map{'(?,?)}@{$self->{hosts}}),187 map{(0=>$}}{$self->{hosts}}188)`@Skylos:啊,我完全忽略了someSubroutine()
。我把toolic的注释读作操作代码…而不是操作代码。我以为他一直在看来自或其他什么的输出。谢谢