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

Hi All,

I have the following code. Each key in %logfiles looks similar to HELog_fpltesthc.log.3.gz. When I try to use the split fuction on the keys it fails with the error below? I am new to perl and maybe this is not possible. Does anyone see the error of my way?

foreach $log ( sort keys %logfiles ) { foreach ( @surl ) { $urlp = $_ . 'hc'; if ( $log =~ /[.]/ && $log !~ /^[.]/ ) { @slog = split( '.', $log ); #$slog[0] =~ s/HELog_//g; print $slog[0]; #if ( $slog[0] eq $urlp ) { #push @logfiles, $log; #} } } }
Use of uninitialized value in print at ./he8-errors line 252. Use of uninitialized value in print at ./he8-errors line 252. Use of uninitialized value in print at ./he8-errors line 252. Use of uninitialized value in print at ./he8-errors line 252. Use of uninitialized value in print at ./he8-errors line 252. Use of uninitialized value in print at ./he8-errors line 252.


The line that is erroring out is: print $slog[0];

Apparently the split is failing.

Replies are listed 'Best First'.
Re: Is it possible to split a hash key?
by diotalevi (Canon) on Jul 28, 2007 at 23:06 UTC

    You are too scared of proper escaping. The first parameter to split is always a regexp even if you write a string (unless that string happens to be a single space). You have written split( /./ , $log ) says to split between every non-newline character. Further, the performance of all non-5.10 regexp engines are reduced by writing your dots as [.] instead of the literal \.. Your regexp and pattern to split should both read /\./.

    ⠤⠤ ⠙⠊⠕⠞⠁⠇⠑⠧⠊

      That's right! I forgot to escape the reqex .

      Thanks for pointing that out.
      Just a side note. You wrote:

      The first parameter to split is always a regexp even if you write a string (unless that string happens to be a single space).

      A single space also results in (the equivalent of) a regex in split. The difference is that the regex is not the string itself (/ /) but /\s+/. Specifying ' ' is an alternaive way of invoking the default which is to split on white space.

      Anno

        ... The difference is that the regex is not the string itself (/ /) but /\s+/

        ...not to forget the subtle, additional magic of ' ' vs. /\s+/ in the handling of leading whitespace. Compare

        my $s = " foo bar baz"; print join("|", split /\s+/, $s), "\n"; # prints |foo|bar|baz print join("|", split ' ', $s), "\n"; # prints foo|bar|baz
Re: Is it possible to split a hash key?
by wind (Priest) on Jul 29, 2007 at 00:41 UTC
    style and efficiency suggestion:

    It appears that your code and logic are currently incomplete. However, the first if statement should probably be moved to just after the foreach $log loop. As it's written right now it's independent of the foreach on @surl, so it should be outside of it to simplify the logic and to not needlessly run that foreach multiple times.

    And don't forget to "my" your foreach iterator.
    foreach my $log ( sort keys %logfiles ) { next if $log !~ /\./ || $log =~ /^\./;
    - Miller
Re: Is it possible to split a hash key?
by Anonymous Monk on Jul 29, 2007 at 20:02 UTC

    Is it possible to split a hash key?

    No, split operates on scalars. It can, however, operate on a scalar returned by keys. They're not special.

      All hash keys are scalars. And all arrays are arrays of scalars (multi-dimensional arrays have a degree of indirection behind the scenes).

      Looking at perldoc -f keys, you get the following:

      keys HASH
      Returns a list consisting of all the keys of the named hash. (In scalar context, returns the number of keys.)

      So in summary, of course you can split a hash key, and do everything else with it than you can a scalar.