为什么这行 Perl 代码会抛出数字 gt 警告?

发布于 2024-10-18 22:41:45 字数 4156 浏览 4 评论 0原文

我有以下条件:

if ($self->path ne 'contact_us' && !grep { $status == $_ } 2, 3, 8) {

它抛出此警告:

在数字 gt (>) 中使用未初始化的值

当然,表面上根本不存在数字 gt。 $self->path 是一个 Moose 属性访问器,因此唯一的幕后魔力就来自于此。但我看不出这将如何进行数字 gt 比较,特别是因为 path 定义如下:

has 'path' => (is => 'rw', isa => 'Str');

关于如何抛出此警告的任何想法?我正在使用为 i386-linux-thread-multi 构建的 Perl v5.8.8,如果在这种情况下很重要的话。

更新:更神秘的是,我将条件重写如下:

my $cond1 = $self->path ne 'contact_us';
my $cond2 = !grep { $status == $_ } 2, 3, 8;
if ($cond1 && $cond2) {

第三行抛出警告。 Carp::Always 的堆栈跟踪信息不足。一些进一步的披露,因为我现在感觉完全无能为力:基本文件是一个由 Apache 的 mod_fcgi 调用的 FastCGI 脚本。

最后更新: $status 是通过调用另一个模块 (My::Session) 中的方法来设置的。这是在该模块的方法中生成警告的行(注意错误的 >):

my $disputes => dbh('b')->selectrow_hashref($query);

令我困惑的是为什么警告没有引用包含有问题的行的模块(它引用了使方法调用,My::Page)。这是 Carp::Always 的完整输出;完全没有提及 My::Session

[2011 年 2 月 23 日星期三 17:44:29] [警告] [客户端----.---.94.159] mod_fcgid: stderr:在中使用未初始化的值 数字 gt (>) 位于 /path/to/My/Page.pm 第 65 行,参考: https://testserver.domain.tld/help

[2011 年 2 月 23 日星期三 17:44:29] [警告] [客户端----.---.94.159] mod_fcgid: 标准错误: \tPage::BUILD('我的::Page::Help=HASH(0xa7ce788)', 'HASH(0xa327904)') 调用于 /usr/lib/perl5/site_perl/5.8.8/i386-linux-thread-multi/Class/MOP/Method.pm 第 123 行,参考: https://testserver.domain.tld/help

[2011 年 2 月 23 日星期三 17:44:29] [警告] [客户端----.---.94.159] mod_fcgid: 标准错误: \tClass::MOP::Method::execute('Moose::Meta::Method=HASH(0x9fa357c)', '我的::页面::帮助=哈希(0xa7ce788)', 'HASH(0xa327904)') 调用于 /usr/lib/perl5/site_perl/5.8.8/i386-linux-thread-multi/Moose/Object.pm 第 57 行,引用: https://testserver.domain.tld/help

[2011 年 2 月 23 日星期三 17:44:29] [警告] [客户端----.---.94.159] mod_fcgid: stderr: \tMoose::Object::BUI,引用地址: https://testserver.domain.tld/help

[2011 年 2 月 23 日星期三 17:44:29] [警告] [客户端----.---.94.159] mod_fcgid: 标准错误: LDALL('我的::页面::帮助=HASH(0xa7ce788)', 'HASH(0xa327904)') 调用于 /usr/lib/perl5/site_perl/5.8.8/i386-linux-thread-multi/Moose/Meta/Class.pm 第 278 行,参考: https://testserver.domain.tld/help

[2011 年 2 月 23 日星期三 17:44:29] [警告] [客户端----.---.94.159] mod_fcgid: 标准错误: \tMoose::Meta::Class::new_object('Class::MOP::Class::ANON::SERIAL::1=HASH(0xa3397c8)', 'HASH(0xa327904)') 调用于 /usr/lib/perl5/site_perl/5.8.8/i386-linux-thread-multi/Moose/Object.pm 第 26 行,引用: https://testserver.domain.tld/help

[2011 年 2 月 23 日星期三 17:44:29] [警告] [客户端----.---.94.159] mod_fcgid: 标准错误: \tMoose::Object::new('我的::页面::帮助', 'HASH(0xa339d38)') 在生成时调用 方法(来源不明)第3行, 推荐人: https://testserver.domain.tld/help

[2011 年 2 月 23 日星期三 17:44:29] [警告] [客户端----.---.94.159] mod_fcgid: 标准错误: \tMy::Page::new('My::Page::Suppo, 推荐人: https://testserver.domain.tld/help

[2011 年 2 月 23 日星期三 17:44:29] [警告] [客户端----.---.94.159] mod_fcgid: stderr: rt', 'HASH(0xa339d38)') 被调用 在 /path/to/My.pm 第 44 行,引用地址: https://testserver.domain.tld/help

[2011 年 2 月 23 日星期三 17:44:29] [警告] [客户端----.---.94.159] mod_fcgid: stderr: \tMy::start() 调用于 index.fcgi 第 9 行,引用地址: https://testserver.domain.tld/help

I have the following conditional:

if ($self->path ne 'contact_us' && !grep { $status == $_ } 2, 3, 8) {

And it is throwing this warning:

Use of uninitialized value in numeric gt (>)

Of course, there's no numeric gt at all on the surface. $self->path is a Moose attribute accessor, so the only under-the-hood magic would be coming from that. But I can't see how that would be making a numeric gt comparison, especially since path is defined as follows:

has 'path' => (is => 'rw', isa => 'Str');

Any ideas on how this warning is getting thrown? I'm using Perl v5.8.8 built for i386-linux-thread-multi, if it matters in this case.

Update: Even more mysteriously, I've rewritten the conditional as follows:

my $cond1 = $self->path ne 'contact_us';
my $cond2 = !grep { $status == $_ } 2, 3, 8;
if ($cond1 && $cond2) {

And it's the third line that throws the warning. Carp::Always's stack trace isn't sufficiently informative. Some further disclosure, as I'm feeling utterly clueless now: The base file is a FastCGI script being called up by Apache's mod_fcgi.

Last update:
$status was getting set by a call to a method found in another module (My::Session). Here was line generating the warning in that module's method (note the errant >):

my $disputes => dbh('b')->selectrow_hashref($query);

What's confusing to me is why the warning didn't reference the module containing the offending line (it referenced the module making the method call, My::Page). Here's the full output from Carp::Always; there is an utter lack of mention of My::Session:

[Wed Feb 23 17:44:29 2011] [warn]
[client ---.---.94.159] mod_fcgid:
stderr: Use of uninitialized value in
numeric gt (>) at /path/to/My/Page.pm
line 65, referer:
https://testserver.domain.tld/help

[Wed Feb 23 17:44:29 2011] [warn]
[client ---.---.94.159] mod_fcgid:
stderr:
\tPage::BUILD('My::Page::Help=HASH(0xa7ce788)',
'HASH(0xa327904)') called at
/usr/lib/perl5/site_perl/5.8.8/i386-linux-thread-multi/Class/MOP/Method.pm
line 123, referer:
https://testserver.domain.tld/help

[Wed Feb 23 17:44:29 2011] [warn]
[client ---.---.94.159] mod_fcgid:
stderr:
\tClass::MOP::Method::execute('Moose::Meta::Method=HASH(0x9fa357c)',
'My::Page::Help=HASH(0xa7ce788)',
'HASH(0xa327904)') called at
/usr/lib/perl5/site_perl/5.8.8/i386-linux-thread-multi/Moose/Object.pm
line 57, referer:
https://testserver.domain.tld/help

[Wed Feb 23 17:44:29 2011] [warn]
[client ---.---.94.159] mod_fcgid:
stderr: \tMoose::Object::BUI, referer:
https://testserver.domain.tld/help

[Wed Feb 23 17:44:29 2011] [warn]
[client ---.---.94.159] mod_fcgid:
stderr:
LDALL('My::Page::Help=HASH(0xa7ce788)',
'HASH(0xa327904)') called at
/usr/lib/perl5/site_perl/5.8.8/i386-linux-thread-multi/Moose/Meta/Class.pm
line 278, referer:
https://testserver.domain.tld/help

[Wed Feb 23 17:44:29 2011] [warn]
[client ---.---.94.159] mod_fcgid:
stderr:
\tMoose::Meta::Class::new_object('Class::MOP::Class::ANON::SERIAL::1=HASH(0xa3397c8)',
'HASH(0xa327904)') called at
/usr/lib/perl5/site_perl/5.8.8/i386-linux-thread-multi/Moose/Object.pm
line 26, referer:
https://testserver.domain.tld/help

[Wed Feb 23 17:44:29 2011] [warn]
[client ---.---.94.159] mod_fcgid:
stderr:
\tMoose::Object::new('My::Page::Help',
'HASH(0xa339d38)') called at generated
method (unknown origin) line 3,
referer:
https://testserver.domain.tld/help

[Wed Feb 23 17:44:29 2011] [warn]
[client ---.---.94.159] mod_fcgid:
stderr:
\tMy::Page::new('My::Page::Suppo,
referer:
https://testserver.domain.tld/help

[Wed Feb 23 17:44:29 2011] [warn]
[client ---.---.94.159] mod_fcgid:
stderr: rt', 'HASH(0xa339d38)') called
at /path/to/My.pm line 44, referer:
https://testserver.domain.tld/help

[Wed Feb 23 17:44:29 2011] [warn]
[client ---.---.94.159] mod_fcgid:
stderr: \tMy::start() called at
index.fcgi line 9, referer:
https://testserver.domain.tld/help

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

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

发布评论

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

评论(2

如此安好 2024-10-25 22:41:45

我的猜测是你的参数之一是一个重载的对象,并且重载会引发错误。检查一下你的参数到底是什么:

print "$_: ", ref, $/ for $self, $self->path, $status;

哪个应该打印类似的内容:

HASH(0x12341234)=Self::Object: Self::Object
some/path:
4:

如果你得到的是:

HASH(0x12341234)=Self::Object: Self::Object
some/path: Some::Object
4: Some::Other::Object

那么你应该查看每个包以查看是否存在重载。

您还可以编写一个 bool 函数,它将强制将一个值转换为非重载的 bool:

sub bool {$_[0] ? 1 : 0}

然后:

my $cond1 = bool $self->path ne 'contact_us';
my $cond2 = bool !grep { $status == $_ } 2, 3, 8;
if ($cond1 && $cond2) {

如果这解决了问题,那么您的参数中至少有一个可能是行为不当的重载对象。

这也可能是由自动装箱编译指示之一引起的,例如 use bigint;use bignum;,它们转换文字数字,例如 2, 3, 8 进入重载对象。有这样的实用指令吗?

My guess is that one of your arguments is an overloaded object, and that overloading is throwing the error. Check to see exactly what your arguments are:

print "$_: ", ref, $/ for $self, $self->path, $status;

Which should print something like:

HASH(0x12341234)=Self::Object: Self::Object
some/path:
4:

If instead you are getting:

HASH(0x12341234)=Self::Object: Self::Object
some/path: Some::Object
4: Some::Other::Object

Then you should look at each of those packages to see if there is overloading present.

You can also write a bool function which will force a value into a non-overloaded bool:

sub bool {$_[0] ? 1 : 0}

And then:

my $cond1 = bool $self->path ne 'contact_us';
my $cond2 = bool !grep { $status == $_ } 2, 3, 8;
if ($cond1 && $cond2) {

If that fixes the problem, chances are at least one of your arguments is an overloaded object that is misbehaving.

This also could possibly be caused by one of the autoboxing pragmas like use bigint; or use bignum; which convert literal numbers like 2, 3, 8 into overloaded objects. Are any pragmas like this in effect?

情泪▽动烟 2024-10-25 22:41:45

我很确定您没有在粘贴的代码上方正确设置 $status 。您可能还使用旧版本的 Perl,因为在我的 MBP 上的 ActiveState 5.12 中,它将打印出失败的变量名称,就像在 FreeBSD 下的 5.10 中一样。在我的基于 Linux 的 VPS 上的 5.8.8 下,变量名称不是失败消息的一部分。

提供帮助不仅仅是几行代码会更容易,因为通常不会在程序死亡的行上找到此类错误的根本原因,而是由于变量并非真正的原因持有你认为它持有的东西。

I'm pretty sure that you're not getting $status set properly somewhere above the code that you've pasted. You're probably also on an older version of Perl, since in ActiveState 5.12 on my MBP, it will print out the variable name which has failed, as it does in 5.10 under FreeBSD. Under 5.8.8 on my Linux-based VPS, the variable name isn't part of the fail message.

It would be easier to help with more than just a couple of lines of code, since usually the root cause of this sort of error isn't going to be found on the line where the program is dying, but due to a variable not really holding what you think it holds.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文