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

Folks,

This is Yet Another Regex Question. Yes indeed. The multi-grep example in perlretut works very fine... when not using 'use strict', that is. As soon as 'use strict' is specified, a flurry of the following appears:

Global symbol "$number" requires explicit package name [...] Global symbol "@regexp" requires explicit package name [...] Global symbol "$number" requires explicit package name [...]

Is it possible to make this code work with 'use strict', and if so, how ? - Thanks !

As a reference, here's how the code is called, and the code itself from perlretut:

Called like:

./multi_grep.pl 2 last for multi_grep.pl

The code (saved as multi_grep.pl):

$number = shift; $regexp[$_] = shift foreach (0..$number-1); @compiled = map qr/$_/, @regexp; while ($line = <>) { foreach $pattern (@compiled) { if ($line =~ /$pattern/) { print $line; last; } } }

Replies are listed 'Best First'.
Re: YARQ: multi_grep example in perlretut
by vkon (Curate) on Apr 08, 2006 at 13:53 UTC
    actually it become 'use strict' question, and not 'Yet Another Regex Question'
    And 'use strict' is very respected among Perl community, together with 'warnings' option! :):)

    All you need is to declare required variables, as simple as that:

    my ($number,@regexp,@compiled,$line);
    That simple!
      Thanks a lot !

      The actual declaration for the given example would be:

      my ($pattern, $number, @regexp, @compiled, $line);

      And yes, you are correct, this is not a regex question, but IWTBTA.

      .

      .

      (I Was Tempted By The Acronym)

      Yes, it works this way, but you can improve it.

      As a rule of thumb, use as small scopes as possible for variable declarartion, e.g. $pattern isn't used outside the foreach-loop (especially since $pattern is an alias to the current element of @compiled), and so it's useless to declare it "globally"

      The same procedure with $line (although line is no alias, and the last content of line would stay in $line after the while block); if you write while( my $line = <> ) {, $line would only be usable within the while-loop-block, and you don't need to care if there is another $line somewhere outside the block which value is changed after the while loop)

      use strict; use warnings; my $number = shift; # first usage my @regexp = (); # initialize before first usage, my $regexp[$_] wou +ldn't work $regexp[$_] = shift foreach (0..$number-1); my @compiled = map qr/$_/, @regexp; # first usage while( my $line = <> ) { # only in block foreach my $pattern (@compiled) { # only in block if( $line =~ /$pattern/ ) { print $line; last; } } }

      or the like

      And I guess you can write the shift foreach-line in a better readable way:

      my $number = shift( @ARGV ); my @regexp = @ARGV[ 0..$number-1 ];

      Best regards,
      perl -e "s>>*F>e=>y)\*martinF)stronat)=>print,print v8.8.8.32.11.32"