Why is this line of Perl code throwing a numeric gt warning?
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 d开发者_开发知识库idn'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
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?
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.
精彩评论