The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Data::Dumper::EasyOO - wraps DD for easy use of various printing styles

ABSTRACT

EzDD is an object wrapper around Data::Dumper (henceforth just DD), and uses an inner DD object to produce all its output. Its purpose is to make DD's OO capabilities easier to use, ie to make it easy to:

 1. label your data meaningfully, not just as $VARx
 2. make and reuse EzDD objects
 3. customize print styles on any/all of them independently
 4. provide essentially all of DD's functionality
 5. do so with fewest keystrokes possible

SYNOPSIS

1st, an equivalent to DD's Dumper, which prints exactly like Dumper does

    use Data::Dumper::EasyOO;
    print ezdump([1,3]);

which prints:

    $VAR1 = [
              1,
              3
            ];

Here, we provide our own (meaningful) label, and use autoprinting, and thereby drop the 'print' from all ezdump calls.

    use Data::Dumper::EasyOO (autoprint => 1);
    my $gl = { Joe => 'beer', Betsy => 'wine' });
    ezdump ( guest_list => $gl);

which prints:

    $guest_list = {
                    'Joe' => 'beer',
                    'Betsy' => 'wine'
                  };

And theres much more...

DESCRIPTION

EzDD wraps Data::Dumper, and uses an inner DD object to print/dump. By default the output is identical to DD. That said, EzDD gives you a nicer interface, thus encouraging you to tailor DD output the way you like it.

A primary design feature of EzDD is that you can choose your preferred printing style in the 'use' statement. EzDD replaces the usual 'import' semantics with the same (property => value) pairs as are available in new().

You can think of the use statement as a way to set new()'s default behavior once, and reuse those styles (or override and supplement them) on EzDD objects you create thereafter.

All of DD's style-setting methods are available in EzDD as both properties to new(), and as object methods; its your choice.

An easy use of ezdump()

For maximum laziness support, ezdump() is exported into your namespace, and supports the synopsis example. $ezdump is also exported; it is the EzDD object that ezdump() uses to do its dumping, and allows you to tailor ezdump()s print-style. It also lets you use OO style if you prefer.

Continuing from 2nd synopsis example...

    $ezdump->Set(sortkeys=>1);
    ezdump ( guest_list => $gl );
    print "\n";
    $ezdump->Indent(1);
    ezdump ( guest_list => $gl );

which prints:

    $guest_list = {
                    'Betsy' => 'wine',
                    'Joe' => 'beer'
                  };

    $guest_list = {
      'Betsy' => 'wine',
      'Joe' => 'beer'
    };

The print-styles are set 2 times; 1st as a property setting, 2nd done like a DD method. The styles accumulate and persist on the object.

FEATURES

The following features are discussed in OO context, but are nearly all applicable to ezdump() via its associated $ezdump object-handle.

Automatic Labelling of your data

EzDD 'knows' you prefer labelled => $data, and assumes that you've called it that way, except when you havent. Any arglist that looks like a list of pairs is treated as as such, by 2 rules:

  1. arglist length is even
  2. no candidate-labels are refs to other structures

so this labels your data:

  $ezdd->(person => $person, place => $place);

but this doesn't (assuming that $person is an object, not a string):

  $ezdd->($person, $place);

If you find that EzDD sometimes misinterprets your array data, just explicitly label it, like so:

    $ezdd->(some_label => \@yourdata);

DD::Simple does more magic labelling than EzDD (it grabs the name of the variable being dumped), but EzDD avoids source filtering, and gives you an unsuprising way to get what you want without fuss.

Dumping is default operation

EzDD recognizes that the only reason you'd use it is to dump your data, so it gives you a shorthand to do so.

  print $ezdd->dump($foo);      # 'long' way
  print $ezdd->pp($foo);        # shorter way
  print $ezdd->($foo);          # look Ma, no function name

It helps to think of an EzDD object as analogous to a printer; sometimes you want to change the paper-tray, or the landscape/portrait orientation, but mostly you just want to print.

Dumping without calling 'print'

To save more keystrokes, you can set autoprint => 1, either at use-time (see synopsis), or subequently. Printing is then done for you when you call the object.

    $ezdd->Set(autoprint=>1);   # unless already done
    $ezdd->($foo);              # even shorter

