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

SYNOPSIS
     {
         # set common style for all objects created
         use Data::Dumper::EasyOO (indent => 1);

         # build an EzDD object, adding print-styles
         my $ezdd = Data::Dumper::EasyOO->new (terse => 1);
     
         # use the same ezdd obj repeatedly
         print "default: ", $ezdd->($_) for @userdata;
     
         # label it $foo, not $VAR1
         print $ezdd->(foo => $_) for @userdata;
     
         # alter printing style using DD API
         $ezdd->Terse(0);
         print "default: ", $ezdd->($_) for @userdata;
     
         # alter many print styles at once
         $ezdd->Set (terse=>0, sortkeys=>1);
         print "default: ", $ezdd->($_) for @userdata;

         # set autoprint to STDOUT
         $ezdd->Set (autoprint => 1);
         $ezdd->( you_used_pkgs => \%INC);

         # set autoprint to an opened filehandle
         $ezdd->Set (autoprint => $fh);
         $ezdd->( you_used_pkgs => \%INC);
     }

DESCRIPTION
    This package wraps Data::Dumper, and gives an object thats as easy to
    print with as Dumper(), DDs exported procedural interface. Its also easy
    to control print-style, as theyre set within the EzDD object.

    In this document, I use DD as shorthand for Data::Dumper, DD-OO for DD's
    object oriented API, and EzDD for *this* class. Despite the package
    name, I assume some knowledge about DD, at least wrt explaining why EzDD
    is better.

    In DD-OO, you must provide new() with the data to print, then change
    print-style, then print. This 3 step usage tends to be verbose. Because
    theres no (currently documented) way to un-bind the data, most users
    just toss the DD object.

    In contrast, EzDD is geared for object reuse, just think of it like a
    printer; print-style is analogous to color, paper-size, etc. You just
    build an object for each different print style you want, and use them
    repeatedly. A single EzDD object is enough for most users.

FEATURE COMPARISON
    In the following, I compare EzDD to either or both DD and DD-OO. This
    section is meant to be somewhat cursory; the next section delves a bit
    deeper.

  construct the EzDD object (overhead)
    To use EzDD, you have to (blow a line of code to) create an EzDD object,
    but you can initialize it once and for all, with less typing than with
    DDs package vars.

        new:   $ezdd = Data::Dumper::EasyOO->new(indent=>1,sortkeys=>1);
        old: {
            $Data::Dumper::Indent = 1;
            $Data::Dumper::Sortkeys = 1;
        }

    You can reduce this 'overhead' too; see "Auto-Construction" in FEATURES

  EzDD printing takes less typing
    Once your $ezdd object is built, printing is as easy as using Dumper().
    Note that $ezdd doesnt even need a method name !

        new:   print $ezdd->($foo);
         dd:   print Dumper ($foo);
      dd_oo:   print Data::Dumper->Dump($foo);

    Using autoprint mode, you can drop the 'print'

        $ezdd->Set(autoprint=>1);
        $ezdd->($foo);              # prints to STDOUT

  Easier Labelling of Data
      old: print Data::Dumper->Dump ( [$a,$b,$c], [qw(a b c)] );
      new: print $ezdd       ->     ( a=>$a, b=>$b, c=>$c )

    Labelling data wih DD-OO is counterintuitive; most perl users like and
    expect to see "labelled => $data". DD-OO is also too punctuation
    intensive, too dependent on having exactly 2 arrayref args, and having
    them the same length. And Dumper() cannot label data at all.

  You can independently control print-style on each object
    With Dumper(), print-style is controlled either globally, or by
    localizing a set of variables. With EzDD, print-style can be set on the
    object. This is a big advantage when you want 2 styles simultaneously.

      DD: {
          local $Data::Dumper::Indent = 1;
          local $Data::Dumper::Sortkeys = 1;
          print Dumper (\@foo);
      }
      new: {
          $ezdd->Set(indent=>1,sortkeys=>1); # do once on obj
          print $ezdd->(\@foo);
      }

    The next example shows DD_OO style control. Its tedious if you have to
    do it each time you want to print.

  You can print repeatedly with same object
    In DD-OO, you must provide the data to be dumped when the object is
    created, only then can the print-style be changed. This means lots of
    extra typing and method calls, thus discouraging use of OO style.

      EzDD: {
          $d->Set(indent=>1,deepcopy=>1);
          print $d->($_) foreach @data;
      }
      DD_OO:
        foreach $datum (@data) {
            $d = Data::Dumper->new($datum);
            $d->Sortkeys(1)->Indent(1)->Deepcopy(1);
            print $d->Dump;
        }

