Why is this line of Perl code throwing a numeric gt warning? - perl

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

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.

Related

Raspbian can not be update properly

Suddenly my RaspberryPi can not be upgrade properly. The apt gives following error message. Is there anyone could me how to fix this problem.
Following is the error message
dpkg-deb: error: subprocess tar was killed by signal (Segmentation fault)
Traceback (most recent call last):
File "/usr/bin/apt-listchanges", line 250, in <module>
main()
File "/usr/bin/apt-listchanges", line 108, in main
pkg = DebianFiles.Package(deb)
File "/usr/share/apt-listchanges/DebianFiles.py", line 134, in __init__
self.binary = pkgdata.Package
AttributeError: ControlStanza instance has no attribute 'Package'
i have already found the reason and fixed the problem.
step
1) use this command to catch the trace log.
sudo strace -f -e trace=execve apt-get -y upgrade > execlist 2>&1
2) check the execlist file and notice following error message
[pid 27534] execve("/usr/local/sbin/tar", ["tar", "-x", "-m", "-f", "-", "--warning=no-timestamp"], [/* 17 vars */]) = -1 ENOENT (No such file or directory)
[pid 27534] execve("/usr/local/bin/tar", ["tar", "-x", "-m", "-f", "-", "--warning=no-timestamp"], [/* 17 vars */]) = -1 ENOENT (No such file or directory)
[pid 27534] execve("/usr/sbin/tar", ["tar", "-x", "-m", "-f", "-", "--warning=no-timestamp"], [/* 17 vars */]) = -1 ENOENT (No such file or directory)
[pid 27534] execve("/usr/bin/tar", ["tar", "-x", "-m", "-f", "-", "--warning=no-timestamp"], [/* 17 vars */]) = -1 ENOENT (No such file or directory)
[pid 27534] execve("/sbin/tar", ["tar", "-x", "-m", "-f", "-", "--warning=no-timestamp"], [/* 17 vars */]) = -1 ENOENT (No such file or directory)
[pid 27534] execve("/bin/tar", ["tar", "-x", "-m", "-f", "-", "--warning=no-timestamp"], [/* 17 vars */]) = 0
[pid 27533] +++ exited with 0 +++
[pid 27532] +++ exited with 0 +++
[pid 27531] --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=27533, si_uid=0, si_status=0, si_utime=0, si_stime=0} ---
[pid 27534] --- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0x638aa} ---
[pid 27534] +++ killed by SIGSEGV +++
3) it seems something wrong with the program tar.
4) download a new tar program on another server and replace it.
the problem solved.

Test::Mojo + prove leads to duplicate logging

