Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

Match operator fails for elements 100 and higher

by thrasher (Initiate)
on Nov 03, 2010 at 20:39 UTC ( #869313=perlquestion: print w/replies, xml ) Need Help??
thrasher has asked for the wisdom of the Perl Monks concerning the following question:

There's a piece of code out there called _bm_build, and it failed on me. I extracted the relevant part to create this test.
#! /usr/bin/perl -w use strict; my @mystrings = ("string") x 200; m/$mystrings[99]/; # This compiles fine. "$mystrings[100]"; # This compiles fine. m/$mystrings[100]/; # This does not.
The error I get is
Global symbol "$mystrings" requires explicit package name at ./maketest.pl line 9. Execution of ./maketest.pl aborted due to compilation errors.
The Perl package on this RHEL5 machine is perl-5.8.8-32.el5_5.1. Why does only the last line fail, and any ideas how to work around this?

Update: Added -w for warnings and added forgotten parentheses to repeat string.

Replies are listed 'Best First'.
Re: Match operator fails for elements 100 and higher
by Crackers2 (Parson) on Nov 03, 2010 at 21:07 UTC
    Interestingly, things start working again at 999. i.e.
    m/$mystrings[998]/; # Fails m/$mystrings[999]/; # Works m/$mystrings[1000]/; # Works
    Deparse shows it's indeed parsed differently, but doesn't show why:
    > perl -MO=Deparse x Global symbol "$mystrings" requires explicit package name at x line 10 +. x had compilation errors. use strict 'refs'; my(@mystrings) = 'string' x 200; $mystrings[99]; "$mystrings[100]"; /$mystrings[999]/; /${'mystrings'}[998]/;

    Update: These values also work: 111, 222, 333, 444, 555, 666, 777, 888. And apparently above 1000 it's not simple either. The first working ones after 1000 are: 1110, 1111, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1131, 1141, 1151, 1161, 1171, 1181, 1191, 1311, 1333, 1411

    Overall, there's 393 values from 0 to 10,000 for which it works. The rest fail.

      I found a work-around, just use a different array to index the string array instead of using numbers:
      my @mystrings = ("string") x 200; my @i = 0..$#mystrings; m/$mystrings[$i[100]]/;
      Thanks for your help. Should I report this issue?

        Simpler workaround (or maybe it's the right thing to do in the first place) is this:

        m/${mystrings[100]}/;
Re: Match operator fails for elements 100 and higher
by toolic (Bishop) on Nov 03, 2010 at 20:54 UTC
    Turn on warnings.

    Your array only has 1 element:

    my @mystrings = "string" x 200; print 'size=', scalar @mystrings, "\n"; # size=1

    I don't know why the 1st regex does not produce an error, where the 2nd one does. But, maybe if you fix the warnings, you will get what you are looking for.

      This doesn't seem to be the issue, as the same error occurs after you fix it (my @strings = ("string") x 200;).
Re: Match operator fails for elements 100 and higher
by liverpole (Monsignor) on Nov 03, 2010 at 22:51 UTC
    With a nod to Crackers2 above, who pointed out perl -MO=Deparse, here is a sort of "meta" program, which tries 'deparsing' ...
    my $check = m/$mystrings[N]/;

    ... on incrementing values of N:

    #! /usr/bin/perl -w ############### ## Libraries ## ############### use strict; use warnings; use File::Basename; use B::Deparse; use IO::File; ############# ## Globals ## ############# my $iam = basename $0; $| = 1; my $b_verbose = 0; my $text = q{ use strict; use warnings; my @mystrings = ( "string" ) x 200; my $check = m/$mystrings[<NUM>]/; }; ################## ## Main Program ## ################## for (my $i = 0; $i <= 1000; $i++) { try($i); } ################# ## Subroutines ## ################# sub try { my ($n) = @_; my $new = $text; $new =~ s/<NUM>/$n/g; my $fn = 'test.pl'; my $fh = new IO::File($fn, "w") or die "Can't write '$fn' ($!)\n"; print $fh "$new\n"; close $fh; chomp(my @results = `perl -MO=Deparse $fn 2>&1`); my ($check) = grep { /check/ } @results; my $b_ok = ($check =~ /my \$check = \$mystrings\[\d+\]/)? 1: 0; if ($b_verbose) { printf "Value %4d => %s\n", $n, $b_ok? "Okay": "*** FAILS ***" +; } else { printf "%s", $b_ok? '.': '@'; } }

    It prints '.' or '@' for "Okay" and "Failed" values of N, respectively.

    You can also assign $b_verbose to a nonzero value to see more verbose results :)


    s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/
Re: Match operator fails for elements 100 and higher
by AnomalousMonk (Chancellor) on Nov 04, 2010 at 02:14 UTC

    Results (consistent with other reports) for ActiveState 5.8.9-827 and Strawberries 5.10.1.0 and 5.12.0.1 under Windows 7:

    >perl -wMstrict -le "my @mystrings = ('string') x 10_000; ;; my %evaled; for my $i (0 .. $#mystrings) { eval qq{ qr{\$mystrings[$i]} }; $evaled{$i} = $@; } ;; my $ok =()= grep !$_, values %evaled; printf qq{ok == %4d \n}, $ok; my $bad =()= grep $_ && /Global symbol \"\$mystrings\" requires explicit package name/ +, values %evaled ; printf qq{bad == %4d \n}, $bad; " ok == 392 bad == 9608
Re: Match operator fails for elements 100 and higher
by aquarium (Curate) on Nov 03, 2010 at 21:56 UTC
    if the code is in the exact sequence as you put it, then the matches implicitly test against $_ (i think) which would be assigned in each previous statement. and as these matches are bare (used as LValue), with the result not being assigned to anything, the outcome of matching each array element content against $_ is converted to a scalar or possibly even boolean. the second test, where you have no "m" in front of the quoted string becomes the value of the string.
    the hardest line to type correctly is: stty erase ^H

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://869313]
Approved by toolic
help
Chatterbox?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others lurking in the Monastery: (4)
As of 2018-02-20 19:59 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    When it is dark outside I am happiest to see ...














    Results (274 votes). Check out past polls.

    Notices?