【问题标题】:Getting error while using (/) division operator in perl cgi?在 perl cgi 中使用 (/) 除法运算符时出错?
【发布时间】:2012-03-12 23:56:40
【问题描述】:

我正在使用以下函数来计算天数。 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;
 }

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

/apollo/env/ShiftReport/server-root/gcShiftReport.cgi 第 616 行的语法错误,靠近 ")
    {"
/apollo/env/ShiftReport/server-root/gcShiftReport.cgi 第 618 行,“case 'OX-Gift-Hyderabad'”附近的语法错误
/apollo/env/ShiftReport/server-root/gcShiftReport.cgi 的执行由于编译错误而中止。

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

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

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

【问题讨论】:

  • 所以将/ 更改为* 并且什么都不改变 -- 会发生什么?还是觉得跟运营商有关?还有...空格,请:(
  • 我将 / 更改为 * 并且它正在工作 $age =(($diff - ($diff%$sec)) * $sec);
  • 这……很奇怪。好吧,你激发了我的 +1 兴趣。
  • 如果要进行日期数学运算,请使用 DateTime 等模块。您不会遇到今天(至少在美国所有日子)会造成的这种语法错误或数学错误。

标签: perl cgi


【解决方案1】:

如 cmets 中所述,您使用的是已弃用的 Switch 模块。您可能忘记添加use Switch,因此不会导入switch 关键字。如果你想要这个功能,你应该改用use feature qw(switch),它使用关键字givenwhendefault来代替。

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

这与它前面的代码无关,如果我添加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]}
    }
}

等价,不依赖switch:

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 变量,但我觉得它确实增加了可读性以保留它。

【讨论】:

  • 很抱歉给您带来了困惑。我正在使用use warningsuse strict。直到我没有引入新函数sub getAge 之前,整个代码都运行良好。正如我在上面的评论中提到的,所有其他运营商都工作正常,但 /.
  • @TLP:OP 正在使用已弃用的 Switch 模块,该模块已在 5.10.0 perl5100delta 中被替换
  • @JRF 或更准确地说,OP 不是使用Switch 模块。因此出现错误。
  • @KumarGaurav 运营商 / 几乎不可能导致您的错误。更有可能的是,您更改了其他内容。我的建议:不要使用 switch 或 given,而是使用我在答案中显示的 if 语句。如果问题仍然存在,请告诉我们。
  • @Borodin 好的。我想我应该说“似乎正在尝试使用”。我的观点是,如果 OP 使用已弃用的模块,语法将是有效的。
【解决方案2】:

在我看来你好像不见了

use Switch;

从您的程序开始。但这是 switch 声明的旧版本。如果您使用的是 Perl 5.10 或更高版本,您可以将其替换为

use feature 'switch';

描述了here。语法使用given/when/default 而不是switch/case/else,并且when 条件需要在它们周围加上括号,就像if 条件一样。你的代码应该变成

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

【讨论】:

    【解决方案3】:

    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;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-12-23
      • 2014-07-09
      • 2014-08-25
      • 2021-11-09
      • 1970-01-01
      • 2016-07-08
      • 2015-02-14
      • 2013-01-17
      相关资源
      最近更新 更多