Perl:Subroutine uneven/unusual behavior

ruyhziif  于 2023-10-24  发布在  Perl
关注(0)|答案(1)|浏览(121)

这是关于Perl中函数的行为。
代码段:

&mmg();
my $count;
sub mmg {
    &kkg();
    print "symlink at location updated with the value\n";
    $count++;
    print "$count is value of count \n";
} 


sub kkg {
    if (-d "/home/PPP/ee/dir1") {
        print "I got dir1\n";
        my @arr = glob ("/home/PPP/YEP");
        #..
        #..... Some more commands
        #..
        return;
    }
    else {
        sleep 5;
        &mmg();
    }
}

输出量:

symlink at builds location updated with the value of link at builds location
1 is value of count 
symlink at builds location updated with the value of link at builds location
2 is value of count 
symlink at builds location updated with the value of link at builds location
3 is value of count 
symlink at builds location updated with the value of link at builds location
4 is value of count 
symlink at builds location updated with the value of link at builds location
5 is value of count 
symlink at builds location updated with the value of link at builds location
6 is value of count

在这里,“dir 1”不在那里,我在30-35秒后创建了。现在,根据我的理解,在30-35秒后(当dir 1创建时),只有“symlink at buildings location updated with value of link at buildings location \n 1 is value of count”应该会出现,即只有一次这些语句会打印出来。但是,为什么这些会被打印多次?
我如何理解输出行为的概念?我如何让这个print语句只打印一次?
我理解的概念:mmg()将调用kkg(),它将检查dir 1是否存在。如果不存在,sleep 5然后再次调用mmg()。mmg()将再次调用kkg(),依此类推,直到dir 1存在。如果dir 1可用,kkg()将返回,mmg()将进一步执行并打印其中的内容。

5t7ly7z5

5t7ly7z51#

这是你的代码的执行:

&mmg();
    &kkg();
        if ... 
        else mmg();
                 &kkg();
                     if ...
                     else mmg();
                              &kkg();
                                  if found! return to mmg()
                              print 1, sub finishes
                 print 2, sub finishes
    print 3, sub finishes

因为每次检查dir 1是否存在时,都要启动一个新的mmg()进程,每个进程都会在完成之前打印一次,因为它们是嵌套的。
你应该做的是使用kkg()作为布尔值,让mmg()处理循环控制,例如:

sub mmg {
    while (!kkg()) {
        sleep 5;      # do nothing
    }
    print "....";
    # done
}

sub kkg {
    if (-d "/home/PPP/ee/dir1") {
         # do stuff
         return 1;   # true
    }
    return 0;        # false
}

你甚至可能不需要kkg()。
另外,你应该注意到你使用的sub调用方法--&NAME()--不是惯用的方法。在perldoc perlsub中,你可以读到关于调用子例程的不同方式的文章:

NAME(LIST);    # & is optional with parentheses.
NAME LIST;     # Parentheses optional if predeclared/imported.
&NAME(LIST);   # Circumvent prototypes.
&NAME;         # Makes current @_ visible to called subroutine.

你应该使用NAME()

相关问题