I have the following test script that utilizes Test::Mojo. When I run it from the command line using perl, it outputs correctly. However, when I run it through "prove -v", the Mojo logging is duplicated and one of them isn't piped through "on message".
#!/usr/bin/env perl
use strict;
use warnings;
use Test::More tests => 1;
use Mojolicious::Lite;
use Test::Mojo;
app->log->on(
message => sub {
my ( $log, $level, #lines ) = #_;
note "MojoLog $level: #lines";
}
);
get '/debug/mojo/req_url' => sub {
my $c = shift;
$c->render( text => $c->req->url );
};
subtest 'Mojo - $c->req->url' => sub {
plan tests => 3;
my $t = Test::Mojo->new;
$t->get_ok('/debug/mojo/req_url') #
->status_is(200) #
->content_is('/debug/mojo/req_url');
};
The output when run directly:
$ perl dup_logging.t
1..1
# Subtest: Mojo - $c->req->url
1..3
# MojoLog debug: GET "/debug/mojo/req_url"
# MojoLog debug: Routing to a callback
# MojoLog debug: 200 OK (0.000797s, 1254.705/s)
ok 1 - GET /debug/mojo/req_url
ok 2 - 200 OK
ok 3 - exact match for content
ok 1 - Mojo - $c->req->url
And the output when run through prove:
$ prove -v dup_logging.t
dup_logging.t ..
1..1
# Subtest: Mojo - $c->req->url
1..3
[Thu Mar 8 12:16:35 2018] [debug] GET "/debug/mojo/req_url"
# MojoLog debug: GET "/debug/mojo/req_url"
[Thu Mar 8 12:16:35 2018] [debug] Routing to a callback
# MojoLog debug: Routing to a callback
[Thu Mar 8 12:16:35 2018] [debug] 200 OK (0.000842s, 1187.648/s)
# MojoLog debug: 200 OK (0.000842s, 1187.648/s)
ok 1 - GET /debug/mojo/req_url
ok 2 - 200 OK
ok 3 - exact match for content
ok 1 - Mojo - $c->req->url
ok
All tests successful.
Files=1, Tests=1, 1 wallclock secs ( 0.03 usr 0.01 sys + 0.34 cusr 0.03 csys = 0.41 CPU)
Result: PASS
The following is my version information:
$ perl -MMojolicious -E 'say Mojolicious->VERSION'
7.14
$ prove --version
TAP::Harness v3.36 and Perl v5.16.3
I discovered that one way to avoid this problem is to set the MOJO_LOG_LEVEL environment variable at the top of the script.
$ENV{MOJO_LOG_LEVEL} = 'fatal';
Any other suggestions on how to get prove and Test::Mojo to play well together with regard to the logging?
The prove testrunner uses the TAP::Harness infrastructure. When you run prove -v, this will set the HARNESS_IS_VERBOSE environment variable.
Then, Mojo::Test picks up this environment variable:
# Silent or loud tests
$ENV{MOJO_LOG_LEVEL} ||= $ENV{HARNESS_IS_VERBOSE} ? 'debug' : 'fatal';
You therefore get Mojo's debug log messages when running prove -v.
It seems that manually setting the MOJO_LOG_LEVEL env variable is the best approach if you do not want this output.

How can I fix uninitialized value in numeric eq (==)

How can I fix this error:
[Fri Dec 11 12:07:24.417565 2015] [cgi:error] [pid 10838] [client 24.32.36.240:54536] AH01215: [Fri Dec 11 12:07:24 2015]
uu_upload.pl: Use of uninitialized value in numeric eq (==) at uu_upload.pl line 350.: /home/public_html/cgi-bin/uu_upload.pl,
referer: http://www.....com/uploader.php
Line 349 - Line 353 shows:
# Force 'redirect_using_location' if user does not have a javascript capable browser or using embedded_upload_results
if($query->param('no_script') || $query->param('embedded_upload_results') == 1){
$main::config->{redirect_using_js_html} = 0;
$main::config->{redirect_using_location} = 1;
}
Any assistance will be appreciated.
Using the defined function you can check the variable is defined.
if ( defined($variable) && $variable == 10 ) {
...
}

A fast way to read and store some values inside a big log file with Perl

Sorry for asking so many times questions about reading lines and other thingies. I happen to be dealing with a huge (500,000 lines) file like this:
2013-05-27T19:01:23 [INFO] item_id:1, start at Reader.pm line 23
2013-05-27T19:01:29 [INFO] item_id:2, pause at Reader.pm line 23
2013-05-27T19:01:30 [INFO] item_id:1, start at Reader.pm line 23
2013-05-27T19:01:30 [INFO] item_id:1, start at Reader.pm line 23
2013-05-27T19:01:30 [INFO] item_id:1, start at Reader.pm line 23
2013-05-27T19:01:30 [INFO] item_id:1, start at Reader.pm line 23
2013-05-27T19:01:30 [INFO] item_id:3, start at Reader.pm line 23
2013-05-27T19:01:30 [INFO] item_id:3, start at Reader.pm line 23
2013-05-27T19:01:30 [INFO] item_id:3, start at Reader.pm line 23
2013-05-27T19:01:30 [INFO] item_id:5, start at Reader.pm line 23
2013-05-27T19:01:30 [INFO] item_id:5, start at Reader.pm line 23
2013-05-27T19:01:30 [INFO] item_id:5, start at Reader.pm line 23
2013-05-27T19:01:30 [INFO] item_id:5, start at Reader.pm line 23
2013-05-27T19:01:30 [INFO] item_id:5, start at Reader.pm line 23
What I need to do is, given the file location as input, make a script which output should resemble something like this:
$output = [ {item_id => 1, counter => 2 }, { item_id......
That is, each item_id should be paired with the number of starts it has inside an array ref. Notice that I can't use a "while" to read the file more than once, since its way too big. Also, I do not know a priori how many items there are.
The method I wrote using tips from Stackoverflow members is as follows:
sub count_start{
open LOGFILE, $file_location;
my $max;
my $i;
my $counter = 0;
my $found = 0;
my $data;
while (<LOGFILE>) {
next unless /item_id:(\d+)/;
$found = $1 if $found < $1;
for ($i =1, $i<=$found, $i++){
if ($file_location =~ /\bitem_id:$i, start\b/ig){
$counter++;
}
$output = [ $i => $counter ];
}
}
close LOGFILE;
return $output;
}
1;
But everything went really wrong :(. I get a lot of nasty warnings and nothing remotely similar to what I was asked for. Any ideas or suggestions?
Forgive this perl newbie for his awful code.
I would use a hash to do the counting, then transform it to an array of hashes afterwards. However, it looks like you are using perl code to store your data, which is not the best idea. There are better formats, such as JSON, or even Text::CSV.
That aside, the Data::Dumper module can be used for this purpose.
use strict;
use warnings;
use Data::Dumper;
my %output;
while (<DATA>) {
if (/ item_id:(\d+), start at /) {
$output{$1}++;
}
}
my #data = map { { item_id => $_, counter => $output{$_} } } keys %output;
print Dumper \#data;
__DATA__
2013-05-27T19:01:23 [INFO] item_id:1, start at Reader.pm line 23
2013-05-27T19:01:29 [INFO] item_id:2, pause at Reader.pm line 23
2013-05-27T19:01:30 [INFO] item_id:1, start at Reader.pm line 23
2013-05-27T19:01:30 [INFO] item_id:1, start at Reader.pm line 23
2013-05-27T19:01:30 [INFO] item_id:1, start at Reader.pm line 23
2013-05-27T19:01:30 [INFO] item_id:1, start at Reader.pm line 23
2013-05-27T19:01:30 [INFO] item_id:3, start at Reader.pm line 23
2013-05-27T19:01:30 [INFO] item_id:3, start at Reader.pm line 23
2013-05-27T19:01:30 [INFO] item_id:3, start at Reader.pm line 23
2013-05-27T19:01:30 [INFO] item_id:5, start at Reader.pm line 23
2013-05-27T19:01:30 [INFO] item_id:5, start at Reader.pm line 23
2013-05-27T19:01:30 [INFO] item_id:5, start at Reader.pm line 23
2013-05-27T19:01:30 [INFO] item_id:5, start at Reader.pm line 23
2013-05-27T19:01:30 [INFO] item_id:5, start at Reader.pm line 23
Output:
$VAR1 = [
{
'counter' => 5,
'item_id' => '1'
},
{
'counter' => 3,
'item_id' => '3'
},
{
'counter' => 5,
'item_id' => '5'
}
];
Note that the output is unsorted, due to the fact that hashes are not sorted. If you want it sorted, you can apply the sort function to the keys.
Also note that this version takes into account that you said to count the "starts", which with this input does not include line #2 that says item_id:2, pause at.
You can't put hash like associations in a list. For that you need a hash:
use strict;
use warnings;
my %output;
my $filename = shift #ARGV;
open my $file, "<", $filename or die("$!: $filename");
while (<$file>) {
if (/item_id:(\d+)\s*,\s*start/) {
$output{$1}++;
}
}
close $file;
for my $item(keys %output) {
print "$item -> $output{$item}\n";
}
Output
1 -> 5
3 -> 3
5 -> 4
You can replace the while loop with this:
/item_id:(\d+)\s*,\s*start/ and $output{$1}++ while <$file>;
but it isn't really readable.

Compilation Error in perl script while giving present date in input file name

As per below script, Trying to give two Input files. Test_DDD111_20120731.csv and DDD111.txt.
Inside one folder this Test_DDD111*.csv file with different date will be available. I want to give only current date file as input inside this script.
I assign date as $deviationreportdate. But i am getting error, can anyone help me to solve this problem.
Error which i am getting:
Scalar found where operator expected at subscriberdump.pl line 58, near "/Test_DDD(\d+)/${deviationreportdate}"
(Missing operator before ${deviationreportdate}?)
syntax error at subscriberdump.pl line 58, near "/Test_DDD(\d+)/${deviationreportdate}"
Execution of test.pl aborted due to compilation errors.
#!/usr/bin/perl
use strict;
use warnings;
use strict;
use POSIX;
my #array123;
my $daysbefore;
my %month="";
my ($f2_field, #patterns, %patts, $f2_rec);
while (#ARGV)
{
my $par=shift;
if( $par eq "-d" )
{
$daysbefore=shift;
next;
}
}
sub getDate
{
my $daysago=shift;
$daysago=0 unless ($daysago);
my #months=qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
Localtime(time(86400*$daysago));
# YYYYMMDD, e.g. 20060126
return sprintf("%d%02d%02d",$year+1900,$mon+1,$mday);
}
my $deviationreportdate=getDate($daysbefore-1);
my $transactiondate=getDate($daysbefore);
my $filename="output.txt");
open(OUTPUTFILE,"> /tmp/$filename");
for my $Test_file (<Test_DDD*${deviationreportdate}*>)
{
if ($Test_file =~ /Test_DDD(\d+)/${deviationreportdate}*)
{
my $file = "DDD$1.txt";
my $ID="DDD$1";
open AIN, "<$file" or die($file);
open BIN, "<$Test_file" or die($Test_file);
my %seen;
}
This regular expression is invalid
$Test_file =~ /Test_DDD(\d+)/${deviationreportdate}*
you can only have modifiers after the last slash in a regex. I'm not exactly sure what you're trying to do with this, otherwise I would post the correct regex for you. maybe you ment this?
$Test_file =~ /Test_DDD(\d+)\/${deviationreportdate}*/
or this
$Test_file =~ /Test_DDD(\d+)${deviationreportdate}*/