为什么是“undef”? 这个 Perl 片段没有检测到?

发布于 2024-07-19 04:36:43 字数 1161 浏览 8 评论 0原文

由于 undef 值,我希望输入第二个“if”语句中的块,但日志显示它没有被输入。

sub getcmd{
  my $self = $_[0];
  if ( $self->_recv == OK ){
      push @{$self->{'log'}}, ['NOTICE', "OK"];
      return "My command";          
  }
  push @{$self->{'log'}}, ['ERROR', "Did not get OK back"];
  return undef;
}

...

if (!($ret = $self->getcmd)){
  push @{$self->{'log'}}, ['ERROR', "failed to read after asking for NEXT"];
}
else {
  push @{$self->{'log'}}, ['ERROR', "'undef' not detected in next()"];
}

日志文件显示:

[Fri May  8 19:25:56 2009]: ERROR: Did not get OK back
[Fri May  8 19:26:02 2009]: ERROR: 'undef' not detected in next()

任何想法都感激地接受。

编辑:抱歉,我编辑了代码以显示基本流程。 我应该更好地校对一下。

  • 我在 getcmd() 中添加了 $ret 来模拟日志记录函数中发生的情况,该函数仅打印出 $ret 的当前值,$ret 是一个始终用于捕获返回值的全局变量。
  • 我删减了日志消息并错过了额外的“返回”

感谢您的建议和评论。 我没有注意到日志时间戳中的六秒差异,所以现在我怀疑您关于执行顺序与我最初预期的不同的说法是正确的。

我回去再看看。 猜猜这就是您在一天 13 个小时试图完成“必须在星期一上线”的项目之后尝试查看别人的“平均”Perl 时得到的结果!

我没有写代码,只是继承了它。 该代码是由几个认为自己“不需要任何警告或严格要求”的人编写的。

想象一下 800 行 Perl 和大量的“if”但没有 else 语句! 根本没有防御性编码! 8-O

I would expect the block in the second 'if' statement to be entered because of the undef value but the logs show that it isn't being entered.

sub getcmd{
  my $self = $_[0];
  if ( $self->_recv == OK ){
      push @{$self->{'log'}}, ['NOTICE', "OK"];
      return "My command";          
  }
  push @{$self->{'log'}}, ['ERROR', "Did not get OK back"];
  return undef;
}

...

if (!($ret = $self->getcmd)){
  push @{$self->{'log'}}, ['ERROR', "failed to read after asking for NEXT"];
}
else {
  push @{$self->{'log'}}, ['ERROR', "'undef' not detected in next()"];
}

The log file shows:

[Fri May  8 19:25:56 2009]: ERROR: Did not get OK back
[Fri May  8 19:26:02 2009]: ERROR: 'undef' not detected in next()

Any ideas gratefully accepted.

Edit: Sorry, I'd edited down the code to show the basic flow. I should've proofread it a bit better.

  • I added the $ret in getcmd() to simulate what happens in the logging function which just prints out the current value of $ret which is a global variable always used to capture return values.
  • I'd trimmed down the log messages and missed the extra "back"

Thanks for the suggestions and comments. I hadn't noticed the six second difference in the log timestamps so now I suspect that you're right about the execution sequence being different to what I originally expected.

I'll go back and look again. Guess that's what you get when trying to look at someone else's "average" Perl after a thirteen hour day trying to get things finished for a "must go live on Monday" project!

I didn't write the code and simply inherited it. The code was written by a couple of people who think they don't "need no steenking warnings or stricts".

Imagine 800 lines of Perl and lots of 'ifs' but no else statements! No defensive coding at all! 8-O

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

贪恋 2024-07-26 04:36:43

减少到最低限度,这会打印“undef detector”。

#!/bin/perl -w

use strict;

sub getcmd
{
    return undef;
}

my $ret;

if (!($ret = getcmd()))
{
    print "undef detected\n";
}
else
{
    print "undef undetected\n";
}

因此,您的问题很可能是 $self->getcmd() 没有返回 undef,即使您认为它应该返回。

Reduced to a bare minimum, this prints "undef detected".

#!/bin/perl -w

use strict;

sub getcmd
{
    return undef;
}

my $ret;

if (!($ret = getcmd()))
{
    print "undef detected\n";
}
else
{
    print "undef undetected\n";
}

Consequently, your problem is most likely that the $self->getcmd() isn't returning undef, even though you think it should.

注定孤独终老 2024-07-26 04:36:43

我认为这里发生了更复杂的事情——这些日志消息似乎相隔 6 秒,而推送语句、返回和 if 检查不可能花费 6 秒。

第一条日志消息是否有可能来自应用程序中其他位置之前对该方法的调用?

I think something more complicated is going on here -- those log messages seem to be 6 seconds apart, and there's no way it'd take 6 seconds for the push statement, the return, and the if check.

Any chance the first log message was from a previous call of the method from some other place in the application?

耶耶耶 2024-07-26 04:36:43

使用 perl 调试器 (perl -d) 逐步执行代码以查看发生了什么情况。 调试代码时,重要的是让您的思想摆脱各种假设。

此外,这些行是每个 Perl 程序之上必须的:

use strict;
use warnings;

Use perl debugger (perl -d) to step through the code to see what is going on. When debugging code, it's important to free your mind from every assumption.

Also, these lines are a must above every perl program:

use strict;
use warnings;
守不住的情 2024-07-26 04:36:43

测试 $var 是否为 undef 的正确方法是不是 if (!$var) ...,因为该测试对于 $var = ''$var = 0 也成立。
使用 if (!define $var) ... 代替。

也许像这样(显示所有相关案例):

if (!defined $var) {
    # not defined ...
} elsif ($var) {
    # defined and true...
} else {
    # defined and false
}

The proper way to test $var for undef is not if (!$var) ..., because the test will also be true for $var = '' and $var = 0.
Use if (!defined $var) ... instead.

Maybe like this (showing all relevant cases):

if (!defined $var) {
    # not defined ...
} elsif ($var) {
    # defined and true...
} else {
    # defined and false
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文