Scalar::Util vs. ref function
What's the difference between the built in ref($object)
开发者_JS百科and Scalar::Util
blessed($object)
? Is one preferred over the other?
use strict;
use warnings;
use Scalar::Util qw(blessed isvstring);
my $object = foo->new();
print "Object is a " . blessed($object) . "\n";
print "Object is a " . ref($object) . "\n";
my $version = 5.00.03;
print "Version is a " . ref(\$version) . "\n";
if (isvstring($version)) {
print "Version is a VSTRING\n";
}
package foo;
sub new {
my $class = shift;
my $self = {};
bless($self, $class);
return $self;
}
According to POD, blessed()
only works on blessed references (e.g. a references passed to a bless()
call).
It returns undef
on everything else, including hash/array refs where ref()
returns HASH
/ARRAY
(and a bunch of other types as delineated in perldoc ref). To get reference type you can, of course call Scalar::Util::reftype
.
As for whether one should be used over another, I think it depends largely on what the logic is.
If you only want to distinguish real blessed references from everything else,
blessed()
provides a more concise way than taking aref
and then verifying that the value is not on of standard ones returned by unblessed reference.my $ref_type = ref($my_ref); print "USING REF: "; if ( $ref_type && $ref_type ne ref({}) && $ref_type ne ref([]) && $ref_type ne "SCALAR" # Could also use a hash with all allowed values of ref() instead && $ref_type !~ /^(CODE|REF|GLOB|...)$) { print "I am an object of class $ref_type\n"; } else { print "I'm a reference of type $ref_type\n"; } # vs... print "USING SCALAR_UTIL: "; my $ref_type = blessed($my_ref); print $ref_type ? "I am an object of class $ref_type\n" : "I am a reference of type " . reftype($my_ref) . "\n";
If you need fine distinctions between both blessed references and different ublessed ones, then a single
ref()
call is more concise than a combination ofblessed
andreftype
.One edge case where there's an actual functional difference between the two approaches, as noted in the comments by Eric Strom, is when someone creates a class which matches one of
ref()
hardcoded values (e.g.bless [], 'HASH'
- in which case they are either Way Dumb or Way Too Clever By Half).my $sssft = bless [], 'HASH'; # sssft = someone_should_suffer_for_this ref_description_using_ref($sssft); ref_description_using_scalar_util($sssft); # OUTPUT: USING REF: I'm a reference of type HASH USING SCALAR_UTIL: I am an object of class HASH
DISCLAIMER: Based on documentation, there should be no difference between the two when the argument is a reference blessed into a class (e.g. it returns class name). But I haven't checked "Scalar::Util" source to confirm.
精彩评论