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

时间:2009-11-10 21:55:02

标签: perl scope

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

while ( my $first = $iterator->next && my $second = $iterator->next ) {
  # do work
}

这不会运行 - 我希望$first$secondwhile循环内的适当范围内。

4 个答案:

答案 0 :(得分:17)

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

while ((my $first = $iterator->next) && (my $second = $iterator->next)) {
   # ...
}

&&的优先级高于=,因此您的原始代码似乎正在尝试执行x && y = z之类的作业。

答案 1 :(得分: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;
    };
}

输出:

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";
}

输出:

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

答案 2 :(得分:8)

我倾向于写这样的东西:

 while( my( $first, $second ) = map { ... } 1..2 ) {
      ...
      }

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

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

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

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

 while( my( $first, $second ) = $iterator->read_two ) {
      ...;
      }

如果情况不明确,请用一种方法来装饰它以询问特定问题:

 while( $iterator->two_things_left ) {
      my( $first, $second ) = $iterator->read_two;
      ...;
      }

答案 3 :(得分:1)

尝试:

my $first;
my $second;
while (($first = $iterator->next) && ($second = $iterator->next)) {
  # do work
}