Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

debugging

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?

like image 981
John Avatar asked Jan 19 '10 04:01

John


People also ask

How do you know what type of object it is?

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.

How do I find the type of a variable in Perl?

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...

Does Perl have objects?

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.


Video Answer


3 Answers

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.

like image 164
Axeman Avatar answered Sep 28 '22 14:09

Axeman


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.

like image 29
friedo Avatar answered Sep 28 '22 14:09

friedo


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.

like image 23
Joe McMahon Avatar answered Sep 28 '22 16:09

Joe McMahon