perl中的case语句:无法输入正确的大小写

时间:2014-06-07 16:49:05

标签: perl scripting switch-statement

#!/usr/bin/perl -w
use warnings;
use diagnostics;
use Switch;

open FH, "<$ARGV[0]" or die "$!";

sub commandType{
  print "comm entered for $_";
  switch($_){
    case("add") {print "this is add\n"}
    case("sub") {print "this is sub\n"}
    case("neg") {print "this is neg\n"}
    case("eq") {print "this is eq\n"}
    case("gt") {print "this is gt\n"}
    case("lt") {print "this is lt\n"}
    case("and") {print "this is and\n"}
    case("or") {print "this is or\n"}
    case("not") {print "this is not\n"}
  }
}

while(<FH>){
  next if /^\s*\/\//;
  next if /^\s*$/;
  my $line = "$_";
  $line =~ s/\s+$//;
  print "$line\n";
  commandType($line);
}

这是我的代码,它通过命令行从以下文件中获取输入:

// Pushes and adds two constants.
push constant 7
push constant 8
add

对于上面文件的每一行,perl代码将运行子例程commandType以检查它是否在子例程内的给定情况中,如果是则打印。但即使上面的文件中存在add命令,代码仍然不会打印它。我得到以下输出:

push constant 7
comm entered for push constant 7
push constant 8
comm entered for push constant 8
add
comm entered for add`

为什么案例“添加”不打印任何东西?

3 个答案:

答案 0 :(得分:3)

说明

问题是$_不会自动引用传递给sub的第一个参数,目前您正在阅读与中的$_相同的$_ -loop

commandType 内部"add\n"的值是读取的行,仍然附加了潜在的换行符,并且"add"不等于{ {1}},您的案例未输入。


最好将sub commandType的内容更改为以下内容:

sub commandType{
  my $cmd = shift; # retrieve first argument
  print "comm entered for $cmd";
  switch($cmd) {
    ...
  }
}

答案 1 :(得分:2)

使用$_和普通变量一样安全。它具有全局范围,并且许多内置的Perl操作符对其起作用,因此很可能在没有任何明显原因的情况下进行修改。

在任何情况下,传递给子例程的参数都显示在@_中,而不是$_中,并且在这种情况下它似乎包含正确的值的随机机会。

重写这样的commandType子程序,它应该开始表现得更明智

sub commandType {
  my ($cmd) = @_;
  print "comm entered for $cmd";

  switch ($cmd) {
    case 'add' { print "this is add\n" }
    case 'sub' { print "this is sub\n" }
    case 'neg' { print "this is neg\n" }
    case 'eq'  { print "this is eq\n"  } 
    case 'gt'  { print "this is gt\n"  } 
    case 'lt'  { print "this is lt\n"  }
    case 'and' { print "this is and\n" }
    case 'or'  { print "this is or\n"  }
    case 'not' { print "this is not\n" }
  }
}

您还必须始终每个程序的顶部添加use strict,尤其是在您要求帮助的情况下。它会快速报告您可能会花费宝贵时间追踪的琐碎错误。

Switch模块也不安全,自版本10以来一直可用的内置语言构造given / when因为一些奥术而被标记为实验缺点。最好使用"Basic BLOCKs" section of perlsyn中描述的if语句列表。

答案 2 :(得分:1)

从Perl 5.10.1开始(嗯,5.10.0,但它没有正常工作),您可以说use feature "switch";启用实验性切换功能。在&#34;开关&#34;功能,Perl获得实验性关键字givenwhendefaultcontinuebreak

    #!/usr/bin/perl
    use strict;
    use warnings;
    use feature "switch";
    while(my $line=<DATA>){
        given ($line) {
        when (/push/) { print 'found push' }
        when (/add/) { print 'found add' }
        }
    }
    __DATA__
    push constant 7
    push constant 8
    add

Demo

另见:Perl 5.20 and the fate of smart matching and given-when?