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 its 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 is brief 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); 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. Also, note that 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, or an open FileHandle, and will write accordingly. You can also change this afterwards. my $ez2 = EzDD->new(autoprint => 2); # set in ctor $ez->Set(autoprint => 2); # change during use Auto-Construction 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 not validated by EzDD, DD itself may do so, but I havent tested this, and make no promises. 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, and also provides (via special data value - slightly hackish) access to the underlying DD object for the other methods; Set() and AUTOLOAD(). 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 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 which place blame properly ;-) 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. not *entirely* data-agnostic "$ezdd->('__SA__')" will return underlying DD object, unlike all other data. This hackery is needed cuz the closure is the only handle to the DD object, unless Ive missed something. 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 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.