FEATURES
  Controlling Print Style for objects
    With EzDD, you control print style of single objects, either by
    speifying at creation, or altering thereafter.

        $ezdd = Data::Dumper::EasyOO->new(%printOptions);
        $ezdd->Set(%newprintOptions);       # update many
        $ezdd->Indent(1);                   # update by DDs methods
        $ezdd->Terse(1)->Sortkeys(1);       # update in chains (like DD)

    These settings stay with the object thru its lifetime, and are
    independent of other objects settings. If you dont set preferences as
    above, DDs globals are used by default.

  Controlling Print Style via use
    Print style can also be set at use-time, these are defaults for every
    object built thereafter. They can be overridden for individual objects,
    by any of new(), Set(), or DDs style-setting methods.

    The styles are saved separately for each package using EzDD, so Foo.pm
    and Bar.pm can have a different styles.

  Easy Labelling for your Data
        print $ezdd->(@args);

    @args are treated as pairs of labelled data if possible; ie if arglist
    is even length, and if the 'labels' are scalars. If you have an array
    (of scalars) that is incorrectly printed as labelled data, you can force
    things by passing its ref; ie $ezdd->([0..3]) vs $ezdd->((0..3)).

    This maybe a bit aggressive for your tastes, but I dont use DD with
    simple scalars (except by accident ;-) and my habit with Dumper() is to
    always pass a single data-arg anyway, ex \@foo. YMMV. FWIW -
    DD::Dumper() also does this; it calls Data::Dumper->Dump([@_]). For more
    specifics, check t/labels.t or the code.

  Auto-Printing
    Autoprinting allows you to drop the 'print':

        use Data::Dumper::EasyOO ( autoprint => 1 );
        my $ez = Data::Dumper::EasyOO->new();
        $ez->('the-includes' => \%INC);

    The autoprint property can be 1 for STDOUT, 2 for STDERR, an open
    FileHandle, or any object that can print; EzDD will write to it
    accordingly. You can also change this afterwards.

        my $ez = EzDD->new(autoprint => 2);         # set in ctor
        $ez->Set(autoprint => 2);                   # change during use

  Auto-Construction (needs perlio)
        use Data::Dumper::EasyOO ( %styles, init => \our $foo );
        $foo->( included_modules => \%INC );

    You can get a pre-built object by passing 'init', and a reference to a
    variable in which you want the EzDD object. The object is constructed
    for you, and initialized with the style options you supply.

  Copy-Construction
    You can also clone an existing EzDD object, and optionally alter its
    (the new object) style-options.

        my $newEzDD = $EzDD->new(%newStyleOverrides);

  Speed
    Dumper() builds a new DD object for each print, and this has non-zero
    runtime costs. Ive included a benchmark in the testsuite which shows 3%
    to 24% improvement on a linux 686 laptop, using the small data chunks I
    used for testing. With large data sets, printing time dominates, and the
    improvement drops asymtotically to 0%.

INTERFACE
    As I hope is clear by now, $ezdd->($data) renders the data.

    new(%printOptions) creates a new EzDD object, and calls Set() to
    establish desired printing behavior of that instance.

    Set(%printOptions) alters the print style of an existing EzDD object. It
    accepts option names matching the methods that DD provides, and
    lowercase versions of them. %option values are validated by EzDD,
    against package vars initialized based on DD's version. This is hackish,
    and probably incorrect in a few cases.

    Set() also does not provide accessor functionality; most DD methods
    return the DD object in support of method chaining, they cannot return
    the attribute values.

    AUTOLOAD() allows you to invoke the familiar DD methods on an EzDD
    object, its a convenience method which calls Set().

    pp() and dump() are methods to "pretty-print". The names were borrowed
    from "Data::Dump"

IMPLEMENTATION
    The class builds a blessed CODEref object, for which perl also allows
    method-lookups. This hybrid nature is key to the viability of the
    design.

    new() builds a private Data::Dumper object, then builds and returns a
    closure on that object. The closure provides the printing interface
    directly, methods do the rest.

POSSIBLE APPLICATIONS
    A client-class dumper. You can create one or a few EzDD objects in your
    Foo.pm module, and tailor them to serialize Foo objects however you
    like. With Sortkeys, you can serialize only the object keys you want,
    for persistent storage, or for debugging purposes. Maxdepth, Varname,
    etc are all similarly usable.

