简体   繁体   中英

Getting classname of a object in Perl

I have an object reference and it could be a reference to an object of type 'FooInvalidResults'

There is a file called FooInvalidResults.pm and there is a line 'package FooInvalidResults' in it.

will the following work?

my $class = blessed $result;
if ($class eq 'FooInvalidResults') {
  # do something
} else {
  # do something else
}

String-comparing class names is generally a bad idea, because it breaks polymorphism based on subtypes, and because it's generally not good OO practice to be that nosy about intimate details of an object like its exact package name.

Instead, write $result->isa('FooInvalidResults') — or, if you're paranoid about the possibility that $result isn't an object at all, blessed $result && $result->isa('FooInvalidResults') .

Using UNIVERSAL::isa is a bad idea because some objects (for instance, mock objects for testing) have legitimate reasons to override the isa method, and calling UNIVERSAL::isa breaks that.

Why didn't you use UNIVERSAL::isa ?

if UNIVERSAL::isa( $result, "FooInvalidResults" ) {
   ...
}

This was bad advice , please use

$obj->isa( 'FooInvalidResults' );

I wasn't full aware of the difference between subroutine call ( BAD ) and method call ( GOOD ), but it became clear after I did some RTFM myself ( perldoc UNIVERSAL ). Thanks ( and +1 ) to all folks that pointed out my fault.

It is also possible to do the job with the ref() builtin rather than Scalar::Util::blessed() :

$ perl -E '$ref = {}; bless $ref => "Foo"; say ref $ref'
Foo

Note that if the reference is not blessed, this will return the type of reference:

$ perl -E '$ref = {}; say ref $ref'
HASH

However, as others have mentioned, UNIVERSAL::isa is a better solution.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM