【问题标题】:Context and the Comma Operator上下文和逗号运算符
【发布时间】:2015-06-04 14:25:59
【问题描述】:

我的一位同事在语句后使用逗号而不是分号,结果与以下代码相似

my $SPECIAL_FIELD = 'd';
my %FIELD_MAP = (
   1 => 'a',
   2 => 'b',
   3 => 'c',
);

sub _translate_to_engine {
   my ($href) = @_;

   my %mapped_hash
      = map { $FIELD_MAP{$_} => $href->{$_} } keys %$href;

   $mapped_hash{$SPECIAL_FIELD} = FakeObject->new(
      params => $mapped_hash{$SPECIAL_FIELD} 
   ),  # << comma here

   return \%mapped_hash;
}

起初我很惊讶这通过perl -c,然后我想起了comma operator,并以为我明白发生了什么,但下面两个打印语句的结果让我再次怀疑。

my $scalar_return = _translate_to_engine( 
   { 1 => 'uno', 2 => 'dos', 3 => 'tres' } 
);
print Dumper $scalar_return;
# {'c' => 'tres','a' => 'uno','b' => 'dos','d' => bless( {}, 'FakeObject' )}

此调用是在标量上下文中进行的,我得到的结果是预期的结果。逗号运算符评估被丢弃的逗号的 LHS,然后评估 RHS。我不相信它可以在这里返回 RHS 的值,因为评估返回语句会离开子程序。

my @list_return = _translate_to_engine( 
   { 1 => 'uno', 2 => 'dos', 3 => 'tres' } 
);
print Dumper \@list_return;
# [{'c' => 'tres','a' => 'uno','b' => 'dos','d' => bless( {}, 'FakeObject' )}]

此调用是在列表上下文中进行的,但我得到的结果实际上与标量上下文中的调用相同。 我认为这里发生的事情:两个参数都被评估,因为 sub 在列表上下文中被调用,当 RHS 被评估时,return 语句被执行,因此 LHS 被有效地丢弃。

对任何一种情况下发生的特定语义的任何澄清都将不胜感激。

【问题讨论】:

    标签: perl


    【解决方案1】:

    你的解释是准确的。

    调用_translate_to_engine 的上下文影响是计算函数的所有最终表达式的上下文,包括所有return 的参数。在这种情况下,有两个表达式受到影响:您提到的逗号和\%mapped_hash

    在第一个测试中,返回的值为\%mapped_hash,在标量上下文中求值。在第二个中,返回值是在列表上下文中评估的\%mapped_hash\%mapped_hash 评估为对哈希的引用,无论上下文如何。因此,无论上下文如何,sub 的结果都是相同的。

    【讨论】:

    • 我相信我在倒数第二句中所说的内容类似于您的粗体文本。感谢您关于上下文思想的观点,我认为它适用于子中的所有内容。
    • 已调整。你暗示你没有得到预期的结果,但你没有具体说明你的期望,所以我不确定需要解释什么。
    • sub 中的许多内容不受 sub 调用上下文的影响。例如,%mapped_hash 的赋值是在 void 上下文中计算的,$_ 都是在标量上下文中计算的。
    【解决方案2】:

    表达式的左轴是$mapped_hash{$SPECIAL_FIELD} = FakeObject-&gt;new(...),右轴是return \%mapped_hash。正如您所说,逗号运算符评估左侧(将 FakeObject 实例分配给哈希键 d),然后评估右侧,导致 sub 返回 hashref。对我来说很有意义。

    在列表或标量上下文中调用 sub 无关紧要。它不会改变逗号运算符的上下文,这在两种情况下都是相同的。

    【讨论】:

      猜你喜欢
      • 2010-10-04
      • 2017-07-11
      • 2010-12-16
      • 1970-01-01
      • 2011-03-08
      • 1970-01-01
      • 1970-01-01
      • 2011-07-21
      • 2018-03-22
      相关资源
      最近更新 更多