Front page | perl.perl5.porters |
Postings from March 2000
[PATCH] Two attribute::reftype() anomalies
Thread Next
From:
Tom Christiansen
Date:
March 16, 2000 07:02
Subject:
[PATCH] Two attribute::reftype() anomalies
Message ID:
2377.953218896@chthon
I have discovered two "anomalies" in the attribute pragma's reftype()
function (from xsutils, just sv_reftype). These may well be bugs.
I supply possible fixes (but they really merit discussion and
understanding first) for the second one, but didn't poke at the
first.
First, it under some circumstances appears to care whether you pass
a literal value or not. If you store the value in a variable, and
pass that, you do not produce the same effect.
Look here:
% perl -Mattributes=reftype -le 'print $it = *STDIN; print reftype(*STDIN)'
*main::STDIN
Yes, there was an extra blank line there; reftype() returned the
null string, and the defined one, at that. Now watch this:
% perl -Mattributes=reftype -le 'print $it = *STDIN; print reftype($it)'
*main::STDIN
Usage: attributes::reftype $reference at -e line 1.
Curious, eh? Why should it matter whether *STDIN is a literal or whether
it comes from a varible. This works:
% perl -Mattributes=reftype -le 'print $it = *STDIN; print reftype(\$it)'
*main::STDIN
GLOB
===========================
The other problem is, I think, that something has somehow slipped
through the cracks.
% perl -Mattributes=reftype -le 'print $it = *STDIN{IO}; print ref($it); print reftype(*STDIN{IO})'
IO::Handle=IO(0xff49c)
IO::Handle
UNKNOWN
Which gives the same answer on all literals:
% perl -Mattributes=reftype -le 'print $it = *STDIN{IO}; print ref(*STDIN{IO}); print reftype(*STDIN{IO})'
IO::Handle=IO(0xff49c)
IO::Handle
UNKNOWN
I'd've imagined that since the print value was "IO::Handle=IO(0xff49c)",
that the ref would be "IO::Handle" and the reftype would be "IO",
not "UNKNOWN", particularly given that it would appear sufficiently
"known" for the stringified version.
The apparent fix is for this last one is:
--- sv.c-OLD Thu Mar 16 07:38:46 2000
+++ sv.c Thu Mar 16 07:39:43 2000
@@ -5168,6 +5168,7 @@
case SVt_PVCV: return "CODE";
case SVt_PVGV: return "GLOB";
case SVt_PVFM: return "FORMAT";
+ case SVt_PVIO: return "IO";
default: return "UNKNOWN";
}
}
Which make you get
IO::Handle=IO(0xff49c)
IO::Handle
IO
as you would expect to expect.
But this relationship doesn't always hold true, and I wonder whether
it's by accident or intent. I wonder about these disparities between
the code around lines 2070 and 5170 in sv.c. Are they intentional?
% perl -Mattributes=reftype -le 'print $it = bless \[]; print ref($it) ; print reftype($it)'
main=SCALAR(0xf624c)
main
REF
Shouldn't that be:
main=REF(0xf624c)
main
REF
If so, then you appear to need this:
--- sv.c-OLD Thu Mar 16 07:38:46 2000
+++ sv.c Thu Mar 16 07:45:35 2000
@@ -2066,7 +2066,7 @@
case SVt_PV:
case SVt_PVIV:
case SVt_PVNV:
- case SVt_PVBM: s = "SCALAR"; break;
+ case SVt_PVBM: s = SvROK(sv)? "REF": "SCALAR"; break;
case SVt_PVLV: s = "LVALUE"; break;
case SVt_PVAV: s = "ARRAY"; break;
case SVt_PVHV: s = "HASH"; break;
But perhaps this =REF thing is getting out of hand. For example,
the qr// objects are just =SCALAR.
% perl -Mattributes=reftype -le 'print $it = qr/foo/; print ref($it) ; print reftype($it)'
(?-xism:foo)
Regexp
SCALAR
Although you have to be a tad sneaky to get that out of them:
% perl -le 'print qr/asdf/'
(?-xism:asdf)
% perl -Moverload -le 'print overload::StrVal(qr/asdf/)'
Regexp=SCALAR(0xf624c)
For the broken record, I still disagree with the blessed name
"Regexp". It's not even a class you can "use", the way IO::Handle
at least is. :-(
Interestingly, it's not that way here:
% perl -Mattributes=reftype -le 'print $it = \substr("asdf",1,2); print ref($it) ; print reftype($it)'
LVALUE(0x10c73c)
LVALUE
LVALUE
% perl -Mattributes=reftype -le 'print $it = bless \substr("asdf",1,2); print ref($it) ; print reftype($it)'
main=LVALUE(0x10c73c)
main
LVALUE
So I wonder whether the regex case isn't um, counterintuitive.
--tom
Thread Next
-
[PATCH] Two attribute::reftype() anomalies
by Tom Christiansen