in reply to Why reftype and blessed are making my life harder than it needs to be

Your conversion doesn't really have equivalent semantics. isa includes subclass relationships, which you won't get with ref or blessed.

In the example you gave, what's wrong with this (assuming you don't really want @ISA semantics):

my $is_blah = ref( $thing ) eq 'Some::Class' && $x == 3;

I tend to think of blessed as a boolean -- not a replacement for ref (excepting if blessing into the empty string is something to check for).

And while it's a bit verbose, you could tackle the reftype bit this way:

my $r = ref( $value ) && reftype( $value );

That doesn't really gain you much over reftype( $value ) || q{} except maybe a moment's less thought for the next reader about why the empty string is the alternative if reftype is false.

-xdg

Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

Replies are listed 'Best First'.
Re^2: Why reftype and blessed are making my life harder than it needs to be
by dragonchild (Archbishop) on Feb 09, 2006 at 21:08 UTC
    Thank you! I completely missed that inequivalence. I've changed that test to now read:
    my $is_class = eval { $thing->isa( 'Some::Class' ) }; my $is_blah = $is_class && $x == 3;
    As for the reftype one ... I wonder if reftype can legally be anything other than GLOB/IO/ARRAY/HASH/CODE/REF/SCALAR? Meaning, q{} cannot legally be returned from reftype().

    My criteria for good software:
    1. Does it work?
    2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?

      Reading the code for it, it looks like it can't return q{}. If ref returns the empty string, reftype returns undef. Otherwise, it looks like it gives one of the underlying types. Looks like blessing into the empty string will still slip past reftype. (Bug or feature? You make the call...)

      -xdg

      Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

        So, should there be a patch to reftype() so that it returns one(qw{HASH ARRAY SCALAR CODE GLOB IO REF}) or the empty string?

        Why is reftype() even checking ref() in the first place ... reftype() is supposed to return the underlying representation, not the classname. I thought that's what blessed() is for.


        My criteria for good software:
        1. Does it work?
        2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
Re^2: Why reftype and blessed are making my life harder than it needs to be
by diotalevi (Canon) on Feb 10, 2006 at 05:20 UTC

    blessed() isn't a boolean because package names may be false: "" or "0". If you want a boolean, check for defined( blessed( ... ) ) instead. That's why blessed() returns undef on non-blessed: the "false" value of ref() is actually a valid true value.

    bless( ..., "\0" ); # "" bless( ..., 0 ); # "0"

    ⠤⠤ ⠙⠊⠕⠞⠁⠇⠑⠧⠊

      As I said, I tend to think of it as a boolean -- largely because I only use it in situations when I'm pretty sure I won't be blessing objects into "0" or "\0".

      Interestingly, reftype only checks the length of ref, which is why it can probably be fooled by "\0".

      -xdg

      Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

        Interestingly, reftype only checks the length of ref, which is why it can probably be fooled by "\0".

        You are looking at the perl implementation, which isn't quite what i would consider to the canonical implementation. IMO the canonical implementation is the XS one:

        char * reftype(sv) SV * sv PROTOTYPE: $ CODE: { if (SvMAGICAL(sv)) mg_get(sv); if(!SvROK(sv)) { XSRETURN_UNDEF; } RETVAL = sv_reftype(SvRV(sv),FALSE); } OUTPUT: RETVAL

        In Data::Dump::Streamer its implemented as

        char * reftype(sv) SV * sv PROTOTYPE: $ CODE: { if (SvMAGICAL(sv)) mg_get(sv); if(!SvROK(sv)) { XSRETURN_NO; } else { RETVAL = sv_reftype(SvRV(sv),FALSE); } } OUTPUT: RETVAL

        Notice the only difference is the XSRETURN_NO; versus XSRETURN_UNDEF;. With the benefit of experience IMO the use of XSRETURN_UNDEF; was a mistake. I've said as much on p5p a number of times, but without much response. I guess it would be too dangerous a change, which is why im going to be providing patches to implement _reftype() so you can say

        if (_reftype($foo) eq $TYPE) { ... }

        without worrying about warnings. Of course if you don't want to wait, you can always

        use Data::Dump::Streamer qw(reftype);

        And get the more practical implementation Right Now. :-)

        ---
        $world=~s/war/peace/g