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

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"

⠤⠤ ⠙⠊⠕⠞⠁⠇⠑⠧⠊

  • Comment on Re^2: Why reftype and blessed are making my life harder than it needs to be
  • Download Code

Replies are listed 'Best First'.
Re^3: Why reftype and blessed are making my life harder than it needs to be
by xdg (Monsignor) on Feb 10, 2006 at 12:35 UTC

    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

        Unfortunately, Data::Dump::Streamer is 5.6+ (though you don't have a "use 5.006;" line before your "use warnings;" line). This came up in the context of me helping JHUCKABY with DBM::Deep and I want to keep DBM::Deep able to run with older Perls.

        It seems sad, though, that reftype() won't be patched to XSRETURN_NO, especially as that makes more sense. Also, why can't the Perl version be patched to at least return !!0 instead of explicit undef?


        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?