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.
| [reply] [d/l] [select] |
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? | [reply] [d/l] |
m/${mystrings[100]}/;
| [reply] [d/l] |
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.
| [reply] [d/l] |
This doesn't seem to be the issue, as the same error occurs after you fix it (my @strings = ("string") x 200;).
| [reply] [d/l] |
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$..$/
| [reply] [d/l] [select] |
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
| [reply] [d/l] |
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
| [reply] |