http://www.perlmonks.org?node_id=1043060

QM has asked for the wisdom of the Perl Monks concerning the following question:

I'm looking for a (free) object browser for Perl. Something that will let me see changes in an object, either in a debugger session, or comparing object dumps such as from Data::Dumper.

Did I miss something obvious in my search?

Currently I'm running in a remote environment, where a debugger is problematic, so I've been dumping objects at different execution points, and diffing the results after the run.

-QM
--
Quantum Mechanics: The dreams stuff is made of

Replies are listed 'Best First'.
Re: Object Browser for Perl?
by rjt (Curate) on Jul 08, 2013 at 10:32 UTC

    I'm afraid I'm not really sure what it is you're after. You say you want to look at changes in an object, perhaps in a debugger session, but then you say "a debugger is problematic". What am I missing?

    At the risk of offering advice that's too general for your query, I have found the likes of Data::Dumper (or more recently Data::Dump) to be more than sufficient for my data inspection needs, from the simple to the arcane. Both are extensible enough to flex to almost any whim. Depending on the type of application or module, and its stage of development, where I actually send those dumps changes. Usually (and this includes headless serial terminals), I can find a way to snag Perl's output in a shell, log, or web output, which is good enough for me.

    And usually, my tests hit the mark reasonably well, so typically my "live" debugging is rather minimal.

    What is it in particular about your current project that renders all of this impossible or prohibitively inconvenient? Perhaps I can offer more specific advice with a better description.

      Examining objects, especially changes to objects between runs, is problematic because:

      (1) There is a lot of data in an object, so complete Data::Dumper output runs hundreds or thousands of lines. I can reduce this with 'depth', but then runs may not be so easily compared, as truncated object trees end with 'key' => 'Blah::Foo::Bar=HASH(0xdeadbeef)'. (Not such a big win anyway, since internal pointers dump as $VAR1->{blah}.) I could also give a list of interesting keys to dump, which requires another iteration.

      (2) I'm using a large library, that I'm only superficially acquainted with, that adds lots of uninteresting data to the objects in many places. It would probably be easier if the library added stuff under a top-level key like 'internal_machinations', where I seldom need to access anything from my code.

      (3) There's a shared resource key at many levels, pre-arranged so that $self->{'resource'} points to the same instance, regardless of $self. So in some cases I have to worry about clobbering existing data there, etc.

      (4) There are very few accessors in the large library, and only for specific, often-used attributes.

      -QM
      --
      Quantum Mechanics: The dreams stuff is made of

        ++ and thanks for the additional details, QM. It sounds like Data::Dump (and Data::Dump::Filtered) will do what you want, if you give it a bit of help. Here's a documented example that should get you going:

        Full example source

        Output:

        Before: ---------------------------------------------------------------------- +------ do { my $a = bless({ attr1 => "val1", circular_ref => 'fix', however => { this => { unwanted => bless({ is => "actually wa +nted" }, "Unwanted") }, }, internal_ref => 'fix', resource => bless({ 1 => 2, 11 => 12, 13 => 14, 15 => 16, 17 => 18, 19 => 20, 3 => 4, 5 => 6, 7 => 8, 9 => 10, note => "Defined outside \$hairy_object", }, "Singleton::Resource"), Silly => { complex => { references => "can be mangled", so +=> "they make more sense." }, }, unwanted => bless({ thing => "We want to ignore" }, "Unwanted" +), }, "Hairy::Object"); $a->{circular_ref} = $a; $a->{internal_ref} = $a->{however}{this}; $a; } After: ---------------------------------------------------------------------- +------ $a = bless( { attr1 => "val1", circular_ref => 'fix', however => # Here, there be dragons { this => { unwanted => bless({ is => "actually wanted" }, "Unwant +ed") }, }, internal_ref => 'fix', resource => $singleton, Silly => "references can be mangled so they make more sense.", }, "Hairy::Object"); $a->{circular_ref} = $a; $a->{internal_ref} = $a->{however}{this};
Re: Object Browser for Perl?
by hdb (Monsignor) on Jul 09, 2013 at 09:00 UTC

    For interactive inspection of objects it would be useful to be able to fold sections of the object. One way could be to dump the object in some kind of xml format and use an xml editor to close and open sections of the object. In order to create xml, XML::Simple is too simple as keys of hashes make not automatically valid xml tags. I am not aware of a simple xml creator for an arbitrary structure, so I tried to roll my own:

    The dispatch table gives you a lot of flexibility. Any unknown structures will be processed in the 'default' section and you will not see any details. If you want to see the details you just need to add a rule how to deal with it. The 'HASH' rule should work for blessed references as shown in the XML::Simple example.

    What one probably wants to add is a facility to write it into file instead of STDOUT but that should be simple.

    It is no good for diffing across runs as it prints the memory locations as well that I expect not to be constant across runs.

Re: Object Browser for Perl?
by tobyink (Canon) on Jul 08, 2013 at 16:10 UTC

    Hmmm... sounds like a fun project. :-)

    Update: check out Data::Dumper::GUI.

    package Cow { use Moo; has name => (is => 'lazy', default => sub { 'Mooington' }) } say Cow->new->name