Search code examples
perldebugging

How to find which type of object I have on Perl?


How can I find which object type I am dealing with in Perl? I tried using perl -d to enter the debugger, but I'm not sure what to do then. Likewise I'd like a way to easily see which methods are available for each object, how can that be done?


Solution

  • The standard way for telling what type of object you have is either ref or Scalar::Util::blessed. If you know the object is blessed, then they return the same information.

    my $class1 = blessed( $obj );
    my $class2 = ref $obj;
    

    But ref will also return 'HASH' for unblessed hashes, while blessed refuses to play that game.

    As for a list of methods, for the blessed pointer style of perl object, it's easy enough to code one up yourself. The code below works fairly well for me. It returns the names of functions (those taking the "CODE slot" of the given name) mapped to the package which defines them.

    sub class_methods { 
        use Class::ISA;
        my $obj = shift;
        return unless ref( $obj );
        my %meth_names;
        foreach my $anc ( Class::ISA::self_and_super_path( ref $obj ), 'UNIVERSAL' ) {
            my $stash = \%{"$anc\::"};
            my @funcs 
                = grep { m/^[_\p{Alpha}]/                # begins with _ or alpha
                       && !exists $meth_names{$_}        # no clobbering
                       &&  defined *{$stash->{$_}}{CODE} # has a filled CODE slot
                       } keys %$stash
                ;
            # assign to the "hash slice", keyed by all the entries in @funcs
            # the value of $anc repeated as many times as elements in @funcs.
            @meth_names{@funcs} = ( $anc ) x @funcs;
        }
        return %meth_names;
    }
    
    • This will work for reasonably complex objects as well, but if the owning package contains a lot of generated code, it's not going to be that helpful to know which package the generators stuck the code pointer in. It's going to mean more to find what package generated the code.

    • This being the case, you might get the code out of running your code, including Data::Dumper and setting $Data::Dumper::Deparse to 1, like so: ( local $Data::Dumper::Deparse = 1;) and then dumping the code pointer, like so: say Dumper( $code_ref );

    • It WON'T work for valid methods that have yet to be created by any AUTOLOAD methods. If you see those in the list, the object might do more, but what all it does, you don't know.

    • The "base class" UNIVERSAL is included, because that class contains behavior usable by the object.

    Good luck.