develooper Front page | perl.perl5.porters | Postings from May 2003

[perl #22369] $1 dynamic scoping breaks with recursion

Thread Next
From:
perlbug-followup
Date:
May 29, 2003 14:50
Subject:
[perl #22369] $1 dynamic scoping breaks with recursion
Message ID:
rt-22369-58348.16.2649916529604@rt.perl.org
# New Ticket Created by  frederik@ugcs.caltech.edu 
# Please include the string:  [perl #22369]
# in the subject line of all future correspondence about this issue. 
# <URL: http://rt.perl.org/rt2/Ticket/Display.html?id=22369 >



This is a bug report for perl from frederik@ugcs.caltech.edu,
generated with the help of perlbug 1.34 running under perl v5.8.0.


-----------------------------------------------------------------
[Please enter your report here]

The perlre man page says:

 The numbered variables ($1, $2, $3, etc.) and the related punctuation
 set ($+, $&, $`, $', and $^N) are all dynamically scoped until the
 end of the enclosing block or until the next successful match,
 whichever comes first.

The phrase "until the next successful match" is not quite clear to me.
Unless it means the obvious "until the next successful match in the
same enclosing scope", I would have interpreted it as "until the next
successful match anywhere". But the latter is not true (otherwise the
dynamic scoping would be useless); instead the statement seems to
indicate that the variables will be overwritten only if another match
is done using the same piece of code, even in a different scope:

sub r
{ 
  shift =~ /(.*)/;
  if(shift) {
    r("bar", 0);
    print "$1\n";
  }
}
r("foo", 1);

# prints: bar
# (expected: foo)

In addition to strange action-at-a-distance, this behavior means that
replacing a call to one function with a call to another which has an
identical body to the first can change the behavior of your program:

# t is a copy of r
sub t
{ 
  shift =~ /(.*)/;
  if(shift) {
    t("bar", 0);
    print "$1\n";
  }
}
sub r
{ 
  shift =~ /(.*)/;
  if(shift) {
    t("bar", 0);
    print "$1\n";
  }
}
r("foo", 1);

# prints: foo

I know of no other programming language that breaks this common
invariant of functions. Furthermore, I can't imagine why the above
behavior would be a desirable feature of Perl, unless the only
possible fix results in considerably slower performance. So I am
reporting it as a bug, either in the regular expression matching code,
or in the documentation, which should be clearer if this behavior is
indeed intentional.

[Please do not change anything below this line]
-----------------------------------------------------------------
---
Flags:
    category=core
    severity=medium
---
Site configuration information for perl v5.8.0:

Configured by Debian Project at Mon Feb 17 13:43:44 UTC 2003.

Summary of my perl5 (revision 5.0 version 8 subversion 0) configuration:
  Platform:
    osname=linux, osvers=2.4.19-powerpc-smp, archname=powerpc-linux-thread-multi
    uname='linux voltaire 2.4.19-powerpc-smp #1 smp mon sep 9 09:11:02 edt 2002 ppc unknown unknown gnulinux '
    config_args='-Dusethreads -Duselargefiles -Dccflags=-DDEBIAN -Dcccdlflags=-fPIC -Darchname=powerpc-linux -Dprefix=/usr -Dprivlib=/usr/share/perl/5.8.0 -Darchlib=/usr/lib/perl/5.8.0 -Dvendorprefix=/usr -Dvendorlib=/usr/share/perl5 -Dvendorarch=/usr/lib/perl5 -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl/5.8.0 -Dsitearch=/usr/local/lib/perl/5.8.0 -Dman1dir=/usr/share/man/man1 -Dman3dir=/usr/share/man/man3 -Dman1ext=1 -Dman3ext=3perl -Dpager=/usr/bin/sensible-pager -Uafs -Ud_csh -Uusesfio -Uusenm -Duseshrplib -Dlibperl=libperl.so.5.8.0 -Dd_dosuid -des'
    hint=recommended, useposix=true, d_sigaction=define
    usethreads=define use5005threads=undef useithreads=define usemultiplicity=define
    useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
    use64bitint=undef use64bitall=undef uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fno-strict-aliasing -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    optimize='-O3',
    cppflags='-D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fno-strict-aliasing'
    ccversion='', gccversion='3.2.3 20030210 (Debian prerelease)', gccosandvers=''
    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=4321
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=8
    ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=8, prototype=define
  Linker and Libraries:
    ld='cc', ldflags =' -L/usr/local/lib'
    libpth=/usr/local/lib /lib /usr/lib
    libs=-lgdbm -ldb -ldl -lm -lpthread -lc -lcrypt
    perllibs=-ldl -lm -lpthread -lc -lcrypt
    libc=/lib/libc-2.3.1.so, so=so, useshrplib=true, libperl=libperl.so.5.8.0
    gnulibc_version='2.3.1'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-rdynamic'
    cccdlflags='-fPIC', lddlflags='-shared -L/usr/local/lib'

Locally applied patches:
    

---
@INC for perl v5.8.0:
    /etc/perl
    /usr/local/lib/perl/5.8.0
    /usr/local/share/perl/5.8.0
    /usr/lib/perl5
    /usr/share/perl5
    /usr/lib/perl/5.8.0
    /usr/share/perl/5.8.0
    /usr/local/lib/site_perl
    .

---
Environment for perl v5.8.0:
    HOME=/home/frederik
    LANG=C
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/home/frederik/bin:/usr/X11R6/bin:/usr/local/bin:/usr/bin:/bin:/home/frederik/sbin:/usr/X11R6/sbin:/usr/local/sbin:/usr/sbin:/sbin
    PERL_BADLANG (unset)
    SHELL=/bin/bash


Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About