But this happens only when you want it to, not when you assign the results to something else (or return it into your own print statement)

    $b4 = $ezdd->($foo);        # save rendering in var
    $foo->bar();                # alter printed obj

    # now dump before and after
    print "before: $b4, after: ", $ezdd->($foo);

not Dumping when you dont want to

For laziness with greater impunity, ezdump() and friends will carp if you call them without printing (ie call them in void context). But if thats really what you want to do, set autoprint => 0 at use-time, and your calls will do nothing quietly.

Then when you want to enable dumping, perhaps with a cmd-line option, you can do so once per object, and they are all enabled. With this, you can declutter your dumping calls.

setting print styles (on existing objects)

You can set an object's print-style by imitating the way you'd do it with object oriented DD. All of DDs style-changing methods are emulated this way, not just the 2 illustrated here.

    $ezdd->Indent(2);
    $ezdd->Terse(1);

You can chain them too:

    $ezdd->Indent(2)->Terse(1);

setting print styles using Set()

The emulation above is really dispatched to Set(); those 2 examples above can be restated:

    $ezdd->Set(indent => 2)->Set(terse => 1);

or more compactly:

    $ezdd->Set(indent => 2, terse => 1);

Multiple objects' print-styles can be altered independently of each other:

    $ez2->Set(%addstyle2);
    $ez3->Set(%addstyle3);

For maximum laziness, mixed-case versions of both method calls and properties are also supported.

Creating new printer-objects

Create a new printer, using default style:

    $ez3 = Data::Dumper::EasyOO->new();

Create a new printer, with some style overrides that are passed to Set():

    $ez4 = Data::Dumper::EasyOO->new(%addstyle);

Clone an existing printer:

    $ez5 = $ez4->new();

Clone an existing printer, with style overrides:

    $ez5 = $ez4->new(%addstyle2);

Dumping to other filehandles

    # obvious way
    print $fh $ezdd->($bar);

    # auto-print way
    $ezdd->Set(autoprint => $fh);
    $ezdd->($bar);

You can set autoprint style to any open filehandle, for example \*STDOUT, \*STDERR, or $fh. For convenience, 1, 2 are shorthand for STDOUT, STDERR. autoprint => 0 turns it off.

TBC: autoprint => 3 prints to fileno(3) if it's been opened, or warns and prints to stdout if it hasnt.

Namespace aliasing

Data::Dumper::EasyOO is cumbersome to type more than once in a program, and is unnecessary too. Just provide an alias at use-time, and then use that alias thereafter.

   use Data::Dumper::EasyOO ( alias => 'EzDD' );
   $ez6 = EzDD->new();

use-time object initialization

If calling $ez1 = EzDD->new is too much work, you can initialize it by passing it at use time.

    use Data::Dumper::EasyOO ( %style, init => \our $ez );

By default, $ez is initialized with DD's defaults, these can be overridden by %style.

If you want to store the handle in my $ez, then declare the myvar prior to the use statement, otherwize the object assigned to it at BEGIN time is trashed at program INIT time.

    my $ez;
    use Data::Dumper::EasyOO ( init => \$ez );

use-time multi-object initialization

You can even create multiple objects at use-time. EzDD treats the arguments as an order-dependent list, and initializes any specified objects with the settings seen thus far. To better clarify, consider this example:

  use Data::Dumper::EasyOO 
    (
     alias => EzDD,
     # %DDdefstyle,     # since we use a DD object, we get its default style
     %styleA,
     init => \$ez1,     # gets DDdef and styleA
     %styleB,
     init => \$ez2,     # gets DDdef, styles A and B
     %styleC,
     init => \$ez3,     # gets DDdef, styles A, B and C
     %styleD,
     );

This is equivalent:

  use Data::Dumper::EasyOO (alias => 'EzDD');
  BEGIN {
    $ez1 = EzDD->new(%DDdefstyle, %styleA);
    $ez2 = EzDD->new(%DDdefstyle, %styleA, %styleB);
    $ez2 = EzDD->new(%DDdefstyle, %styleA, %styleB, %styleC );
  }

Each %style can supplement or override the previous ones. %styleD is not used for any of the initialized objects, but it is incorporated into the using package's default style, and is used in all new objects created at runtime.

