Re: Why reftype and blessed are making my life harder than it needs to be
by xdg (Monsignor) on Feb 09, 2006 at 21:01 UTC
|
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.
| [reply] [d/l] [select] |
|
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:
- Does it work?
- Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
| [reply] [d/l] |
|
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.
| [reply] [d/l] [select] |
|
|
|
bless( ..., "\0" ); # ""
bless( ..., 0 ); # "0"
| [reply] [d/l] |
|
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.
| [reply] [d/l] [select] |
|
|
|
Re: Why reftype and blessed are making my life harder than it needs to be
by merlyn (Sage) on Feb 09, 2006 at 20:35 UTC
|
Since the empty string is a valid blessed class, reftype and blessed are doing the right thing there by using undef when the value is not blessed. Otherwise, how would you distinguish the empty blessing from the unblessed,
religious overtones notwithstanding?
| [reply] [d/l] [select] |
|
Since the empty string is a valid blessed class
No, it's not. If the second argument of bless is the empty string, the thing being blessed is blessed into main. If you turn on warnings, Perl will tell you so.
Otherwise, how would you distinguish the empty blessing from the unblessed, religious overtones notwithstanding?
That's easy. blessed returns main in the first case, and so does ref. ref returns the empty string if its argument isn't a reference - and that's never ambigious, and hence there would be any ambiguity if blessed would do the same.
#!/usr/bin/perl
use strict;
use warnings;
use Scalar::Util 'blessed';
my $ref = bless [], "";
print ref $ref, "\n";
print blessed $ref, "\n";
__END__
Explicit blessing to '' (assuming package main) at "..." line 8.
main
main
| [reply] [d/l] |
|
| [reply] [d/l] |
|
|
|
|
|
Since the empty string is a valid blessed class
No, it's not. If the second argument of bless is the empty string, the thing being blessed is blessed into main. If you turn on warnings, Perl will tell you so.
I'm pretty sure you can bless into "" from XS code. Didn't go so far as to try it though.
| [reply] |
|
That's fair enough. So, how would you recommend I handle the cases I bring up?
My criteria for good software:
- Does it work?
- Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
| [reply] |
Re: Why reftype and blessed are making my life harder than it needs to be
by demerphq (Chancellor) on Feb 09, 2006 at 20:22 UTC
|
Actually its really weird you bring this up today. Ive encountered this annoyance before and ended up writing my own reftype for Data::Dump::Streamer which returns an Pl_no when the item isn't a ref. And I just a few hours ago wrote on my todo list that this should be included in Scalar::Util as _reftype(). Unfortunately the Pl_no logic doesnt work with blessed as '0' and '' are both valid (but evil) classnames.
Anyway, if you want to avoid this problem you can use DDS::reftype() instead.
---
$world=~s/war/peace/g
| [reply] |
Re: Why reftype and blessed are making my life harder than it needs to be
by Jenda (Abbot) on Feb 09, 2006 at 21:05 UTC
|
I may be missing something, but isn't the difference that the isa($thing, 'Some::Class') returns true even if the $thing is blessed into a subclass of the Some::Class while the blessed($thing) eq 'Some::Class' is true only for $things blessed directly to Some::Class more important than whether you have to do something to silence use warnings 'uninitialized';?
| [reply] [d/l] [select] |