【问题标题】:Variable value not passing through loop变量值不通过循环
【发布时间】:2014-02-24 14:25:58
【问题描述】:

我有一个循环,通过检查文件数是否恒定来检查目录中的所有文件是否都上传到目录。

开始,它知道目录中有 $before 文件(“之前”它再次查找)。

use strict;
use warnings;
my $after = 0;
my $before ="10";

until($before == $after) {
    #check again, which changes the value of $after.
    #Now....
    $after = "20"; 

    if ( $after == $before ) {
        print "After is before. Moving out of until because all files are there!\n";
    }
    else {
        print "After isn't before.\n";
        my $before = $after;#set $before to be the new value after the update
        my $after = 0; #this will be updated in the next update
        sleep 1;
    }
}

当我运行它时,它声称它在 else{} 中将 $before 设置为 $after,但实际上,$before 仍然是 10,就像它之前设置的那样,并且程序无限循环。

当我从else{} 内部删除mys 时,脚本运行正常:

use strict;
use warnings;
my $after = 0;
my $before ="10";

until( $before == $after ) {
    #check again, which changes the value of $after.
    #Now....
    $after = "20"; 

    if($after == $before) {
        print "After is before. Moving out of until because all files are there!\n";
    }
    else {
        print "After isn't before.\n";
        $before = $after;#set $before to be the new value after the update
        $after = 0; #this will be updated in the next update
        sleep 1;
    }
}

这是否意味着在 else 中定义为“my $before”的$before 与上面定义的“$before”不是同一个变量?

【问题讨论】:

  • 使用$a 和`$b 作为变量名是个糟糕的主意
  • use strictuse warnings
  • 代码中的&update_a 是什么?
  • 你显示的代码没有明显的问题,所以我猜问题出在你没有显示的代码上。如果您无法想出一个展示问题的可运行示例,我们可能无法提供帮助。

标签: perl variables loops conditional


【解决方案1】:

当您编写代码时,始终正确缩进。很难看到代码是如何执行的,而且当代码缩进不好时,它也可以隐藏错误。此外,始终使用空格并且不要将语句加倍。 90% 的编程都是维护工作,因此您只需进行少量额外输入以使代码易于理解即可节省大量维护时间。

我重新发明了你的代码,所以我可以阅读它。


当您使用my 声明变量时,您将其声明为词法范围。这意味着它是在有限的上下文中定义的。这通常是一件好事。这意味着当您不再需要变量时,它们就会消失。但是,这也意味着变量会在您需要时消失。

my 变量位于定义它们的中。如果在 while/until 循环中定义,它们将存在于该 while 循环中。一旦你退出while,他们就会再见。与if 语句或for 循环相同。事实上,如果你只是放大括号,my 变量,如果在这些大括号中定义,一旦在外面就会失去它的定义:

{
    my $foo = "bar";
}
print "$foo\n";   # Whoops, $foo is undefined!

如果您需要一个变量存在于循环之外,则需要在该循环之外定义它:

my $odd_count = 0;
for my $number ( @number_list ) {
    if ( $number % 2 ) { 
        $odd_count++;
    }
}
print "There are $odd_count numbers in my list\n";

如果你用my重新声明一个变量,你也可以重新定义一个变量:

use warnings;
use strict;
use feature qw(say);

my $foo = "bar";
{    # New block!
     say "Initial value of \$foo: $foo";
     my $foo = "foo";   # Using "my" on $foo
     say "Changed value of \$foo: $foo";
}
say "Final value of \$foo: $foo";

如果你运行这个,你会得到:

Initial value of $foo: bar
Changed value of $foo: foo
Final value of $foo: bar

这是因为您在块内重新声明了$foo,所以您现在有了一个新变量$foo,它将覆盖$foo 的旧值,直到块结束。块结束后,the old$foo` 变量将返回,并保留其旧值:

my $foo = "bar";
{    # New block!
     say "Initial value of \$foo: $foo";
     $foo = "foo";   # No "my" on $foo
     say "Changed value of \$foo: $foo";
}
say "Final value of \$foo: $foo";

如果你运行这个,你会得到:

Initial value of $foo: bar
Changed value of $foo: foo
Final value of $foo: foo

在这种情况下,我删除了my。现在当我说$foo = "foo"; 时,我使用的是我在块外定义的相同$foo,所以一旦我离开块,$foo 仍将具有其旧值。

【讨论】:

  • 非常感谢您提供如此清晰而全面的解释(以及有关格式的建议)!我在多个脚本中都遇到了这些问题,我无法告诉你你刚刚为我解决了多少麻烦。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-07
  • 2016-07-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多