in reply to Hooks like Storable for Dumper?

By 'hook implementation', do you mean a function that causes Data::Dumper to serialize/output the data in a user-specifiable order? Or something else?

Jim Keenan

Replies are listed 'Best First'.
Re^2: Hooks like Storable for Dumper?
by xdg (Monsignor) on Jan 02, 2006 at 22:33 UTC

    In the case of Storable, the hook functions are responsible for returning a string that represents the data -- it's a custom serialization routine. It's not so much the order that matters, but for handling data that isn't part of a Perl data structure. That might be C data structures for an XS module, or -- for the purposes of the presentation -- an inside-out object where the reference is just an index and the real data is kept in lexical hashes that Storable doesn't know about.

    For Data::Dumper, etc., it's not clear how an inside-out object should be dumped as eval-able code. Object::InsideOut addresses this by providing it's own dump/pump routines that dump and recreate an object. However, that doesn't work well if some programmer throws an ordinary data structure with inside-out objects at Data::Dumper.

    use Some::InsideOut::Class; use Data::Dumper; my @list; for ( 1 .. 10 ) { push @list, Some::InsideOut::Class->new( data => $_ ); } print Dumper \@list;

    The earlier comment about Data::Dumper::Freezer suggests that there is probably a way to convert the inside-out object to a regular Perl data structure to be dumped. A couple problems that I see:

    • Programmers expect a dump to reflect the underlying code structure and the dump they get would be just a convenient fiction.

    • Registering the Freezer/Toaster requires loading Data::Dumper -- so regardless of whether a dump is ever called, just supporting Data::Dumper requires the overhead of loading it.

    -xdg

    Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

      Programmers expect a dump to reflect the underlying code structure and the dump they get would be just a convenient fiction.

      You can’t help that, can you? Going around diddling innards according to a Data::Dumper reading is a bad idea anyway; I don’t think you should feel obligated to support this notion. What you want to do is support Data::Dumper-based serialisation; that’s another matter altogether.

      Registering the Freezer/Toaster requires loading Data::Dumper – so regardless of whether a dump is ever called, just supporting Data::Dumper requires the overhead of loading it.

      How so? You can always assign a value to $Data::Dumper::Freezer, whether the module is loaded or not.

      sub f { warn }; $Data::Dumper::Freezer = 'f'; require Data::Dumper; Data::Dumper::Dumper( bless \$_, 'main' ); __END__ Warning: something's wrong at - line 1.

      The real problem I see is that multiple modules may want to use this hook, and they will probably all have a different idea of what the right value for $Data::Dumper::Freezer is.

      You could try to be a little more cooperative by using something like this:

      $Data::Dumper::Freezer = "DD_freezer" unless defined $Data::Dumper::Fr +eezer; *{; do { no strict 'refs'; \*{$Data::Dumper::Freezer} } } = sub { # serialisation code here };

      But that gives you no guarantee that everyone else will attempt to be similarly cooperative. :-/

      Makeshifts last the longest.

        The real problem I see is that multiple modules may want to use this hook, and they will probably all have a different idea of what the right value for $Data::Dumper::Freezer is.

        Good point. I misunderstood how $Data::Dumper::Freezer worked. I thought you had to do something like this and it registered per package:

        package Foo; use Data::Dumper; Data::Dumper->Freezer( "__FREEZE" ); # Incorrect! sub __FREEZE { # custom class dump here }

        It looks like it's just a global, which is even worse. (Unless you want to use Data::Dumper objects, which can have a per D::D object freezer, but that's doesn't help either.)

        As the discussion below suggests, I think Data::Dumper::Streamer comes closest with its FreezeClass handlers.

        -xdg

        Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.