Closed p5pRT closed 20 years ago
If you accidentally use something like tr/\d// on a reference\, the variable becomes stringified without any warning. Later on if you try to use it as a reference\, the error message produced is confusing.
#!/usr/bin/perl -w use IO::File; use strict; use diagnostics; my $t = IO::File->new_tmpfile(); if ($t =~ tr/\d//) { print "string $t contains digits\n"; } $t->close();
A better error message would warn that the variable had been stringified earlier on and had lost its reference-ness. Alternatively you could give a warning when the stringification happens\, or even a fatal error. (Nobody would really want to use tr/// on a reference\, it must be a mistake.)
I reported this to comp.lang.perl.moderated and Yitzchak Scott-Thoennes \sthoenna@​efn\.org suggested a fix:
s/// is broken\, too.
Here's one way to fix tr///:
End of Patch.
but that would prevent doing anything useful with an overloaded object (but that should be ok since it is broken as it is now). And the error message may need to be more specific.
Are there any cases where a non-readonly non-reference would have get magic but not set magic? If so\, these would be broken too.
I also noticed that $x =~ tr/x// is calling get magic twice.
In article \200009111001\.LAA17175@​dynamic08\.doc\.ic\.ac\.uk\, Edward Avis \epa98@​doc\.ic\.ac\.uk wrote:
If you accidentally use something like tr/\d// on a reference\, the variable becomes stringified without any warning. Later on if you try to use it as a reference\, the error message produced is confusing. \
I reported this to comp.lang.perl.moderated and Yitzchak Scott-Thoennes \sthoenna@​efn\.org suggested a fix: s/// is broken\, too.
Here's one way to fix tr///: --- doop.c.orig Fri Sep 1 14:09:46 2000 +++ doop.c Sat Sep 9 22:37:38 2000 @@ -438\,7 +438\,7 @@ I32 hasutf = (PL_op->op_private & (OPpTRANS_FROM_UTF|OPpTRANS_TO_UTF));
- if (SvREADONLY(sv) && !(PL_op->op_private & OPpTRANS_IDENTICAL)) + if ((SvREADONLY(sv) || SvROK(sv)) && !(PL_op->op_private & OPpTRANS_IDENTICAL)) Perl_croak(aTHX_ PL_no_modify);
\(void\)SvPV\(sv\, len\);
End of Patch.
but that would prevent doing anything useful with an overloaded object (but that should be ok since it is broken as it is now). And the error message may need to be more specific.
Are there any cases where a non-readonly non-reference would have get magic but not set magic? If so\, these would be broken too.
I also noticed that $x =~ tr/x// is calling get magic twice.
I didn't give the correct fix\, since even a 'counting' tr seems to implicity stringify the reference. (That is\, $x =~ tr/x// is equivalent to ($x = "$x") =~ tr/x//. It probably should be equivalent to "$x" =~ tr/x// instead.)
Also problematic are s///\, chop\, chomp\, 4-arg substr\, and 3-arg rvalue substr. Each of these operating on a reference $x implicitly do ($x = "$x") first. Are there other operators that give string lvalue context?
3-arg lvalue substr (e.g. substr($x\,0\,0)='') does give a warning "Attempt to use reference as lvalue in substr" but goes ahead and stringifies the reference.
I'd be inclined to say all the others should do the same\, but the wording of the warning bothers me since it is not just attempting to use the reference as an lvalue\, it actually is using it as an lvalue.
On Mon\, Sep 11\, 2000 at 02:40:03PM -0700\, Yitzchak Scott-Thoennes wrote:
Also problematic are s///\, chop\, chomp\, 4-arg substr\, and 3-arg rvalue substr. Each of these operating on a reference $x implicitly do ($x = "$x") first. Are there other operators that give string lvalue context?
vec().
Abigail
Migrated from rt.perl.org#4282 (status was 'resolved')
Searchable as RT4282$