在perl cgi中使用(/)除法运算符时出错?

时间:2012-03-11 18:50:34

标签: perl cgi

我正在使用以下功能来计算天数。 setAge函数的参数是epoc时间。

 sub getAge {
    my $diff;
    my $age=0;
    my $sec=86400;
    my $createTime;
    my $currTime;
    $createTime = $_[0];
    $currTime = UnixDate("now", "%s");
    $diff = ($currTime - $createTime);
    $age =(($diff-($diff%$sec))/$sec);
    return $age;
 }

但是每当我使用除法运算符时,我都会收到以下错误

syntax error at /apollo/env/ShiftReport/server-root/gcShiftReport.cgi line 616, near ")
    {"
syntax error at /apollo/env/ShiftReport/server-root/gcShiftReport.cgi line 618, near "case 'OX-Gift-Hyderabad'"
Execution of /apollo/env/ShiftReport/server-root/gcShiftReport.cgi aborted due to compilation errors.

错误行来自紧随其后的函数定义。

sub getName {
    my $tempName = $_[0];
    switch ($tempName)
    {
            case 'Cart Software' { return 'CART' }
            case 'OX-Gift-Hyderabad' { return 'Gift' }
            else { return $_[0]}
    }
}

有人可以指出为什么会发生这种情况并且仅在我使用除法(/)运算符时。

3 个答案:

答案 0 :(得分:3)

如评论中所述,您使用的是已弃用的Switch模块。您可能忘记添加use Switch,因此未导入switch关键字。如果您需要此功能,则应改为使用use feature qw(switch),而是使用关键字givenwhendefault

您的错误消息 - 相当含糊 - 来自perl而不是将switch ($variable) { ... }作为有效语句处理。编译器认为它看到了一个函数,因为裸字switch后跟parens,但是下面的块{ ... }会导致错误。

这与之前的代码无关,如果我添加use Switch,代码就适用于我。

如果对此代码使用此特定功能是一个不错的选择,那么这是值得商榷的。

use feature qw(switch);

sub getName {
    my $tempName = $_[0];
    given ($tempName)
    {
            when ('Cart Software') { return 'CART' }
            when ('OX-Gift-Hyderabad') { return 'Gift' }
            default { return $_[0]}
    }
}

等效,不依赖于开关:

sub getName {
    my $name = shift;
    return "CART" if $name eq "Cart Software";
    return "Gift" if $name eq "OX-Gift-Hyderabad";
    return $name;
}

我认为这是更可取的,因为更清楚哪种类型的比较。

ETA:您的子程序getAge可以更有效地编写。我冒昧地删除你的随机资本,因为它们是邪恶的,而perl确实区分了aFunctionForGettingStuffaFunctionForgettingStuff

我看到你正在使用某种自制方法截断浮子。这不是必需的,因为perl确实有一个内置函数:int()

sub getage {
    my $createtime = shift; # shift first argument off @_
    my $sec = 86400;
    # use int() instead of removing remainder
    my $age = int((UnixDate("now", "%s") - $createtime) / $sec);
    return $age;
}

没有必要将语句堆叠成一个,但我认为删除尽可能多的转换变量是个好主意。但是,我认为有必要 - 从可读性的角度和良好的实践 - 在实际使用变量之前不要声明变量。这样,当您阅读代码并看到my $foo = ...知道时,$foo被声明并分配到那里。

你甚至可以删除$age变量,但我觉得它确实增加了可读性以留下它。

答案 1 :(得分:2)

在我看来,你错过了

use Switch;
从程序开始

。但这是switch语句的旧版本。如果您使用的是Perl版本5.10或更高版本,则可以将其替换为

use feature 'switch';

描述了here。语法使用given / when / default代替switch / case / elsewhen条件需要括号在他们周围,就像一个if条件。你的代码应该成为

sub getName {
  my $tempName = $_[0];
  given ($tempName) {
    when  ('Cart Software') { return 'CART' }
    when ('OX-Gift-Hyderabad') { return 'Gift' }
    default { return $_[0]}
  }
}

答案 2 :(得分:0)

Switch模块作为源过滤器实现,它会读取您的源代码并尝试将switch语句转换为有效的Perl代码。我的猜测是,你以某种方式设法说服Switch /开始正则表达式匹配,将switch隐藏在它认为的模式文本中。在这种情况下,您的switch很容易重写为哈希查找,可能更安全,更快。

my %name_map = (
    'Cart Software' => 'CART',
    'OX-Gift-Hyderabad' => 'Gift',
);
sub getName {
    my $temp_name = $_[0];
    if (exists $name_map{$temp_name}) {
        return $name_map{$temp_name};
    }
    return $temp_name;
}