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

Hi all I have a large data structure that I want to store to disk. I was planning to use the excellent module, however on a closer look it doesn't work with references to CODE.
i.e @database=( { "group" =>"1", "pattern" =>'lizard', "function" =>sub { print "hello\n"; }, }, );
From the docs.....'You can't store GLOB, CODE, FORMLINE, etc... If you can define semantics for those operations, feel free to enhance Storable so that it can deal with them.' Its that last bit that's caught my interest. I looks like I can define semantics so that Storable can cope. Does anyone know what this means ? Can any one point me to an example of a modification like this. Thanks in advance jeff

Replies are listed 'Best First'.
Re: refs
by chromatic (Archbishop) on Mar 27, 2001 at 23:00 UTC
    It's hard. I've tried. The best option I've found that doesn't involve mucking about in perlguts, interpreting PP code, and trying to recreate stashes and the like, is to keep around the text of an eval()d sub, or make a string that contains code to recreate the reference.

    There are rumblings that The Damian is working on something to allow Data::Dumper to dump code references, and the same sort of technology will be much easier to attach to Storable. For now... good luck.

(tye)Re: refs
by tye (Sage) on Mar 27, 2001 at 22:57 UTC

    The only solution that will (nearly) always work is to create the code references such that the source for the code is cached (and that won't even work for many cases involving closures since it is hard to define how to preserve proper scope when the code reference is (re)constructred).

            - tye (but my friends call me "Tye")
Re: refs
by darobin (Monk) on Mar 28, 2001 at 00:22 UTC

    I've been thinking about this for a while... I think that it ought to be possible using B::Deparse.

    According to the doc:

    use B::Deparse; $deparse = B::Deparse->new("-p", "-sC"); $body = $deparse->coderef2text(\&func); eval "sub func $body"; # the inverse operation

    So it should be possible to store the coderef as text along with something to indicate that it's a coderef (and it's name, if it has one). On thaw it would simply eval it.

    Note that you can probably already do this without touching Storable. IIRC, before freeze()/thaw()ing Storable will try to call STORABLE_{freeze,thaw} in your namespace. You can use that as a filter mechanism.

    -- darobin

      Deparse isn't perfect (I recall examples of code that it doesn't deparse correctly) and there is still the issue of how to recreate a closure.

              - tye (but my friends call me "Tye")

        Yes I know, obvioulsy if the solution was perfect someone would have done it already :)

        However it can imho be a good place to look at given a certain level of simplicity, and may be a good place to watch for future updates on that front.

        -- darobin

Re: refs
by clintp (Curate) on Mar 28, 2001 at 03:53 UTC
    This has been tried (with B::Deparse and Data::Dumper) and the gory details are on p5p.

    It's not perfect, but a place to start maybe.