【发布时间】:2014-05-29 15:55:47
【问题描述】:
我有一个关于如何评估-> 运算符的左侧和右侧的问题。考虑以下代码:
#! /usr/bin/perl
use strict;
use warnings;
use feature ':5.10';
$, = ': ';
$" = ', ';
my $sub = sub { "@_" };
sub u { shift->(@_) }
sub v { my $s = shift; $s->(@_) }
say 'u', u($sub, 'foo', 'bar');
say 'v', v($sub, 'foo', 'bar');
输出:
u: CODE(0x324718), foo, bar
v: foo, bar
我希望 u 和 v 行为相同,但事实并非如此。我总是假设 perl 在这些情况下从左到右评估事情。像shift->another_method(@_) 甚至shift->another_method(shift, 'stuff', @_) 这样的代码很常见。
如果第一个参数恰好是代码引用,为什么会中断?我在这里是在未定义/未记录的领域吗?
【问题讨论】:
-
这只是部分答案:虽然只有一个
->运算符记录在案,但->()、->[]、->{}和->method实际上是作为完全不同的运算符实现的。跨度> -
@RobEarl,我的回答是在方法调用之前评估参数(这很简单),而不是在 LHS 之前。即使
->()的工作方式与方法调用相同,这在这里也无济于事。 -
@RobEarl,有趣的是,
->method(@args)的 LHS 在 args 之前被评估,所以shift->foo(@_)确实按预期工作! (可能是因为定期做这件事很诱人,所以值得额外使用前端堆栈。)
标签: perl