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?
Use the typeof operator to get the type of an object or variable in JavaScript. The typeof operator also returns the object type created with the "new" keyword. As you can see in the above example, the typeof operator returns different types for a literal string and a string object.
Perl provides the ref() function so that you can check the reference type before dereferencing a reference... By using the ref() function you can protect program code that dereferences variables from producing errors when the wrong type of reference is used...
An object within Perl is merely a reference to a data type that knows what class it belongs to. The object is stored as a reference in a scalar variable. Because a scalar only contains a reference to the object, the same scalar can hold different objects in different classes.
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.
The blessed
function from Scalar::Util will tell you the package name of any blessed reference (an object.)
To find out what methods are available, consult the documentation for that package. Alternatively, you can use something like Class::MOP::Class to instantiate a metaclass and get introspective information about the methods it contains.
Just for completeness, here's a very short intro to the debugger.
perl -d your_program
starts it under the bugger. You'll get control at the first executable line (use statements and the like have already executed at this point).
's' will step to the next line. Once you've entered an 's', you can simply press return to repeat it. 's' will step down into functions/subroutines/methods. Either keep stepping till you return or enter the 'r' command to execute the rest of the function and return to right after the call.
If you want to step 'over' subroutines - that is, execute them and return without having to step in and return, use 'n. The carriage return after the first 'n' also keeps doing 'n' for you.
If you know the line where you want to stop, use the 'b' command - b linenumber - to set a breakpoint, then 'c' to continue till you reach it. Note that every time you 'c' and come back to the breakpoint you will stop again. Use 'B linenumber' to turn the breakpoint back off.
So let's assume you've gotten to something like this:
my $obj = complex_function_returning_unknown_thing;
The debugger's just shown you this line, which says "I have not executed this yet, but it is what I will do next." Enter 'n' to execute the subroutine, then use the 'x' command to look at the object: 'x $obj'. If it's big, you can say '|x $obj' which runs the output through a pager. To see what methods the object has, use 'm $obj'.
There's a lot more to the debugger, but you can indeed use it for this kind of thing - you need to simply see the type of an object you're getting from some code and find out what methods the object you got has.
It may be more useful to 'x' the object, and then go look at the source of the class the object's been blessed into to find out what you should do as opposed to what you can do. The 'x' command is pretty much 'print ref($obj)' crossed with Data::Dumper anyway.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With