Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

need help on declaring variables

by tuakilan (Acolyte)
on Mar 03, 2008 at 06:41 UTC ( #671582=perlquestion: print w/ replies, xml ) Need Help??
tuakilan has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks,

I put the following code to run on a linux box and tried to run it but it gave me some error

use strict; use warnings; use DateTime::Format::Strptime; my $Strp = new DateTime::Format::Strptime(pattern => '%Y-%b-%d %T' +,); my $infile = 'log.txt'; my $outfile = 'report.txt'; my($fh_out, $fh); my %lookup; my $channel = 'TWO'; my $time_delta = 3600; # seconds = 1 hour open($fh_out, '>', $outfile) or die "Could not open outfile: $!"; open($fh, '<', $infile) or die "Could not open logfile: $!"; while (<$fh>) { next unless /$channel/; $_ =~ m/^(.*) UTC.*refs = (\d+)$/; my $dt = $Strp->parse_datetime($1); my $timestamp = $dt ->epoch(); my $refs = $2; if ( defined($lookup{$refs}) && $lookup{$refs} + $time_delta <= $t +imestamp ) { print $fh_out "REFS $refs: occurrences at " . $lookup{$refs} . + "and $timestamp \n"; print "REFS $refs: occurrences at " . $lookup{$refs} . " and $ +timestamp \n"; } $lookup{$refs} = $timestamp; } close $fh_out; #close $fh;

The error seems to stem from here

my $dt = $Strp->parse_datetime($1); my $timestamp = $dt ->epoch(); my $refs = $2;
the $1 and $2 ...

I wonder where did i go wrong ...

Comment on need help on declaring variables
Select or Download Code
Replies are listed 'Best First'.
Re: need help on declaring variables
by Thilosophy (Curate) on Mar 03, 2008 at 06:48 UTC
    but it gave me some error

    Hmm. Did it give you an error message to go along with the error?

    The error seems to stem from here:

    my $dt = $Strp->parse_datetime($1); my $timestamp = $dt ->epoch(); my $refs = $2;
    You suspect $1 and $2. Do they contain the value you think they should (add some debug output)? When using regular expressions, you should check if there actually was a match.
      hi thilosophy,

      the error which i got when run the script is

      Can't call method "epoch" on an undefined value at comblog.pl line 52, + <$fh> line 5.
Re: need help on declaring variables
by peterdragon (Beadle) on Mar 03, 2008 at 09:05 UTC
    The line
    my $dt = $Strp->parse_datetime($1);
    is returning undef because the input string in $1 is in an incorrect format. Either change the declaration of Strp like
    my $Strp = new DateTime::Format::Strptime(pattern => '%Y-%b-%d %T' +, on_error => 'croak');
    to throw an error in that case or check for it in your code by replacing the line starting 'my $dt...' with
    unless (my $dt = $Strp->parse_datetime($1)) { warn "invalid datetime: $1"; next; }
Re: need help on declaring variables
by ysth (Canon) on Mar 03, 2008 at 07:38 UTC
Re: need help on declaring variables
by almut (Canon) on Mar 03, 2008 at 08:34 UTC
    $_ =~ m/^(.*) UTC.*refs = (\d+)$/; my $dt = $Strp->parse_datetime($1); my $timestamp = $dt ->epoch(); my $refs = $2;

    ...third (in addition to what ysth said), don't use $1, $2, etc. after some code which could have modified those variables in the meantime (like the $dt->epoch() call here — I'm not saying that it did modify $2, but code under the hood of that call could have...). Best only use them immediately after the match, or store the value away in some other variable.

Re: need help on declaring variables
by hipowls (Curate) on Mar 03, 2008 at 09:35 UTC

    When using regular expressions it is usually a good idea to put them in a condition.

    if ( my ( $raw_dt, $refs ) = /^(.*) UTC.*refs = (\d+)$/ ) { my $dt = $Strp->parse_datetime($raw_dt); ... } else { # possible error condition }
    The greater danger of your code, apart from using uninitialized $1 and $2, is using an initialized $1 and $2 from a previous match. The capture buffer variables $1 etc are not reset to undef when a match fails so you may produce erroneous output without any outward sign.

Re: need help on declaring variables
by stiller (Friar) on Mar 03, 2008 at 09:24 UTC
    Wariation over a theme...., change:
    $_ =~ m/^(.*) UTC.*refs = (\d+)$/; my $dt = $Strp->parse_datetime($1); my $timestamp = $dt ->epoch(); my $refs = $2; if ( defined($lookup{$refs}) && ....
    to:
    my ($dt, $timestamp, $refs); if ( m/^(.*) UTC.*refs = (\d+)$/ ){ # right here, just after the match, is the only # place it's safe to use $1 and $2 - tuck them away: my $t = $1; $refs = $2; $dt = $Strp->parse_datetime($t); $timestamp = $dt ->epoch(); } else { warn "No match: $_ \n"; next; } if ( defined($lookup{$refs}) && ....
    Edit: corrected an error (my'ing $refs twice)

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://671582]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (9)
As of 2015-07-29 10:07 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (263 votes), past polls