Each user package can set its own default style; you can use this, for example, to set a different sortkeys => \&pkg_filter for each. With this, YourReport::Summary and YourReport::Details can dump the info appropriate for your needs.

re-importing to change print-style defaults

If you decide during runtime that you dont like your use-time defaults, just call import again to change them. All newly built objects will inherit those new print-styles.

A FEATURE-FULL EXAMPLE

This is a rather over-the-top usage.

1st, it sets an alias, with which you can shorten calls to new(). 2nd, it sets several of my favorite print styles. 3rd, it initializes several dumper objects, giving each of them slightly different print-styles.

 my $ezdd;      # declare a handle for an object to be initialized

 use Data::Dumper::EasyOO
    (
     alias      => EzDD,        # a temporary top-level-name alias
     
     # set some print-style defaults
     indent     => 1,           # change DD's default from 2
     sortkeys   => 1,           # a personal favorite

     # autoconstruct a printer obj (calls EzDD->new) with the defaults
     init       => \$ezdd,      # var must be undef b4 use

     # set some more default print-styles
     terse      => 1,           # change DD's default of 0
     autoprint  => $fh,         # prints to $fh when you $ezdd->(\%something);

     # autoconstruct a 2nd printer object, using current print-styles
     init       => \our $ez2,   # var must be undef b4 use

     alias      => Ez2,         # another top-level-name alias
     );

 $ezdd->(p1 => $person);        # print as '$p1 => ...'

 my $foo = EzDD->new(%style)    # create a printer, via alias, w new style
    ->(there => $place);        # and print with it too.

 $ez2-> (p2 => $person);        # dump w $ez2, use its style

 $foo->(here => $where);        # dump w $foo style (use 2 w/o interference)

 $foo->Set(%morestyle);         # change style at runtime
 $foo->($_) foreach @things;    # print many things

Other conveniences

dump() and pp()

These are both object methods, and are aliases which provide a familiar invocation for users of Data::Dump.

  # these are all the same
  $ezdump->(\%INC);
  $ezdump->pp(\%INC);
  $ezdump->dump(\%INC);

IMPORTS

This module pollutes the users namespace with 2 symbols: $ezdump and &ezdump. In the context of maximum easyness, this is construed to be a feature.

Caveats, Todos, Tobe Considered

The layering of defaults takes some getting used to. However, the complexity is not a bug, its a feature.

Print-style defaults are stored in EzDD for each user package. This does not permit aliases to have separate defaults, which could be useful. This is fairly straightforward, and may be added in the future.

Aliases could be treated like object 'init's, in that they could get defaults based upon the print-styles seen thus far in the use-time arguments. The difficulty with this idea is that it changes the declarative flavor of aliases. In the featureful example above, the EzDD alias appears before the various print-style settings, so they would not apply to it, but only to the 2nd alias, Ez2.

BUGS

If you 'use strict' and this module together, you may get weird errors; similar to the following. The last ones in particular are odd, since the code has NO variable named $class.

 Variable "$ezdump" is not imported at t/ezdump-strict.t line 18.
  at t/ezdump-strict.t line 18
        (Did you mean &class instead?)
  at t/ezdump-strict.t line 18
 Variable "$ezdump" is not imported at t/ezdump-strict.t line 18.
  at t/ezdump-strict.t line 18
        (Did you mean &ezdump instead?)
  at t/ezdump-strict.t line 18
 Global symbol "$class" requires explicit package name at t/ezdump-strict.t line 18.
 Global symbol "$ezdump" requires explicit package name at t/ezdump-strict.t line 18.

I dont know the root cause of this, but the solution is simple; predeclare the $ezdump variable, as is done in t/ezdump-strict.t (the file proves that explicit importing of those default imports doesnt fix the oddity shown above).

SEE ALSO (its a crowded space, isnt it!)

 L<Data::Dumper>                the mother of them all
 L<Data::Dumper::Simple>        nice interface, basic feature set
 L<Data::Dumper::EasyOO>        easyest of them all :-)
 L<Data::Dump>                  has cool feature to squeeze data
 L<Data::Dump::Streamer>        highly accurate, evaluable output
 L<Data::TreeDumper>            lots of output options

AUTHOR

Jim Cromie <jcromie@cpan.org>

Copyright (c) 2003,2004,2005 Jim Cromie. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.