Skip Menu | You are currently an anonymous guest. | Login | Return to Main | Preferences
Id: 23624
Status: open
Left: 0 min
Priority: 0/0
Queue: perl5

Owner: Nobody
Requestors: vparseval <tassilo.parseval [at] post.rwth-aachen.de>
Cc: nobull67 [at] gmail.com
AdminCc:

Operating System: Linux
PatchStatus: (no value)
Severity: low
Type: core
Perl Version: 5.8.0
Fixed In: (no value)

X Report information



X History Display mode: Brief headersFull headers
#   Thu Aug 28 01:53:46 2003 vparseval - Ticket created  
Date: Thu, 28 Aug 2003 08:46:14 +0000
From: tassilo.parseval@post.rwth-aachen.de
Subject: scoping of @+/@- when useed with tie()
To: perlbug@perl.org
CC: tassilo.parseval@post.rwth-aachen.de
Download (untitled) [text/plain 3.9k]

This is a bug report for perl from tassilo.parseval@post.rwth-aachen.de,
generated with the help of perlbug 1.34 running under perl v5.8.0.


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

Hi,

there is something very odd going on when trying to emulate $`, $' and $&
through tied hashes. See this code:

#! /usr/bin/perl -w

package Tie::Prematch;
sub TIEHASH { bless \my $dummy => __PACKAGE__ }
sub FETCH { return substr $_[1], 0, $-[0] }

package main;

tie my %pre, 'Tie::Prematch';
my $foo = "foobar";
$foo =~ s/.ob/$pre{ $foo }/;
print $foo, "\n";

$foo = "foobar";
$foo =~ s/.ob/tied(%pre)->FETCH($foo)/e;
print $foo, "\n";

tie %-, 'Tie::Prematch';
$foo = "foobar";
$foo =~ s/.ob/$-{$foo}/;
print $foo;
__END__
Use of uninitialized value in substr at bug.pl line 5.
far
ffar
ffar

According to my knowledge, @- and @+ should be dynamically scoped so it's
obvious that they still have their values in Tie::Prematch::FETCH() when doing

$foo =~ s/.ob/tied(%pre)->FETCH($foo)/e;

But they somehow loose them when doing

$foo =~ s/.ob/$pre{ $foo }/;

even though it should be functionally identical.

It's even stranger: as the third example in the above shows, it works when
I tie one of the truely global symbols (%- in this case). It turns out that
this kind of tying behaves normally with punctuation variables but fails
with lexicals and package variables.

This bug is present in at least 5.6.1, 5.8.0 and 5.8.1RC4.

Tassilo

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

Configured by root at Tue Feb 25 16:06:57 Local time zone must be set--see zic manual page 2003.

Summary of my perl5 (revision 5.0 version 8 subversion 0) configuration:
Platform:
osname=linux, osvers=2.4.20, archname=i686-linux
uname='linux ethan 2.4.20 #2 mon dec 2 14:26:23 cet 2002 i686 unknown '
config_args='-ds -e -Dprefix=/usr -Dccflags= -O3 -march=athlon'
hint=recommended, useposix=true, d_sigaction=define
usethreads=undef use5005threads=undef useithreads=undef usemultiplicity=undef
useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
use64bitint=undef use64bitall=undef uselongdouble=undef
usemymalloc=n, bincompat5005=undef
Compiler:
cc='cc', ccflags ='-O3 -march=athlon -fno-strict-aliasing -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
optimize='-O2',
cppflags='-O3 -march=athlon -fno-strict-aliasing'
ccversion='', gccversion='3.2', gccosandvers=''
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, prototype=define
Linker and Libraries:
ld='cc', ldflags =' -L/usr/local/lib'
libpth=/usr/local/lib /lib /usr/lib
libs=-lnsl -ldl -lm -lc -lcrypt -lutil
perllibs=-lnsl -ldl -lm -lc -lcrypt -lutil
libc=/lib/libc-2.2.5.so, so=so, useshrplib=false, libperl=libperl.a
gnulibc_version='2.2.5'
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:
/usr/lib/perl5/5.8.0/i686-linux
/usr/lib/perl5/5.8.0
/usr/lib/perl5/site_perl/5.8.0/i686-linux
/usr/lib/perl5/site_perl/5.8.0
/usr/lib/perl5/site_perl
.

---
Environment for perl v5.8.0:
HOME=/home/ethan
LANG=C
LANGUAGE (unset)
LC_CTYPE=de_DE@euro
LD_LIBRARY_PATH=:/usr/local/j2sdk1.4.0/jre/lib/i386:/usr/local/pwlib/lib
LOGDIR (unset)
PATH=/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin:/usr/games:/usr/local/j2re1.4.1/bin
PERLDOC_PAGER=/bin/less -isR
PERL_BADLANG (unset)
SHELL=/bin/bash
#   Thu Aug 28 01:53:47 2003 RT_System - Default: Keyword/9 changed from (no value) to 'Linux'  
#   Thu Aug 28 01:53:47 2003 RT_System - Default: Keyword/11 changed from (no value) to 'low'  
#   Thu Aug 28 01:53:47 2003 RT_System - Default: Keyword/12 changed from (no value) to 'core'  
#   Thu Aug 28 01:53:47 2003 RT_System - Default: Keyword/13 changed from (no value) to '5.8.0'  
#   Thu Aug 28 23:48:24 2003 rafael - Correspondence added  
Date: Fri, 29 Aug 2003 08:40:49 +0200
From: Rafael Garcia-Suarez <rgarciasuarez@free.fr>
To: perl5-porters@perl.org
Subject: Re: [perl #23624] scoping of @+/@- when useed with tie()
Download (untitled) [text/plain 511b]
tassilo.parseval@post.rwth-aachen.de (via RT) wrote:
> According to my knowledge, @- and @+ should be dynamically scoped so it's
> obvious that they still have their values in Tie::Prematch::FETCH() when doing
>
> $foo =~ s/.ob/tied(%pre)->FETCH($foo)/e;
>
> But they somehow loose them when doing
>
> $foo =~ s/.ob/$pre{ $foo }/;
>
> even though it should be functionally identical.

No, the /e creates a scope. Add a /e to your 2nd example and it becomes
equivalent to the 1st one (apparently).
#   Fri Aug 29 00:31:48 2003 vparseval - Correspondence added  
Date: Fri, 29 Aug 2003 09:30:30 +0200
From: Tassilo von Parseval <tassilo.parseval@post.rwth-aachen.de>
Subject: Re: [perl #23624] scoping of @+/@- when useed with tie()
To: perl5-porters@perl.org
CC: Rafael Garcia-Suarez <rgarciasuarez@free.fr>
Download (untitled) [text/plain 1.6k]
On Fri, Aug 29, 2003 at 08:40:49AM +0200 Rafael Garcia-Suarez wrote:
> tassilo.parseval@post.rwth-aachen.de (via RT) wrote:
> > According to my knowledge, @- and @+ should be dynamically scoped so it's
> > obvious that they still have their values in Tie::Prematch::FETCH() when doing
> >
> > $foo =~ s/.ob/tied(%pre)->FETCH($foo)/e;
> >
> > But they somehow loose them when doing
> >
> > $foo =~ s/.ob/$pre{ $foo }/;
> >
> > even though it should be functionally identical.
>
> No, the /e creates a scope. Add a /e to your 2nd example and it becomes
> equivalent to the 1st one (apparently).

I don't understand this. Why do I need this additional scope in the
second case? In which scope is FETCH() called without the /e? Since
the values of these dynamically scoped variables aren't accessible in
it, it must be a scope above the one from the whole substitution (or
rather: above the scope where @- and @+ are set). Or am I wrong here?

And secondly, why don't I need the /e when I use %- (for instance) as
the tied hash?

Adding an /e, if I may say that, is also highly strange. The right-hand
side of a substition is in double-quotish context. But:

$a{a} = "foo";
$s = "foo";

# these two will give the same results
$s =~ s/./$a{a}/e
$s =~ s/./$a{a}/;

print $s;

This is not something that would become obvious when reading about /e in
perlop.pod.

Tassilo
--
$_=q#",}])!JAPH!qq(tsuJ[{@"tnirp}3..0}_$;//::niam/s~=)]3[))_$-3(rellac(=_$({
pam{rekcahbus})(rekcah{lrePbus})(lreP{rehtonabus})!JAPH!qq(rehtona{tsuJbus#;
$_=reverse,s+(?<=sub).+q#q!'"qq.\t$&."'!#+sexisexiixesixeseg;y~\n~~dddd;eval
#   Mon Dec 29 18:00:38 2003 RT_System - Status changed from 'new' to 'open'  
#   Sat Aug 04 09:15:05 2007 nobull67 - Correspondence added  
Download (untitled) [text/plain 915b]
On Thu Aug 28 01:53:46 2003, vparseval wrote:
> #! /usr/bin/perl -w
>
> package Tie::Prematch;
> sub TIEHASH { bless \my $dummy => __PACKAGE__ }
> sub FETCH { return substr $_[1], 0, $-[0] }
>
> package main;
>
> tie my %pre, 'Tie::Prematch';
> my $foo = "foobar";
> $foo =~ s/.ob/$pre{ $foo }/;

The problem here is that the Perl compiler sees the RHS of the s/// as
being invariant and thinks it can get away with evaluating without
setting up the last-match context.

At the optree level the difference is the inclusion or otherwise of the
substcont OP code.

Since this is a compile time optimisation and the tied-ness of %pre
cannot be determined at compile time there's not much that can really be
done to fix this (other than ditch the optimisation completely - which
would be a very high price to pay).

Arguably this (c|sh)ould be documented in perlop and/or perltie.

#   Sat Aug 04 10:00:12 2007 nobull67 - Correspondence added  
Download (untitled) [text/plain 157b]
On Sat Aug 04 09:15:05 2007, nobull67 wrote:

> Arguably this (c|sh)ould be documented in perlop and/or perltie.

perltie diff (to BUGS section) attached
Download perltie.pod.diff [application/octet-stream 647b]
Message body not shown because it is too large or is not plain text.
#   Mon Aug 13 09:00:36 2007 nobull67@gmail.com - Cc nobull67@gmail.com added  


For issues related to this RT instance (aka "perlbug"), please contact perlbug-admin at perl.org