如何在条件下初始化Perl中的词法变量?

Tim*_*mmy 3 perl scope

写下以下内容的正确方法是什么:

while ( my $first = $iterator->next && my $second = $iterator->next ) {
  # do work
}
Run Code Online (Sandbox Code Playgroud)

这不会运行 - 我想要$first并且$secondwhile循环内的适当范围内.

mob*_*mob 17

你想要在赋值表达式周围使用括号.

while ((my $first = $iterator->next) && (my $second = $iterator->next)) {
   # ...
}
Run Code Online (Sandbox Code Playgroud)

&&优先级高于=,因此您的原始代码看起来像是在尝试执行类似的任务 x && y = z.


Sin*_*nür 11

这是and&&以下更合适的地方:

#!/usr/bin/perl
use strict; use warnings;

my $it = make_iterator();

while ( my $first = $it->() and my $second = $it->() ) {
    print "$first\t$second\n";
}

sub make_iterator {
    my @x = qw(a b c);
    return sub {
        return shift(@x) if @x;
        return;
    };
}
Run Code Online (Sandbox Code Playgroud)

输出:

C:\Temp> it
a       b

我很想把分配带$second出来while(取决于迭代器的意义而不是返回偶数个元素):

while ( my $first = $it->() ) {
    defined(my $second = $it->())
        or warn "Iterator returned odd number of elements\n"
        and last;
    print "$first\t$second\n";
}
Run Code Online (Sandbox Code Playgroud)

输出:

C:\Temp> it
a       b
Iterator returned odd number of elements


bri*_*foy 8

我倾向于写这样的东西:

 while( my( $first, $second ) = map { ... } 1..2 ) {
      ...
      }
Run Code Online (Sandbox Code Playgroud)

您可能不喜欢这种语法,因为您不习惯这样做,但它遵循一些规则,我认为使代码更容易:

  • 我没有两次输入同样的东西
  • 我一次分配给所有变量
  • 当我需要多次运行时,我使用地图生成列表.
  • 我没有无偿地使用逻辑运算符.

但是,还有另一个问题.你必须弄清楚你在这个while条件下测试的是什么,然后让下一个程序员明白这一点.我不确定为什么你在那种情况下有两件事.如果只有一件东西(即未经处理的奇怪的人会发生什么),可以读取迭代器吗?

一个更好的解决方案是在不显示机制的情况下展示您尝试做的事情.我不知道你的迭代器的任何信息,我可能会建议你用另一个返回两个项的方法来装饰它(如果它在最后,可能是空列表):

 while( my( $first, $second ) = $iterator->read_two ) {
      ...;
      }
Run Code Online (Sandbox Code Playgroud)

如果这不能使情况清楚,请用一种方法来装饰它以询问特定问题:

 while( $iterator->two_things_left ) {
      my( $first, $second ) = $iterator->read_two;
      ...;
      }
Run Code Online (Sandbox Code Playgroud)