Perl / perl5

🐪 The Perl programming language
https://dev.perl.org/perl5/
Other
1.91k stars 542 forks source link

counting tr/// stringifies references #5996

Closed p5pRT closed 21 years ago

p5pRT commented 21 years ago

Migrated from rt.perl.org#17823 (status was 'resolved')

Searchable as RT17823$

p5pRT commented 21 years ago

From @nwc10

Created by @nwc10

tr/// when used to count characters (an empty replacement list) seems to aggressively stringify its argument​:

..../perl -wle '$r1 = $r0 = \$^X; $r0 =~ tr/a//; print ref $r0; print ref $r1'

SCALAR

This forcible stringifcaiton doesn't seem necessary\, considering that 5.6.x now allows tr on read only values​:

perl5.6.1 -wle 'print "perl" =~ tr/rocks//' 1

Perl Info ``` Flags: category=core severity=low Site configuration information for perl v5.9.0: Configured by nick at Wed Oct 9 11:43:13 BST 2002. Summary of my perl5 (revision 5.0 version 9 subversion 0 patch 17981) configuration: Platform: osname=freebsd, osvers=4.6-stable, archname=i386-freebsd uname='freebsd roast.cow.org.uk 4.6-stable freebsd 4.6-stable #13: mon aug 19 14:25:20 bst 2002 paul@roast.cow.org.uk:usrobjusrsrcsysroast i386 ' config_args='-Dusedevel -Ubincompat5005 -Uinstallusrbinperl -Dcf_email=nick@talking.bollo.cx -Dperladmin=nick@talking.bollo.cx -Dinc_version_list= -Dinc_version_list_init=0 -Uuse64bitint -de -Dcc=gcc' 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='gcc', ccflags ='-DHAS_FPSETMASK -DHAS_FLOATINGPOINT_H -fno-strict-aliasing -I/usr/local/include', optimize='-O', cppflags='-DHAS_FPSETMASK -DHAS_FLOATINGPOINT_H -fno-strict-aliasing -I/usr/local/include' ccversion='', gccversion='2.95.4 20020320 [FreeBSD]', 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='gcc', ldflags ='-Wl,-E -L/usr/local/lib' libpth=/usr/lib /usr/local/lib libs=-lbind -lgdbm -lm -lc -lcrypt -lutil perllibs=-lbind -lm -lc -lcrypt -lutil libc=, so=so, useshrplib=false, libperl=libperl.a gnulibc_version='' Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags=' ' cccdlflags='-DPIC -fpic', lddlflags='-shared -L/usr/local/lib' Locally applied patches: DEVEL17881 @INC for perl v5.9.0: lib /usr/local/lib/perl5/5.9.0/i386-freebsd /usr/local/lib/perl5/5.9.0 /usr/local/lib/perl5/site_perl/5.9.0/i386-freebsd /usr/local/lib/perl5/site_perl/5.9.0 /usr/local/lib/perl5/site_perl . Environment for perl v5.9.0: HOME=/usr/home/nick LANG (unset) LANGUAGE (unset) LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/games:/usr/local/sbin:/usr/local/bin:/usr/X11R6/bin:/usr/home/nick/bin PERL_BADLANG (unset) SHELL=/usr/local/bin/bash ```
p5pRT commented 21 years ago

From @rgs

Nicholas Clark (via RT) wrote​:

tr/// when used to count characters (an empty replacement list) seems to aggressively stringify its argument​:

....../perl -wle '$r1 = $r0 = \$^X; $r0 =~ tr/a//; print ref $r0; print ref $r1'

SCALAR

I applied this fix :

Change 17984 by rgs@​rgs-home on 2002/10/09 19​:17​:08

  Fix bug #17823 : non-modifying tr/// stringifies references

Affected files ...

...... //depot/perl/doop.c#129 edit ...... //depot/perl/t/op/tr.t#33 edit

Differences ...

==== //depot/perl/doop.c#129 (text) ====

@​@​ -608\,10 +608\,11 @​@​   (void)SvPV(sv\, len);   if (!len)   return 0; - if (!SvPOKp(sv)) - (void)SvPV_force(sv\, len); - if (!(PL_op->op_private & OPpTRANS_IDENTICAL)) + if (!(PL_op->op_private & OPpTRANS_IDENTICAL)) { + if (!SvPOKp(sv)) + (void)SvPV_force(sv\, len);   (void)SvPOK_only_UTF8(sv); + }

  DEBUG_t( Perl_deb(aTHX_ "2.TBL\n"));

==== //depot/perl/t/op/tr.t#33 (xtext) ====

@​@​ -6\,7 +6\,7 @​@​   require './test.pl'; }

-plan tests => 97; +plan tests => 99;

my $Is_EBCDIC = (ord('i') == 0x89 & ord('J') == 0xd1);

@​@​ -379\,3 +379\,7 @​@​ eval '$foo{bar} =~ tr/N/N/'; is( $@​\, ''\, 'implicit count outside hash bounds' ); is( scalar keys %foo\, 0\, " doesn't extend the hash"); + +$x = \"foo"; +is( $x =~ tr/A/A/\, 2\, 'non-modifying tr/// on a scalar ref' ); +is( ref $x\, 'SCALAR'\, " doesn't stringify its argument" );

p5pRT commented 21 years ago

From @nwc10

On Wed\, Oct 09\, 2002 at 10​:33​:02PM +0200\, Rafael Garcia-Suarez wrote​:

I applied this fix :

Thanks

- if (!SvPOKp(sv)) - (void)SvPV_force(sv\, len); - if (!(PL_op->op_private & OPpTRANS_IDENTICAL)) + if (!(PL_op->op_private & OPpTRANS_IDENTICAL)) { + if (!SvPOKp(sv)) + (void)SvPV_force(sv\, len); (void)SvPOK_only_UTF8(sv); + }

I hoped it would be something as simple as identifying the correct SvPV_force to turn into SvPV. Clearly it was slightly more complex.

+$x = \"foo"; +is( $x =~ tr/A/A/\, 2\, 'non-modifying tr/// on a scalar ref' ); +is( ref $x\, 'SCALAR'\, " doesn't stringify its argument" );

Wah. Risqué. I was only expecting tr/A//; to work :-)

Nicholas Clark -- Even better than the real thing​: http​://nms-cgi.sourceforge.net/

p5pRT commented 21 years ago

From @rgs

Nicholas Clark wrote​:

On Wed\, Oct 09\, 2002 at 10​:33​:02PM +0200\, Rafael Garcia-Suarez wrote​:

I applied this fix :

Thanks

- if (!SvPOKp(sv)) - (void)SvPV_force(sv\, len); - if (!(PL_op->op_private & OPpTRANS_IDENTICAL)) + if (!(PL_op->op_private & OPpTRANS_IDENTICAL)) { + if (!SvPOKp(sv)) + (void)SvPV_force(sv\, len); (void)SvPOK_only_UTF8(sv); + }

I hoped it would be something as simple as identifying the correct SvPV_force to turn into SvPV. Clearly it was slightly more complex.

No\, it's simple\, but I rearranged the if()s to avoid testing several times for the OPpTRANS_IDENTICAL flag. An SvPV is done earlier.

+$x = \"foo"; +is( $x =~ tr/A/A/\, 2\, 'non-modifying tr/// on a scalar ref' ); +is( ref $x\, 'SCALAR'\, " doesn't stringify its argument" );

Wah. Risqué. I was only expecting tr/A//; to work :-)

not since change 13486 ;-)

p5pRT commented 21 years ago

@rgs - Status changed from 'new' to 'resolved'