dbrock has asked for the wisdom of the Perl Monks concerning the following question:

Hello, I seem to be missing the proper use of push... I thought I could push an variable onto the end of an array (Right side of array) by using somthing like...

push(@array,$variable);

I am chomping from a log file an Error message and assigning it to the variable of $errout then I push the $errout into @array and print it to a file before the end of the script.
I seem to have the problem that only the last if statement that is chomping my error messages is populating the @array. I was wondering if someone could point out my mistakes from this small code sample.

the error messages that the script is reading is ascii text ie...
file/path - skipped
file/path - cannot verify
file/path - corrupt file

##### cannot verify error - and Populate Output file##### if (@txtfile[$i] =~ /\bcannot verify/) { chomp ($errout = @txtfile[$i]); push(@outfile,$errout); } ##### corrupt file error - and Populate Output file##### if (@txtfile[$i] =~ /\bcorrupt file/) { chomp ($errout = @txtfile[$i]); push(@outfile,$errout); } ##### skipped File error - and Populate Output file##### if (@txtfile[$i] =~ /\b- skipped/) { chomp ($errout = @txtfile[$i]); push(@outfile,$errout); }

Thank you... Darrick...

Replies are listed 'Best First'.
Re: Example of push
by Paladin (Vicar) on Mar 26, 2003 at 04:42 UTC
    There are a few things that may be causing problems. You have
    if (@txtfile[$i] =~ /\b- skipped/) { chomp ($errout = @txtfile[$i]); push(@outfile,$errout); }
    • Single elements of arrays are accessed $array[0]. Using @array[0] takes an array slice, which is a list of 1 element, not a scalar value, which it doesn't look like you want. -w would have warned you about this.
    • \b in a regex matches between a \w and a \W character (or the other way around). In your example you have "file/path - skipped" as a sample. Both the space and the - are \W characters, so the \b won't match there.
    Other than that, the code looks good. If you are still having problems after fixing these things, perhaps you can reply and show us where @txtfile is getting assigned values, and where @outfile is getting used and someone can see what's wrong.
Re: Example of push
by robartes (Priest) on Mar 26, 2003 at 06:56 UTC
    Your code works as is, except for the \b issue in the last regex, as mentioned by Paladin. Note however, that, unlike what Paladin says (although probably like what he meant to say), is that. \b matches any spot between a \w character (alphanumerics and _, so [A-Za-z0-9_]) and a \W character (anything that is not a \w). In your example, you have put the \b in front of a dash, which is a \W, so the character in front of that would have to be a \w, which it is not (it's a space, in fact). That regex should be /\bskipped/ (or even /\bskipped\b/ if you're paranoid).

    You should also heed Paladin's warning re: the array slices. In this case you get the expected result, as your slices result in one element lists, which return the last (and only) element in scalar context.

    Another possible improvement is to put your regexes in a hash or an array to avoid the repetitive code you have above. Something like this:

    use strict; use Data::Dumper; my @txtfile=("file/path - skipped", "file/path - cannot verify", "file/path - corrupt file", "My camel has fleas", ); my @regex=('\bcannot verify', '\bcorrupt file', '\bskipped', ); my @outfile; foreach my $error (@txtfile) { foreach (@regex) { push (@outfile, $error) if $error=~/$_/; } } print Dumper(\@outfile); __END__ $VAR1 = [ 'file/path - skipped', 'file/path - cannot verify', 'file/path - corrupt file' ];

    Update: Turns out that Paladin actually did say what I thought he meant to say :). \w and \W were virtually indistinguishable in the font my browser picked for the <ul>, but he did say \W in the right places.

    CU
    Robartes-

      Expanding a bit on what robartes said, using a precompiled regular expression (qr//) might speed up the iterative loop. Because $_ is changing through each iteration of the loop:
      $error=~/$_/
      /$_/ must be re-compiled each time the value of $_ changes. Though this won't matter much in this instance, because of the relatively few number of iterations, a better way to do this would be to change the contents of @regex from:
      my @regex=('\bcannot verify', '\bcorrupt file', '\bskipped', );
      to:
      my @regex=( qr/\bcannot verify/, qr/\bcorrupt file/, qr/\bskipped/, );
      or even:
      my @regex = map qr/$_/, ( '\bcannot verify', '\bcorrupt file', '\bskipped', );
Re: Example of push
by dbrock (Sexton) on Mar 27, 2003 at 15:56 UTC

    Thank you all for your insite, and assistance... I have resolved this delima...
    This is a great site and the Members / Monks are very helpful...
    Thank You All...
    Darrick...