Closed p5pRT closed 21 years ago
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
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" );
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/
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 ;-)
@rgs - Status changed from 'new' to 'resolved'
Migrated from rt.perl.org#17823 (status was 'resolved')
Searchable as RT17823$