BUGS
    EasyOO relys on Data::Dumper, so if youre using 5.00503 and havent
    upgraded DD, some print-style controls wont be available.

    Validation of DD methods is based on checks of $DD::VERSION, and may
    have a few errors, or may miss a few DD versions between original and
    current.

    Some allowed methods may be nonsense in this context; I havent used them
    all myself in real-life, or in tests.

    Theres no accessor functionality for print-styles.

CAVEATS, Enhancements, TBD, TBC
    method-less invocation may be over-cool.
        This was an experiment (in blessed coderefs) that went well enough
        to continue. If this feature makes you itch, you can use $ezdd->pp()
        $ezdd->dump() instead.

    Brand new code, with the usual caveats.
        Tested OK against 5.005_03, 5.8.2, and many in between, both
        threaded and unthreaded.

    Too much dependency on DD
        The down-side of 5.00503 compatibility is that DD was less capable
        back then. Some modern usages on an ancient DD have been reported
        and fixed, but others may lurk.

    No validation on %printOptions values.
        If DD expects a particular value type, you must provide it; I do no
        checking, and rely on DD to complain as fitting.

        If DD carps about stuff passed in, it may blame EzDD, as it will
        probably use carp(), and EzDD is the using package. I regard this as
        a user error, youve been warned. I will accept patches though.

    format control not per-use, but on object only
        You cant localize print options for 1 usage. This is because those
        DD pkg vars, localized or not, are copied into the DD object when
        its constructed, and are thereafter ignored by that object. This
        *could* be fixed by changes to DD, but I dont see the value, Id
        anticipate a slowdown, and I dont expect DDs maintainer would accept
        that.

    auto-labelling may be overzealous.
        In particular, "$ezdd->(1,2,3,4)" will treat 1,3 as labels. You can
        prevent this by doing "$ezdd->([1,2,3,4])" instead.

    Reporting of illegal methods can change capitalization
        Modulo lc() and ucfirst() differences, all DD style method-names are
        reflected in DD object attributes. This makes it handy to be
        cavalier wrt method vs attribute vs package-var, but this can be
        slightly confusing wrt reporting of usage errors.

    add no_reset option
        EzDD uses $ddo->Reset so that $ddo can be reused. a no_reset option
        would allow you to defeat that. The internal flag 'ddez_noreset'
        already exists, but is incomplete; the details are subject to
        change.

To Be Considered
    AUTOLOAD() accessor mode
        This conflicts with support for method-chaining (ie returning the
        object so it can be chained). Since DD supports it, we should too.

        It may be possible by defining sub _get($prop), calling it from
        AUTOLOAD if not @args. This would break chaining for accessors, but
        thats 'broken by design' anyway.

    Sortkeys as hashref
        If sortkeys was a hashref (with arrayref values), the keys *could*
        specify applicability of the arrayref based upon the data being
        dumped; its type, depth, tag, etc.. See "Possible Applications".

        Reasons not to bother: The key would need som XPath-ish form, which
        may be sufficient reason to kill the idea at birth. It would also
        need DD support, at very least a callback scheme.

    blessed alias
        I find it unfortunate that bless takes class-name as 2nd arg; its
        tedious to scroll to the bottom of a large object just to know its
        type. I may someday add an alias to reverse them..

  Comments welcome.
    Whats overkill ? Certainly some of this.

SEE ALSO
    Data::Dumper is used internally (you know by now ;-). If you really want
    to, you can reuse DD objects without this module. See the code for how
    to do so.

    Data::Dump also has a simple interface, ie a single function, imported
    as dump() or pp(). It doesnt have print-style controls, and doesnt have
    DDs evaluable output, so its not directly usable in place of DD, where
    this is. On the other hand, its output is magically data-dependent; if
    the data fits on a single line, it gets printed that way.

ACKNOWLEDGMENTS
    Gurusamy Sarathy for writing DD, I love it and use it *ALL* the time,
    its often my microscope of choice. I cant leave the above critique as
    the only commentary.

AUTHOR
    Jim Cromie <jcromie@cpan.org>

    Copyright (c) 2003 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.

    I dont suppose I'll ever recover the (modest) development time via
    reduced keystrokes, but CPAN has saved me so much already; heres a
    little give-back. And besides, perl is fun, like an always-new toy.

