Closed p5pRT closed 20 years ago
Hello\,
I have discovered what I belive is a bug in Perl version 5.6.1. At least\, the behavior is bizarre enough that I would appreciate knowing if this is supposed to be a feature.
The problem seems to lie in regexps with multi-line matching. I've written a small perl program (included) which demonstrates the bug and it can be reproduced. I have tried this on two different machines (x86 Solaris 8 & x86 Linux 2.4.4) with the same results.
The situation occurs when using /o in a regexp. Specifically I am using /mos\, and the bug does not show up if I change the regexp to /ms. My understanding is /o means 'compile pattern once'. But since I am doing this in a subroutine\, I was expecting the regexp to go out of scope when the subroutine ended.
What happens in test #2 is almost certainly a bug since I am passing in two different strings and the second string is being modified in a place where the first string had been changed. I think it's probably easier just to show an example output:
============BEGIN TEST 1 ============ ModifyX(): replace 'brown' with 'purple'
BEFORE: The quick brown fox jumps over the lazy dawg
AFTER: The quick purple fox jumps over the lazy dawg
====END ModifyX()====
ModifyX(): replace 'over' with 'into'
BEFORE: The quick purple fox jumps over the lazy dawg
AFTER: The quick purple fox jumps over the lazy dawg
====END ModifyX()====
============BEGIN TEST 2 ============
===Replace 'brown' with 'purple'===
BEFORE: The quick brown fox jumps over the lazy dawg
AFTER: The quick purple fox jumps over the lazy dawg
==END ModAnyString()==
===Replace 'over' with 'into'===
BEFORE: The quick brown fox jumps over the lazy dawg
AFTER: The quick into fox jumps over the lazy dawg
==END ModAnyString()==
What follows is the program I wrote to do this test\, an output from running 'perl -Dr' to show the pattern matching\, and the obligatory dump as requested from 'perlbug'.
Thank you\,
Stuart Lory Zurich Switzerland
#!/usr/bin/perl
$X=$Y=$Z="The quick\nbrown fox jumps\nover the\nlazy dawg\n";
test1(); test2();
sub test1 { print "============BEGIN TEST 1 ============\n"; ModifyX('brown'\,'purple'); ModifyX('over'\,'into'); } sub test2 { print "============BEGIN TEST 2 ============\n"; ModAnyString($Y\,'brown'\,'purple'); ModAnyString($Z\,'over' \,'into' ); } sub ModifyX { # # specifically modifies $X # my ($old\,$new)=@_; print "ModifyX(): replace '$old' with '$new'\n\n"; print "BEFORE: $X"; $X=~s/\A(.+)$old/\1$new/mos; print "\nAFTER: $X\n====END ModifyX()====\n\n"; } sub ModAnyString { # # modifies first string in @_ # my ($target\,$old\,$new)=@_; print "\n===Replace '$old' with '$new'===\n\n"; print "BEFORE: $target"; $target=~s/\A(.+)$old/\1$new/mos; print "\nAFTER: $target\n==END ModAnyString()==\n\n"; }
Script started on Wed 25 Jul 2001 03:41:33 AM MEST $ perl -Dr bug.pl Omitting $` $& $' support.
EXECUTING...
============BEGIN TEST 1 ============ ModifyX(): replace 'brown' with 'purple'
BEFORE: The quick
brown fox jumps
over the
lazy dawg
Compiling REx `\A(.+)brown'
size 11 first at 2
rarest char w at 3
1: SBOL(2)
2: OPEN1(4)
4: PLUS(6)
5: SANY(0)
6: CLOSE1(8)
8: EXACT \
\<> | 6: CLOSE1 45 \<e lazy dawg \<> | 8: EXACT \
failed... 44 \<e lazy dawg> \< | 6: CLOSE1 44 \<e lazy dawg> \< | 8: EXACT \ failed... 43 \<e lazy daw> \<g | 6: CLOSE1 43 \<e lazy daw> \<g | 8: EXACT \ failed... 42 \<e lazy da> \<wg | 6: CLOSE1 42 \<e lazy da> \<wg | 8: EXACT \ failed... 41 \<e lazy d> \<awg | 6: CLOSE1 41 \<e lazy d> \<awg | 8: EXACT \ failed... 40 \<e lazy > \<dawg | 6: CLOSE1 40 \<e lazy > \<dawg | 8: EXACT \ failed... 39 \<e lazy> \< dawg | 6: CLOSE1 39 \<e lazy> \< dawg | 8: EXACT \ failed... 38 \<e laz> \<y dawg | 6: CLOSE1 38 \<e laz> \<y dawg | 8: EXACT \ failed... 37 \<he la> \ | 6: CLOSE1 37 \<he la> \ | 8: EXACT \ failed... 36 \<the l> \ | 6: CLOSE1 36 \<the l> \ | 8: EXACT \ failed... 35 \< the \ | 6: CLOSE1 35 \< the \ | 8: EXACT \ failed... 34 \ \< lazy d> | 6: CLOSE1 34 \ \< lazy d> | 8: EXACT \ failed... 33 \ \<e lazy > | 6: CLOSE1 33 \ \<e lazy > | 8: EXACT \ failed... 32 \ \<he lazy> | 6: CLOSE1 32 \ \<he lazy> | 8: EXACT \ failed... 31 \ \<the laz> | 6: CLOSE1 31 \ \<the laz> | 8: EXACT \ failed... 30 \< over> \< the la> | 6: CLOSE1 30 \< over> \< the la> | 8: EXACT \ failed... 29 \<s ove> \<r the l> | 6: CLOSE1 29 \<s ove> \<r the l> | 8: EXACT \ failed... 28 \<ps ov> \<er the | 6: CLOSE1 28 \<ps ov> \<er the | 8: EXACT \ failed... 27 \<mps o> \ | 6: CLOSE1 27 \<mps o> \ | 8: EXACT \ failed... 26 \<umps \ | 6: CLOSE1 26 \<umps \ | 8: EXACT \ failed... 25 \ \< over t> | 6: CLOSE1 25 \ \< over t> | 8: EXACT \ failed... 24 \< jump> \<s over > | 6: CLOSE1 24 \< jump> \<s over > | 8: EXACT \ failed... 23 \ \<ps over> | 6: CLOSE1 23 \ \<ps over> | 8: EXACT \ failed... 22 \ \<mps ove> | 6: CLOSE1 22 \ \<mps ove> | 8: EXACT \ failed... 21 \ \<umps ov> | 6: CLOSE1 21 \ \<umps ov> | 8: EXACT \ failed... 20 \< fox > \<jumps o> | 6: CLOSE1 20 \< fox > \<jumps o> | 8: EXACT \ failed... 19 \ \< jumps | 6: CLOSE1 19 \ \< jumps | 8: EXACT \ failed... 18 \ \ | 6: CLOSE1 18 \ \ | 8: EXACT \ failed... 17 \ \ | 6: CLOSE1 17 \ \ | 8: EXACT \ failed... 16 \ \ | 6: CLOSE1 16 \ \ | 8: EXACT \ failed... 15 \ \< fox ju> | 6: CLOSE1 15 \ \< fox ju> | 8: EXACT \ failed... 14 \< brow> \ | 6: CLOSE1 14 \< brow> \ | 8: EXACT \ failed... 13 \<k bro> \ | 6: CLOSE1 13 \<k bro> \ | 8: EXACT \ failed... 12 \<ck br> \ | 6: CLOSE1 12 \<ck br> \ | 8: EXACT \ failed... 11 \<ick b> \ | 6: CLOSE1 11 \<ick b> \ | 8: EXACT \ failed... 10 \<uick \ | 6: CLOSE1 10 \<uick \ | 8: EXACT \ 15 \ \< fox ju> | 11: END Match successful!
AFTER: The quick purple fox jumps over the lazy dawg
====END ModifyX()====
ModifyX(): replace 'over' with 'into'
BEFORE: The quick purple fox jumps over the lazy dawg Guessing start of match\, REx `\A(.+)brown' against `The quick purple fox jumps over the lazy dawg '... Did not find floating substr `brown'... Match rejected by optimizer
AFTER: The quick purple fox jumps over the lazy dawg
====END ModifyX()====
============BEGIN TEST 2 ============
===Replace 'brown' with 'purple'===
BEFORE: The quick
brown fox jumps
over the
lazy dawg
Compiling REx `\A(.+)brown'
size 11 first at 2
rarest char w at 3
1: SBOL(2)
2: OPEN1(4)
4: PLUS(6)
5: SANY(0)
6: CLOSE1(8)
8: EXACT \
\<> | 6: CLOSE1 45 \<e lazy dawg \<> | 8: EXACT \
failed... 44 \<e lazy dawg> \< | 6: CLOSE1 44 \<e lazy dawg> \< | 8: EXACT \ failed... 43 \<e lazy daw> \<g | 6: CLOSE1 43 \<e lazy daw> \<g | 8: EXACT \ failed... 42 \<e lazy da> \<wg | 6: CLOSE1 42 \<e lazy da> \<wg | 8: EXACT \ failed... 41 \<e lazy d> \<awg | 6: CLOSE1 41 \<e lazy d> \<awg | 8: EXACT \ failed... 40 \<e lazy > \<dawg | 6: CLOSE1 40 \<e lazy > \<dawg | 8: EXACT \ failed... 39 \<e lazy> \< dawg | 6: CLOSE1 39 \<e lazy> \< dawg | 8: EXACT \ failed... 38 \<e laz> \<y dawg | 6: CLOSE1 38 \<e laz> \<y dawg | 8: EXACT \ failed... 37 \<he la> \ | 6: CLOSE1 37 \<he la> \ | 8: EXACT \ failed... 36 \<the l> \ | 6: CLOSE1 36 \<the l> \ | 8: EXACT \ failed... 35 \< the \ | 6: CLOSE1 35 \< the \ | 8: EXACT \ failed... 34 \ \< lazy d> | 6: CLOSE1 34 \ \< lazy d> | 8: EXACT \ failed... 33 \ \<e lazy > | 6: CLOSE1 33 \ \<e lazy > | 8: EXACT \ failed... 32 \ \<he lazy> | 6: CLOSE1 32 \ \<he lazy> | 8: EXACT \ failed... 31 \ \<the laz> | 6: CLOSE1 31 \ \<the laz> | 8: EXACT \ failed... 30 \< over> \< the la> | 6: CLOSE1 30 \< over> \< the la> | 8: EXACT \ failed... 29 \<s ove> \<r the l> | 6: CLOSE1 29 \<s ove> \<r the l> | 8: EXACT \ failed... 28 \<ps ov> \<er the | 6: CLOSE1 28 \<ps ov> \<er the | 8: EXACT \ failed... 27 \<mps o> \ | 6: CLOSE1 27 \<mps o> \ | 8: EXACT \ failed... 26 \<umps \ | 6: CLOSE1 26 \<umps \ | 8: EXACT \ failed... 25 \ \< over t> | 6: CLOSE1 25 \ \< over t> | 8: EXACT \ failed... 24 \< jump> \<s over > | 6: CLOSE1 24 \< jump> \<s over > | 8: EXACT \ failed... 23 \ \<ps over> | 6: CLOSE1 23 \ \<ps over> | 8: EXACT \ failed... 22 \ \<mps ove> | 6: CLOSE1 22 \ \<mps ove> | 8: EXACT \ failed... 21 \ \<umps ov> | 6: CLOSE1 21 \ \<umps ov> | 8: EXACT \ failed... 20 \< fox > \<jumps o> | 6: CLOSE1 20 \< fox > \<jumps o> | 8: EXACT \ failed... 19 \ \< jumps | 6: CLOSE1 19 \ \< jumps | 8: EXACT \ failed... 18 \ \ | 6: CLOSE1 18 \ \ | 8: EXACT \ failed... 17 \ \ | 6: CLOSE1 17 \ \ | 8: EXACT \ failed... 16 \ \ | 6: CLOSE1 16 \ \ | 8: EXACT \ failed... 15 \ \< fox ju> | 6: CLOSE1 15 \ \< fox ju> | 8: EXACT \ failed... 14 \< brow> \ | 6: CLOSE1 14 \< brow> \ | 8: EXACT \ failed... 13 \<k bro> \ | 6: CLOSE1 13 \<k bro> \ | 8: EXACT \ failed... 12 \<ck br> \ | 6: CLOSE1 12 \<ck br> \ | 8: EXACT \ failed... 11 \<ick b> \ | 6: CLOSE1 11 \<ick b> \ | 8: EXACT \ failed... 10 \<uick \ | 6: CLOSE1 10 \<uick \ | 8: EXACT \ 15 \ \< fox ju> | 11: END Match successful!
AFTER: The quick purple fox jumps over the lazy dawg
==END ModAnyString()==
===Replace 'over' with 'into'===
BEFORE: The quick brown fox jumps over the lazy dawg Guessing start of match\, REx `\A(.+)brown' against `The quick brown fox jumps over the lazy dawg '... Found floating substr `brown' at offset 10... Guessed: match at offset 0 Matching REx `\A(.+)brown' against `The quick brown fox jumps over the lazy dawg ' Setting an EVAL scope\, savestack=24 0 \<> \<The quick br> | 1: SBOL 0 \<> \<The quick br> | 2: OPEN1 0 \<> \<The quick br> | 4: PLUS SANY can match 45 times out of 32767... Setting an EVAL scope\, savestack=24 45 \<e lazy dawg
\<> | 6: CLOSE1 45 \<e lazy dawg \<> | 8: EXACT \
failed... 44 \<e lazy dawg> \< | 6: CLOSE1 44 \<e lazy dawg> \< | 8: EXACT \ failed... 43 \<e lazy daw> \<g | 6: CLOSE1 43 \<e lazy daw> \<g | 8: EXACT \ failed... 42 \<e lazy da> \<wg | 6: CLOSE1 42 \<e lazy da> \<wg | 8: EXACT \ failed... 41 \<e lazy d> \<awg | 6: CLOSE1 41 \<e lazy d> \<awg | 8: EXACT \ failed... 40 \<e lazy > \<dawg | 6: CLOSE1 40 \<e lazy > \<dawg | 8: EXACT \ failed... 39 \<e lazy> \< dawg | 6: CLOSE1 39 \<e lazy> \< dawg | 8: EXACT \ failed... 38 \<e laz> \<y dawg | 6: CLOSE1 38 \<e laz> \<y dawg | 8: EXACT \ failed... 37 \<he la> \ | 6: CLOSE1 37 \<he la> \ | 8: EXACT \ failed... 36 \<the l> \ | 6: CLOSE1 36 \<the l> \ | 8: EXACT \ failed... 35 \< the \ | 6: CLOSE1 35 \< the \ | 8: EXACT \ failed... 34 \ \< lazy d> | 6: CLOSE1 34 \ \< lazy d> | 8: EXACT \ failed... 33 \ \<e lazy > | 6: CLOSE1 33 \ \<e lazy > | 8: EXACT \ failed... 32 \ \<he lazy> | 6: CLOSE1 32 \ \<he lazy> | 8: EXACT \ failed... 31 \ \<the laz> | 6: CLOSE1 31 \ \<the laz> | 8: EXACT \ failed... 30 \< over> \< the la> | 6: CLOSE1 30 \< over> \< the la> | 8: EXACT \ failed... 29 \<s ove> \<r the l> | 6: CLOSE1 29 \<s ove> \<r the l> | 8: EXACT \ failed... 28 \<ps ov> \<er the | 6: CLOSE1 28 \<ps ov> \<er the | 8: EXACT \ failed... 27 \<mps o> \ | 6: CLOSE1 27 \<mps o> \ | 8: EXACT \ failed... 26 \<umps \ | 6: CLOSE1 26 \<umps \ | 8: EXACT \ failed... 25 \ \< over t> | 6: CLOSE1 25 \ \< over t> | 8: EXACT \ failed... 24 \< jump> \<s over > | 6: CLOSE1 24 \< jump> \<s over > | 8: EXACT \ failed... 23 \ \<ps over> | 6: CLOSE1 23 \ \<ps over> | 8: EXACT \ failed... 22 \ \<mps ove> | 6: CLOSE1 22 \ \<mps ove> | 8: EXACT \ failed... 21 \ \<umps ov> | 6: CLOSE1 21 \ \<umps ov> | 8: EXACT \ failed... 20 \< fox > \<jumps o> | 6: CLOSE1 20 \< fox > \<jumps o> | 8: EXACT \ failed... 19 \ \< jumps | 6: CLOSE1 19 \ \< jumps | 8: EXACT \ failed... 18 \ \ | 6: CLOSE1 18 \ \ | 8: EXACT \ failed... 17 \ \ | 6: CLOSE1 17 \ \ | 8: EXACT \ failed... 16 \ \ | 6: CLOSE1 16 \ \ | 8: EXACT \ failed... 15 \ \< fox ju> | 6: CLOSE1 15 \ \< fox ju> | 8: EXACT \ failed... 14 \< brow> \ | 6: CLOSE1 14 \< brow> \ | 8: EXACT \ failed... 13 \<k bro> \ | 6: CLOSE1 13 \<k bro> \ | 8: EXACT \ failed... 12 \<ck br> \ | 6: CLOSE1 12 \<ck br> \ | 8: EXACT \ failed... 11 \<ick b> \ | 6: CLOSE1 11 \<ick b> \ | 8: EXACT \ failed... 10 \<uick \ | 6: CLOSE1 10 \<uick \ | 8: EXACT \ 15 \ \< fox ju> | 11: END Match successful!
AFTER: The quick into fox jumps over the lazy dawg
==END ModAnyString()==
$ exit script done on Wed 25 Jul 2001 03:41:41 AM MEST
Flags: category= severity=
Site configuration information for perl v5.6.1:
Configured by stuart at Sun Jul 22 02:48:43 MEST 2001.
Summary of my perl5 (revision 5.0 version 6 subversion 1) configuration: Platform: osname=solaris\, osvers=2.8\, archname=i86pc-solaris uname='sunos oryx 5.8 generic_108529-05 i86pc i386 i86pc ' config_args='-Dcc=gcc' hint=recommended\, useposix=true\, d_sigaction=define usethreads=undef use5005threads=undef useithreads=undef usemultiplicity=undef useperlio=undef d_sfio=undef uselargefiles=define usesocks=undef use64bitint=undef use64bitall=undef uselongdouble=undef Compiler: cc='gcc'\, ccflags ='-DDEBUGGING -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64'\, optimize='-O'\, cppflags='-DDEBUGGING' ccversion=''\, gccversion='2.95.2 19991024 (release)'\, gccosandvers='solaris2.8' intsize=4\, longsize=4\, ptrsize=4\, doublesize=8\, byteorder=1234 d_longlong=define\, longlongsize=8\, d_longdbl=define\, longdblsize=12 ivtype='long'\, ivsize=4\, nvtype='double'\, nvsize=8\, Off_t='off_t'\, lseeksize=8 alignbytes=4\, usemymalloc=y\, prototype=define Linker and Libraries: ld='gcc'\, ldflags =' -L/usr/local/lib ' libpth=/usr/local/lib /usr/lib /usr/ccs/lib libs=-lsocket -lnsl -ldl -lm -lc perllibs=-lsocket -lnsl -ldl -lm -lc libc=/lib/libc.so\, so=so\, useshrplib=false\, libperl=libperl.a Dynamic Linking: dlsrc=dl_dlopen.xs\, dlext=so\, d_dlsymun=undef\, ccdlflags=' ' cccdlflags='-fPIC'\, lddlflags='-G -L/usr/local/lib'
Locally applied patches:
@INC for perl v5.6.1: /usr/local/lib/perl5/5.6.1/i86pc-solaris /usr/local/lib/perl5/5.6.1 /usr/local/lib/perl5/site_perl/5.6.1/i86pc-solaris /usr/local/lib/perl5/site_perl/5.6.1 /usr/local/lib/perl5/site_perl .
Environment for perl v5.6.1:
HOME=/home/stuart
LANG=en_US.ISO8859-1
LANGUAGE (unset)
LC_COLLATE=en_US.ISO8859-1
LC_CTYPE=en_US.ISO8859-1
LC_MESSAGES=C
LC_MONETARY=en_US.ISO8859-1
LC_NUMERIC=en_US.ISO8859-1
LC_TIME=en_US.ISO8859-1
LD_LIBRARY_PATH (unset)
LOGDIR (unset)
PATH=/usr/samba/bin:/opt/sfw/gnome/bin:/usr/j2se/bin:/opt/SUNWspro/bin:/usr/ccs/bin:/opt/sfw/bin:/sbin:/usr/sbin:/usr/bin:/usr/dt/bin:/usr/openwin/bin:/bin:/usr/ucb:/usr/local/bin:.
PERL_BADLANG (unset)
SHELL=/bin/ksh
Complete configuration data for perl v5.6.1:
Author='' CONFIG='true' CONFIGDOTSH='true' Date='$Date' Header='' Id='$Id' Locker='' Log='$Log' Mcc='Mcc' PATCHLEVEL='6' PERL_API_REVISION='5' PERL_API_SUBVERSION='0' PERL_API_VERSION='5' PERL_REVISION='5' PERL_SUBVERSION='1' PERL_VERSION='6' RCSfile='$RCSfile' Revision='$Revision' SUBVERSION='1' Source='' State='' _a='.a' _exe='' _o='.o' afs='false' alignbytes='4' ansi2knr='' aphostname='/usr/bin/hostname' api_revision='5' api_subversion='0' api_version='5' api_versionstring='5.005' ar='ar' archlib='/usr/local/lib/perl5/5.6.1/i86pc-solaris' archlibexp='/usr/local/lib/perl5/5.6.1/i86pc-solaris' archname='i86pc-solaris' archname64='' archobjs='' awk='awk' baserev='5.0' bash='' bin='/usr/local/bin' bincompat5005='define' binexp='/usr/local/bin' bison='bison' byacc='byacc' byteorder='1234' c='\c' castflags='0' cat='cat' cc='gcc' cccdlflags='-fPIC' ccdlflags=' ' ccflags='-DDEBUGGING -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64' ccflags_uselargefiles='-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64' ccname='gcc' ccsymbols='__GNUC__=2 __GNUC_MINOR__=95 __i386=1 __i386__=1 __sun=1 __sun__=1 __SVR4=1 __svr4__=1 __unix=1 __unix__=1 cpu=i386 machine=i386 system=svr4' ccversion='' cf_by='stuart' cf_email='stuart@oryx.onyx.ch' cf_time='Sun Jul 22 02:48:43 MEST 2001' charsize='1' chgrp='' chmod='' chown='' clocktype='clock_t' comm='comm' compress='' config_arg0='Configure' config_arg1='-Dcc=gcc' config_argc='1' config_args='-Dcc=gcc' contains='grep' cp='cp' cpio='' cpp='cpp' cpp_stuff='42' cppccsymbols='i386=1 sun=1 unix=1' cppflags='-DDEBUGGING' cpplast='-' cppminus='-' cpprun='gcc -E' cppstdin='gcc -E' cppsymbols='_FILE_OFFSET_BITS=64 __GNUC__=2 __GNUC_MINOR__=95 __i386=1 __i386__=1 _ILP32=1 _LARGEFILE64_SOURCE=1 _LARGEFILE_SOURCE=1 _LITTLE_ENDIAN=1 __STDC__=1 __sun=1 __sun__=1 __SVR4=1 __svr4__=1 __unix=1 __unix__=1' crosscompile='' cryptlib='' csh='csh' d_Gconvert='gconvert((x)\,(n)\,(t)\,(b))' d_PRIEUldbl='define' d_PRIFUldbl='define' d_PRIGUldbl='define' d_PRIXU64='define' d_PRId64='define' d_PRIeldbl='define' d_PRIfldbl='define' d_PRIgldbl='define' d_PRIi64='define' d_PRIo64='define' d_PRIu64='define' d_PRIx64='define' d_SCNfldbl='define' d__fwalk='' d_access='define' d_accessx='' d_alarm='define' d_archlib='define' d_atolf='' d_atoll='define' d_attribut='define' d_bcmp='define' d_bcopy='define' d_bincompat5005='define' d_bsd='' d_bsdgetpgrp='' d_bsdsetpgrp='' d_bzero='define' d_casti32='' d_castneg='define' d_charvspr='' d_chown='define' d_chroot='define' d_chsize='' d_closedir='define' d_const='define' d_crypt='define' d_csh='define' d_cuserid='define' d_dbl_dig='define' d_difftime='define' d_dirnamlen='' d_dlerror='define' d_dlopen='define' d_dlsymun='' d_dosuid='' d_drand48proto='define' d_dup2='define' d_eaccess='' d_endgrent='define' d_endhent='define' d_endnent='define' d_endpent='define' d_endpwent='define' d_endsent='define' d_eofnblk='define' d_eunice='' d_fchmod='define' d_fchown='define' d_fcntl='define' d_fcntl_can_lock='define' d_fd_macros='define' d_fd_set='define' d_fds_bits='define' d_fgetpos='define' d_flexfnam='define' d_flock='' d_fork='define' d_fpathconf='define' d_fpos64_t='define' d_frexpl='' d_fs_data_s='' d_fseeko='define' d_fsetpos='define' d_fstatfs='define' d_fstatvfs='define' d_fsync='define' d_ftello='define' d_ftime='' d_getcwd='define' d_getespwnam='' d_getfsstat='' d_getgrent='define' d_getgrps='define' d_gethbyaddr='define' d_gethbyname='define' d_gethent='define' d_gethname='define' d_gethostprotos='define' d_getlogin='define' d_getmnt='' d_getmntent='define' d_getnbyaddr='define' d_getnbyname='define' d_getnent='define' d_getnetprotos='define' d_getpagsz='define' d_getpbyname='define' d_getpbynumber='define' d_getpent='define' d_getpgid='define' d_getpgrp='define' d_getpgrp2='' d_getppid='define' d_getprior='define' d_getprotoprotos='define' d_getprpwnam='' d_getpwent='define' d_getsbyname='define' d_getsbyport='define' d_getsent='define' d_getservprotos='define' d_getspnam='define' d_gettimeod='define' d_gnulibc='' d_grpasswd='define' d_hasmntopt='define' d_htonl='define' d_iconv='define' d_index='' d_inetaton='' d_int64_t='define' d_isascii='define' d_isnan='define' d_isnanl='' d_killpg='define' d_lchown='define' d_ldbl_dig='define' d_link='define' d_locconv='define' d_lockf='define' d_longdbl='define' d_longlong='define' d_lseekproto='define' d_lstat='define' d_madvise='define' d_mblen='define' d_mbstowcs='define' d_mbtowc='define' d_memchr='define' d_memcmp='define' d_memcpy='define' d_memmove='define' d_memset='define' d_mkdir='define' d_mkdtemp='' d_mkfifo='define' d_mkstemp='define' d_mkstemps='' d_mktime='define' d_mmap='define' d_modfl='' d_mprotect='define' d_msg='define' d_msg_ctrunc='define' d_msg_dontroute='define' d_msg_oob='define' d_msg_peek='define' d_msg_proxy='' d_msgctl='define' d_msgget='define' d_msgrcv='define' d_msgsnd='define' d_msync='define' d_munmap='define' d_mymalloc='define' d_nice='define' d_nv_preserves_uv='define' d_nv_preserves_uv_bits='32' d_off64_t='define' d_old_pthread_create_joinable='' d_oldpthreads='' d_oldsock='' d_open3='define' d_pathconf='define' d_pause='define' d_perl_otherlibdirs='' d_phostname='' d_pipe='define' d_poll='define' d_portable='define' d_pthread_yield='' d_pwage='define' d_pwchange='' d_pwclass='' d_pwcomment='define' d_pwexpire='' d_pwgecos='define' d_pwpasswd='define' d_pwquota='' d_qgcvt='define' d_quad='define' d_readdir='define' d_readlink='define' d_rename='define' d_rewinddir='define' d_rmdir='define' d_safebcpy='define' d_safemcpy='' d_sanemcmp='define' d_sbrkproto='define' d_sched_yield='' d_scm_rights='define' d_seekdir='define' d_select='define' d_sem='define' d_semctl='define' d_semctl_semid_ds='define' d_semctl_semun='define' d_semget='define' d_semop='define' d_setegid='define' d_seteuid='define' d_setgrent='define' d_setgrps='define' d_sethent='define' d_setlinebuf='define' d_setlocale='define' d_setnent='define' d_setpent='define' d_setpgid='define' d_setpgrp='define' d_setpgrp2='' d_setprior='define' d_setproctitle='' d_setpwent='define' d_setregid='define' d_setresgid='' d_setresuid='' d_setreuid='define' d_setrgid='' d_setruid='' d_setsent='define' d_setsid='define' d_setvbuf='define' d_sfio='' d_shm='define' d_shmat='define' d_shmatprototype='define' d_shmctl='define' d_shmdt='define' d_shmget='define' d_sigaction='define' d_sigsetjmp='define' d_socket='define' d_socklen_t='define' d_sockpair='define' d_socks5_init='' d_sqrtl='' d_statblks='define' d_statfs_f_flags='' d_statfs_s='define' d_statvfs='define' d_stdio_cnt_lval='define' d_stdio_ptr_lval='define' d_stdio_ptr_lval_nochange_cnt='define' d_stdio_ptr_lval_sets_cnt='' d_stdio_stream_array='define' d_stdiobase='define' d_stdstdio='define' d_strchr='define' d_strcoll='define' d_strctcpy='define' d_strerrm='strerror(e)' d_strerror='define' d_strtod='define' d_strtol='define' d_strtold='' d_strtoll='define' d_strtoul='define' d_strtoull='define' d_strtouq='' d_strxfrm='define' d_suidsafe='define' d_symlink='define' d_syscall='define' d_sysconf='define' d_sysernlst='' d_syserrlst='define' d_system='define' d_tcgetpgrp='define' d_tcsetpgrp='define' d_telldir='define' d_telldirproto='define' d_time='define' d_times='define' d_truncate='define' d_tzname='define' d_umask='define' d_uname='define' d_union_semun='' d_ustat='define' d_vendorarch='' d_vendorbin='' d_vendorlib='' d_vfork='' d_void_closedir='' d_voidsig='define' d_voidtty='' d_volatile='define' d_vprintf='define' d_wait4='define' d_waitpid='define' d_wcstombs='define' d_wctomb='define' d_xenix='' date='date' db_hashtype='u_int32_t' db_prefixtype='size_t' defvoidused='15' direntrytype='struct dirent' dlext='so' dlsrc='dl_dlopen.xs' doublesize='8' drand01='drand48()' dynamic_ext='B ByteLoader Data/Dumper Devel/DProf Devel/Peek Fcntl File/Glob IO IPC/SysV NDBM_File ODBM_File Opcode POSIX SDBM_File Socket Sys/Hostname Sys/Syslog attrs re' eagain='EAGAIN' ebcdic='' echo='echo' egrep='egrep' emacs='' eunicefix=':' exe_ext='' expr='expr' extensions='B ByteLoader Data/Dumper Devel/DProf Devel/Peek Fcntl File/Glob IO IPC/SysV NDBM_File ODBM_File Opcode POSIX SDBM_File Socket Sys/Hostname Sys/Syslog attrs re Errno' fflushNULL='' fflushall='' find='' firstmakefile='makefile' flex='' fpossize='8' fpostype='fpos_t' freetype='void' full_ar='/usr/ccs/bin/ar' full_csh='/usr/bin/csh' full_sed='/usr/bin/sed' gccosandvers='solaris2.8' gccversion='2.95.2 19991024 (release)' gidformat='"ld"' gidsign='-1' gidsize='4' gidtype='gid_t' glibpth='/usr/shlib /usr/lib /usr/lib/386 /lib/386 /usr/ccs/lib /usr/local/lib' grep='grep' groupcat='cat /etc/group' groupstype='gid_t' gzip='gzip' h_fcntl='true' h_sysfile='false' hint='recommended' hostcat='cat /etc/hosts' i16size='2' i16type='short' i32size='4' i32type='long' i64size='8' i64type='long long' i8size='1' i8type='char' i_arpainet='define' i_bsdioctl='' i_db='' i_dbm='' i_dirent='define' i_dld='' i_dlfcn='define' i_fcntl='define' i_float='define' i_gdbm='' i_grp='define' i_iconv='define' i_ieeefp='define' i_inttypes='define' i_libutil='' i_limits='define' i_locale='define' i_machcthr='' i_malloc='define' i_math='define' i_memory='' i_mntent='' i_ndbm='define' i_netdb='define' i_neterrno='' i_netinettcp='define' i_niin='define' i_poll='define' i_prot='' i_pthread='define' i_pwd='define' i_rpcsvcdbm='define' i_sfio='' i_sgtty='' i_shadow='define' i_socks='' i_stdarg='define' i_stddef='define' i_stdlib='define' i_string='define' i_sunmath='' i_sysaccess='' i_sysdir='' i_sysfile='' i_sysfilio='define' i_sysin='' i_sysioctl='define' i_syslog='define' i_sysmman='define' i_sysmode='define' i_sysmount='define' i_sysndir='' i_sysparam='define' i_sysresrc='define' i_syssecrt='' i_sysselct='define' i_syssockio='' i_sysstat='define' i_sysstatfs='define' i_sysstatvfs='define' i_systime='define' i_systimek='' i_systimes='define' i_systypes='define' i_sysuio='define' i_sysun='define' i_sysutsname='define' i_sysvfs='define' i_syswait='define' i_termio='' i_termios='define' i_time='' i_unistd='define' i_ustat='define' i_utime='define' i_values='define' i_varargs='' i_varhdr='stdarg.h' i_vfork='' ignore_versioned_solibs='' inc_version_list=' ' inc_version_list_init='0' incpath='' inews='' installarchlib='/usr/local/lib/perl5/5.6.1/i86pc-solaris' installbin='/usr/local/bin' installman1dir='/usr/local/man/man1' installman3dir='/usr/local/man/man3' installprefix='/usr/local' installprefixexp='/usr/local' installprivlib='/usr/local/lib/perl5/5.6.1' installscript='/usr/local/bin' installsitearch='/usr/local/lib/perl5/site_perl/5.6.1/i86pc-solaris' installsitebin='/usr/local/bin' installsitelib='/usr/local/lib/perl5/site_perl/5.6.1' installstyle='lib/perl5' installusrbinperl='define' installvendorarch='' installvendorbin='' installvendorlib='' intsize='4' issymlink='test -h' ivdformat='"ld"' ivsize='4' ivtype='long' known_extensions='B ByteLoader DB_File Data/Dumper Devel/DProf Devel/Peek Fcntl File/Glob GDBM_File IO IPC/SysV NDBM_File ODBM_File Opcode POSIX SDBM_File Socket Sys/Hostname Sys/Syslog Thread attrs re' ksh='' ld='gcc' lddlflags='-G -L/usr/local/lib' ldflags=' -L/usr/local/lib ' ldflags_uselargefiles='' ldlibpthname='LD_LIBRARY_PATH' less='less' lib_ext='.a' libc='/lib/libc.so' libperl='libperl.a' libpth='/usr/local/lib /usr/lib /usr/ccs/lib' libs='-lsocket -lnsl -ldl -lm -lc' libsdirs=' /usr/lib' libsfiles=' libsocket.so.1 libnsl.so.1 libdl.so.1 libm.so.1 libc.so.1' libsfound=' /usr/lib/libsocket.so.1 /usr/lib/libnsl.so.1 /usr/lib/libdl.so.1 /usr/lib/libm.so.1 /usr/lib/libc.so.1' libspath=' /usr/local/lib /usr/lib /usr/ccs/lib' libswanted='sfio socket bind inet nsl nm ndbm gdbm dbm db dl dld sun m c cposix posix ndir dir bsd BSD PW x iconv util ' libswanted_uselargefiles='' line='' lint='' lkflags='' ln='ln' lns='/usr/bin/ln -s' locincpth='/usr/local/include /opt/local/include /usr/gnu/include /opt/gnu/include /usr/GNU/include /opt/GNU/include' loclibpth='/usr/local/lib /opt/local/lib /usr/gnu/lib /opt/gnu/lib /usr/GNU/lib /opt/GNU/lib' longdblsize='12' longlongsize='8' longsize='4' lp='' lpr='' ls='ls' lseeksize='8' lseektype='off_t' mail='' mailx='' make='make' make_set_make='#' mallocobj='malloc.o' mallocsrc='malloc.c' malloctype='void *' man1dir='/usr/local/man/man1' man1direxp='/usr/local/man/man1' man1ext='1' man3dir='/usr/local/man/man3' man3direxp='/usr/local/man/man3' man3ext='3' mips_type='' mkdir='mkdir' mmaptype='caddr_t' modetype='mode_t' more='more' multiarch='' mv='' myarchname='i86pc-solaris' mydomain='.onyx.ch' myhostname='oryx' myuname='sunos oryx 5.8 generic_108529-05 i86pc i386 i86pc ' n='' netdb_hlen_type='int' netdb_host_type='const char *' netdb_name_type='const char *' netdb_net_type='in_addr_t' nm='nm' nm_opt='-p' nm_so_opt='' nonxs_ext='Errno' nroff='nroff' nvEUformat='"E"' nvFUformat='"F"' nvGUformat='"G"' nveformat='"e"' nvfformat='"f"' nvgformat='"g"' nvsize='8' nvtype='double' o_nonblock='O_NONBLOCK' obj_ext='.o' old_pthread_create_joinable='' optimize='-O' orderlib='false' osname='solaris' osvers='2.8' otherlibdirs=' ' package='perl5' pager='/usr/bin/less' passcat='cat /etc/passwd' patchlevel='6' path_sep=':' perl='' perl5='/usr/local/bin/perl' perladmin='stuart@oryx.onyx.ch' perllibs='-lsocket -lnsl -ldl -lm -lc' perlpath='/usr/local/bin/perl' pg='pg' phostname='hostname' pidtype='pid_t' plibpth='' pm_apiversion='5.005' pmake='' pr='' prefix='/usr/local' prefixexp='/usr/local' privlib='/usr/local/lib/perl5/5.6.1' privlibexp='/usr/local/lib/perl5/5.6.1' prototype='define' ptrsize='4' quadkind='3' quadtype='long long' randbits='48' randfunc='drand48' randseedtype='long' ranlib=':' rd_nodata='-1' revision='5' rm='rm' rmail='' runnm='true' sPRIEUldbl='"LE"' sPRIFUldbl='"LF"' sPRIGUldbl='"LG"' sPRIXU64='"llX"' sPRId64='"lld"' sPRIeldbl='"Le"' sPRIfldbl='"Lf"' sPRIgldbl='"Lg"' sPRIi64='"lli"' sPRIo64='"llo"' sPRIu64='"llu"' sPRIx64='"llx"' sSCNfldbl='"Lf"' sched_yield='' scriptdir='/usr/local/bin' scriptdirexp='/usr/local/bin' sed='sed' seedfunc='srand48' selectminbits='32' selecttype='fd_set *' sendmail='' sh='/bin/sh' shar='' sharpbang='#!' shmattype='void *' shortsize='2' shrpenv='' shsharp='true' sig_count='46' sig_name='ZERO HUP INT QUIT ILL TRAP ABRT EMT FPE KILL BUS SEGV SYS PIPE ALRM TERM USR1 USR2 CHLD PWR WINCH URG IO STOP TSTP CONT TTIN TTOU VTALRM PROF XCPU XFSZ WAITING LWP FREEZE THAW CANCEL LOST RTMIN NUM39 NUM40 NUM41 NUM42 NUM43 NUM44 RTMAX IOT CLD POLL ' sig_name_init='"ZERO"\, "HUP"\, "INT"\, "QUIT"\, "ILL"\, "TRAP"\, "ABRT"\, "EMT"\, "FPE"\, "KILL"\, "BUS"\, "SEGV"\, "SYS"\, "PIPE"\, "ALRM"\, "TERM"\, "USR1"\, "USR2"\, "CHLD"\, "PWR"\, "WINCH"\, "URG"\, "IO"\, "STOP"\, "TSTP"\, "CONT"\, "TTIN"\, "TTOU"\, "VTALRM"\, "PROF"\, "XCPU"\, "XFSZ"\, "WAITING"\, "LWP"\, "FREEZE"\, "THAW"\, "CANCEL"\, "LOST"\, "RTMIN"\, "NUM39"\, "NUM40"\, "NUM41"\, "NUM42"\, "NUM43"\, "NUM44"\, "RTMAX"\, "IOT"\, "CLD"\, "POLL"\, 0' sig_num='0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 6 18 22 ' sig_num_init='0\, 1\, 2\, 3\, 4\, 5\, 6\, 7\, 8\, 9\, 10\, 11\, 12\, 13\, 14\, 15\, 16\, 17\, 18\, 19\, 20\, 21\, 22\, 23\, 24\, 25\, 26\, 27\, 28\, 29\, 30\, 31\, 32\, 33\, 34\, 35\, 36\, 37\, 38\, 39\, 40\, 41\, 42\, 43\, 44\, 45\, 6\, 18\, 22\, 0' signal_t='void' sitearch='/usr/local/lib/perl5/site_perl/5.6.1/i86pc-solaris' sitearchexp='/usr/local/lib/perl5/site_perl/5.6.1/i86pc-solaris' sitebin='/usr/local/bin' sitebinexp='/usr/local/bin' sitelib='/usr/local/lib/perl5/site_perl/5.6.1' sitelib_stem='/usr/local/lib/perl5/site_perl' sitelibexp='/usr/local/lib/perl5/site_perl/5.6.1' siteprefix='/usr/local' siteprefixexp='/usr/local' sizesize='4' sizetype='size_t' sleep='' smail='' so='so' sockethdr='' socketlib='' socksizetype='int' sort='sort' spackage='Perl5' spitshell='cat' src='.' ssizetype='ssize_t' startperl='#!/usr/local/bin/perl' startsh='#!/bin/sh' static_ext=' ' stdchar='unsigned char' stdio_base='((fp)->_base)' stdio_bufsiz='((fp)->_cnt + (fp)->_ptr - (fp)->_base)' stdio_cnt='((fp)->_cnt)' stdio_filbuf='' stdio_ptr='((fp)->_ptr)' stdio_stream_array='__iob' strings='/usr/include/string.h' submit='' subversion='1' sysman='/usr/man/man1' tail='' tar='' tbl='' tee='' test='test' timeincl='/usr/include/sys/time.h ' timetype='time_t' touch='touch' tr='tr' trnl='\n' troff='' u16size='2' u16type='unsigned short' u32size='4' u32type='unsigned long' u64size='8' u64type='unsigned long long' u8size='1' u8type='unsigned char' uidformat='"ld"' uidsign='-1' uidsize='4' uidtype='uid_t' uname='uname' uniq='uniq' uquadtype='unsigned long long' use5005threads='' use64bitall='' use64bitint='' usedl='define' useithreads='' uselargefiles='define' uselongdouble='' usemorebits='' usemultiplicity='' usemymalloc='y' usenm='true' useopcode='true' useperlio='' useposix='true' usesfio='false' useshrplib='false' usesocks='' usethreads='' usevendorprefix='' usevfork='false' usrinc='/usr/include' uuname='' uvXUformat='"lX"' uvoformat='"lo"' uvsize='4' uvtype='unsigned long' uvuformat='"lu"' uvxformat='"lx"' vendorarch='' vendorarchexp='' vendorbin='' vendorbinexp='' vendorlib='' vendorlib_stem='' vendorlibexp='' vendorprefix='' vendorprefixexp='' version='5.6.1' versiononly='' vi='' voidflags='15' xlibpth='/usr/lib/386 /lib/386' xs_apiversion='5.005' yacc='yacc' yaccflags='' zcat='' zip='zip'
__________________________________________________ Do You Yahoo!? Make international calls for as low as $.04/minute with Yahoo! Messenger http://phonecard.yahoo.com/
On Jul 24\, stuart lory said:
The situation occurs when using /o in a regexp. Specifically I am using /mos\, and the bug does not show up if I change the regexp to /ms. My understanding is /o means 'compile pattern once'. But since I am doing this in a subroutine\, I was expecting the regexp to go out of scope when the subroutine ended.
What happens in test #2 is almost certainly a bug since I am passing in two different strings and the second string is being modified in a place where the first string had been changed. I think it's probably easier just to show an example output:
Long story short:
The /o modifier is SUPREME. If you write:
sub foo { $x =~ /$y/o; }
then the first time foo() is called\, the regex is compiled. Never again will it be compiled. Thus\, this behavior is not buggy.
In your case\, your regex is compiled as
/brown/
all the time. However\, the RIGHT-HAND SIDE of your regex is not bound by the /o rule\, and thus\, you get the behavior:
for ( [ brown => 'purple' ]\, [ over => 'into' ] ) { my ($find\, $replace) = @$_; $X =~ s/$find/$replace/o; }
First\, $X gets "brown" replaced with "purple". Next\, it TRIES to replace "brown" with "into"\, but fails\, since there's no more brown to be found. It uses "brown" because the regex will ONLY BE COMPILED ONCE.
Let's examine your second case:
for ( [ \$Y\, brown => 'purple' ]\, [ \$Z\, over => 'into' ] ) { my ($str\, $find\, $replace) = @$_; $$str =~ s/$find/$replace/o; }
On the first iteration\, $Y is changed -- "brown" becomes "purple". On the second iteration\, $Z is changed -- "brown" becomes "into". Why? Because the regex (/$find/) was ONLY compiled ONCE.
Does this clarify the behavior?
Migrated from rt.perl.org#7337 (status was 'resolved')
Searchable as RT7337$