develooper 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


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About