perl - 为什么 Perl 在循环期间运行不在循环中的代码?
问题描述
我是第一次在 Perl 中开发,我正在添加一个非常大的现有工具。所以,我提前为任何事情道歉。
下面的代码是一个 Perl 测试脚本:
SC "SA Text Here";
SC "SB Text Here"; # SA not important
SC "SB Text Here";
SC "SA Text Here";
SC "SB Text Here";
SC "SB Text Here";
编码:
my $skipA = -1;
my $skipB = -1;
my $skipC = -1;
my $currentA = 0;
my $currentB = 0;
my $currentC = 0;
# Other subs set $skipA, $skipB, $skipC, but how they are set is not important. If set to anything other than -1, they should be a positive integer.
sub SC($)
{
# Do some stuff and set $verb
if( $verb eq "SA" )
{
# Starting
$currentA++;
$currentB = 0;
$currentC = 0;
# Check mode
if( $sxMode eq "X" )
{
if( ( $skipA> -1 && $currentA > $skipA ) || $skipB > -1 )
{
logstatus 0, "DONE";
$skipA= -1;
$skipB = -1;
$skipC = -1;
}
}
$skipA = -1;
$skipB = -1;
}
if( $verb eq "SB" )
{
# Starting
$currentB++;
$currentC = 0;
# Check mode
if( $sxMode eq "X" )
{
if( $skipB> -1 && $currentB > $skipB )
{
logstatus 0, "DONE";
$skipA= -1;
$skipB = -1;
$skipC = -1;
}
}
$skipC = -1;
}
}
# Should execute the first loop, finish, then start the second loop
sub doOtherStuff()
{
#Do other stuff here
# This loop should take me to the $i-th SA in the test script
for( my $i = 1; $i <= 10; $i++ )
{
$skipA = $currentA;
print "THIS IS I $i\n";
doSomething(); # Not important
}
# This loop should take me to the $j-th SB of the $i-th SA in the test script
for( my $j = 1; $j <= 10; $j++ )
{
$skipB = $currentB;
print "THIS IS J $j\n";
doSomething(); # Not important
}
示例:如果我从 1.1 开始(currentA = 1,currentB = 1)并且我想跳到 2.3,我将到达 1.3。预期输出与实际输出:
Actual Output Expected Output
THIS IS I 1 THIS IS I 1
THIS IS J 1 THIS IS I 2
THIS IS J 2 THIS IS J 1
THIS IS J 3 THIS IS J 2
THIS IS J 3
当 Perl 测试脚本运行时,它将看到 SC 并执行该子程序。借助 GUI 上一些精美的按钮,我可以设置 $skipA 和 $skipB,这将触发doOtherStuff()。
如果我注释掉doOtherStuff()中的第二个循环,那么一切正常(第一个循环)。但是,如果我添加第二个循环,第一个将不会完成,第二个将接管。我玩过它,我注意到设置 $skipB 导致了这个问题。
即使我在第一个循环之后设置它,它仍然以某种方式影响它(这是我第一次也是唯一一次设置 $skipB )。所以,我认为第一个循环应该一直运行到完成,然后继续进行第二个循环。
这可能是 Perl 问题还是工具问题?我会错过什么吗?
谢谢!
解决方案
发生这种情况的一种方法是,如果您的循环正在写入缓冲STDOUT
但您的循环结束消息转到 unbuffered STDERR
。
(*STDOUT)->autoflush(0); # use buffered STDOUT
for $i (1 .. 10) {
if ($i == 1) {
print STDERR "$i ";
} else {
print STDOUT "$i ";
}
}
print STDERR "Done with the loop. ";
输出:
1 Done with the loop. 2 3 4 5 6 7 8 9 10
输出缓冲是 Perl(以及在许多其他地方)为了提高效率而使用的一种方案。在将输出添加到缓冲区和缓冲区数据实际写入输出设备之间可能存在延迟。
有关perldoc -v '$|'
Perl 如何使用输出缓冲的信息,请参阅参考资料,有关更多信息,请参阅经典的遭受缓冲的文章。
推荐阅读
- types - 是否可以在运行时获取 F# 函数的类型签名?
- ruby-on-rails - 检查图像是否为“.attached”?将相同图像附加到多个模型时失败
- node.js - 如何使用 Mongoose 自动保存到 MongoDB 而不会出现延迟或冻结?
- java - 在 iFrame 中定位元素时面临问题
- laravel - 使用 GitHub 更新 laravel
- python - 使用tweepy的Python中的Urllib3连接错误
- api - 切片,groupBy []数组
- javascript - 如何判断 npm 上的包是否适用于 angular?
- sql-server - 尝试将大型 html 文本格式存储到产品的 nvarchar(MAX) 字段时超出限制
- regex - 匹配以不同字母开头和结尾的单词