in reply to $_ and nested while loops w/angle operator

To expand upon what diotalevi said... You should do the pattern match inside the inner while loop, not in the conditional itself.

Here's how I'd rewrite your code:

while (<FH>) { if ( /^"\@QUERY:(.*)"/ ) { my $query = $1; while (<FH>) { last if /^"\@ENDQUERY"/; next if $_ eq ''; print $_; push @{$data{$query}}, $_; } } }

Note that this makes a HoA, rather than a HoH. Since the indices of your inner hash were simply sequential integers, an array works just as well, if not better.

PS - You don't need to backwhack quotes inside a /regex/.

jdporter
The 6th Rule of Perl Club is -- There is no Rule #6.

Replies are listed 'Best First'.
Re: Re: $_ and nested while loops w/angle operator
by jdporter (Paladin) on Apr 05, 2004 at 21:45 UTC

    (Continued.)

    My code, above, will create a Hash-of-Arrays in %data. When it's done, you can iterate over the data set using code like the following:

    for my $query( sort keys %data ) { # get all the lines of the query at once, into an array: my @query_lines = @{$data{$query}}; # or iterate over them: for my $qline ( @{$data{$query}} ) { # ... do something with the line. } # or, if you really care about the line numbers: for my $li ( 0 .. $#{$data{$query}} ) { my $qline = $data{$query}[$li]; print "query $query, line $li: $qline"; } }
    Of course, the possibilities are endless; so if you are having trouble working with the data once you've read it in, we'd be happy to help.

    jdporter
    The 6th Rule of Perl Club is -- There is no Rule #6.

      jdporter,

      Update: I should've keep reading in perlreftut! The answer is here for anyone else that is still learning how to use references. Thank you all for your help.


      Thanks for the further elaboration. For some reason, I am having a hard time understanding what is happening here:

      ----------
      Using perl 5.6.1 unless otherwise noted. Apache 1.3.27 unless otherwise noted. Redhat 7.1 unless otherwise noted.

        The fundamental point is that a reference is just another kind of scalar value. Anywhere you can put 3 or "ouch", you can put a reference. So an arrayref need not be the simple scalar variable in the example ($aref), it could be an element of an array ($refs[9]) or the value of a hash element ($hits{"blue"}).

        So, given that $data{$query} contains an array ref, you can push things on that array via

        push @{ $data{$query} }, $thing;

        To return a hash by reference, you treat the hash variable as an opaque container. Like so:

        return \%data;

        jdporter
        The 6th Rule of Perl Club is -- There is no Rule #6.