为什么我的Perl子例程不能在调用它的foreach循环中看到变量的值?

前端之家收集整理的这篇文章主要介绍了为什么我的Perl子例程不能在调用它的foreach循环中看到变量的值?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我希望这是直截了当的,我做错了.我在网上看到一些关于“变异自杀”看起来不错的东西,但它是旧版本而且我在5.10.1.

无论如何 – 我声明的变量 – $RootDirectory – 只是突然失去了价值,我无法弄清楚原因.

这是一个重现问题的脚本.当我在调试模式(perl -d)中运行脚本时,我可以在第21行和第26行打印出$RootDirectory.但它已经过了第30行.

use strict;
my $RootDirectory; 
my @RootDirectories; 

@RootDirectories = (
   'c:\\P4\\EDW\\PRODEDW\\EDWDM\\main\\db\\','c:\\P4\\EDW\\PRODEDW\\EDWADS\\main\\db\\','c:\\P4\\EDW\\PRODEDW\\FJE\\main\\db\\'
   );

foreach $RootDirectory (@RootDirectories) { 
   # $RootDirectory = 'c:\\P4\\EDW\\PRODEDW\\EDWDM\\main\\db\\';
   # print ' In foreach ' . $RootDirectory. "\n";
   RunSchema ();
} 

exit(0);

sub RunSchema() { 
   # print ' In RunSchema ' . $RootDirectory. "\n";
   CreateTables ();
} 

sub CreateTables() { 
   # print ' In CreateTables ' . $RootDirectory. "\n";
   sqlExecFolder ('tbl');
} 

sub sqlExecFolder() { 
   print ' In sqlExecFolder ' . $RootDirectory. "\n";       # Variable $RootDirectory value is gone by now
}

编辑
感谢所有的评论!我想现在我将使用“我们的”关键字,这似乎运作良好 – 感谢内森.还要感谢有关使用警告的工具 – 我想我已经卖掉了那个!

继续让我困惑的是为什么,当我进行调试模式(perl -d)并逐步执行代码时,执行“p $RootDirectory”我得到了第21行和第26行的预期输出,但没有第30行.第30行的情况有何不同?

另外,我感谢关于将$RootDirectory作为函数参数传递的最佳实践的评论.我想避免这种情况,因为我之后有很多函数 – 例如RunSchema调用调用sqlExecFolder的CreateTables.所有这些都必须传递相同的参数.在这种情况下它仍然有意义,还是有更好的方法来构建它?

解决方法

您将$RootDirectory声明为foreach循环中的循环变量.据我所知,这意味着它的值已本地化为循环,并且其值将在循环结束时恢复为其先前的值.

在你的情况下,变量从未被赋值,因此在循环结束时它返回到之前的undef值.

编辑:实际上,问题是$RootDirectory是用my声明的,所以它在其他范围内是未定义的.在函数RunSchema,CreateTables和sqlExecFolder中,变量是未定义的,无论foreach的本地化如何.

如果您希望变量声明为严格,但希望它是全局变量,请使用我们的声明$RootDirectory:

our $RootDirectory;

编辑:话虽如此,使用全局变量并不总是一个好主意.最好将变量作为参数传递给其他人建议的函数.

猜你在找的Perl相关文章