我似乎无法在懒惰的评估中使用IF

时间:2014-05-06 16:14:42

标签: perl

我编写了一个非常简单的脚本来删除目录中的符号链接,然后创建新的链接到另一个目录中的文件(在10天内修改的文件)。

脚本工作得很好,但我想我会开始显示一些输出,更具体地说,只有在给出$ debug(或$ quiet)参数时。这给了我一些悲伤,我不明白为什么我在努力应对这个看似简单的任务。

我认为这是因为'if($ debug)'在find子的短路内使用。没有任何条件逻辑,它工作正常(如第二个查找函数中所示)。

任何想法都将非常感谢,谢谢。

ERROR:

syntax error at symlinksUpdater.pl line 25, 
near "if" syntax error at symlinksUpdater.pl line 26, near "}"
Execution of symlinksUpdater.pl aborted due to compilation errors.

CODE:

#!/usr/bin/perl
use Getopt::Long; 
use File::Find;
use Cwd;

my $symDir = getcwd();
my $archiveDir;
my $clearDynamic = 1;
my $debug= '';
my $dryRun ='';
GetOptions ("dynamicDir|s=s" => \$symDir,
            "archiveDir|a=s" => \$archiveDir,
            "clear|c!" => \$clearDynamic,
            "debug|d!" => \$debug,
            "dryRun!" => \$dryRun
        );

print "DEBUG MODE\n" if $debug;

if ($clearDynamic) {
    find(sub {
            -l &&
            unlink &&
            if($debug) {print "DELETE: $_";}    #LINE 25
        }, "$symDir"); }

find(sub {
        -f &&
        int(-M _) < 10 &&
        symlink($File::Find::name, $symDir."/".$_) &&
        print "$symDir/$_ -> $File::Find::name";
        #(printf("\n%s/%s  ->  %s", $symDir, $_, $File::Find::name) if (defined $debug);
    }, "$archiveDir");

2 个答案:

答案 0 :(得分:4)

&&的操作数必须是表达式,而不是语句。无论如何,你需要的只是

find(sub {
   -l && unlink && $debug && print("DELETE: $_");
}, $symDir);

但我发现以下内容更具可读性:

find(sub {
   if (-l) {
      if (unlink) {
         print("DELETE: $_") if $debug;
      }
   }
}, $symDir);

它还允许轻松处理错误(else { warn ... })。

答案 1 :(得分:2)

尝试将if语句包装在do块中,如下所示:

if ($clearDynamic) {
  find(
    sub {
      -l &&
      unlink &&
      do { if($debug) {print "DELETE: $_";} }    #LINE 25
    }, "$symDir"
  );
}

带有大括号的块的前缀不能像其他构造那样独立作为语句。您也可以使用后缀,如下所示:

... unlink && (print "DELETE: $_" if $debug)

括号中明确说明只有在$debug为真时才会发生打印,而​​不是整个&&条件都取决于$debug

perldoc perlsyn解释“复合陈述”(例如:if {...})和“陈述修饰词”(例如:... if EXPR)。我没有在该文档中找到任何明确表示复合语句不能用作表达式的内容,我只是从经验中知道它不能。