views:

79

answers:

3

I was usually using Storable with nstore, but now I have a module that has CODE and apparently Storable doesn't like that.

I found YAML (and YAML::XS which I can't really get to work). I also experimented a bit with MooseX::Storage without much success.

Are there other alternatives? What would you recommend?

+1  A: 

I believe Data::Dump::Streamer can serialize coderefs. Haven't used it myself though.

Eric Strom
It can, and works okay as long as you understand its documented caveats. I'd avoid dumping coderefs if possible though.
brian d foy
+2  A: 

Have a look at KiokuDB, its designed with and for Moose so it should really cover all the corners (NB. I haven't tried it myself but I keep meaning to!)

/I3az/

draegtun
I'm currently giving a look at `KiokuDB`. It seems interesting, but I actually need to serialize a single object or only a couple of objects at time. I do not need smart searching etc. Using DB backends etc. seems like an overkill for my case.
David B
A: 

You can dump a coderef with Data::Dumper after setting $Data::Dumper::Deparse to a true value, but this is only intended for debugging purposes, not for serialization.

I would suggest you go back to looking at why MooseX::Storage isn't working out for you, as the authors tried really hard to present a well-abstracted and robust solution for Moose object serialization.


Update: it looks like you are running into issues serializing the _offset_sub attribute, as described in this question. Since that attribute has a builder, and its construction is fairly trivial (it just looks at the current value of another attribute), you shouldn't need to serialize it at all -- when you deserialize your object and want to use it again, the builder will be invoked the first time you call $this->offset. Consequently, you should just be able to mark it as "do not serialize":

use MooseX::Storage;

has '_offset_sub' => (
    is       => 'ro',
    isa      => 'CodeRef',
    traits   => [ 'DoNotSerialize' ],
    lazy     => 1,
    builder  => '_build_offset_sub',
    init_arg => undef,
);

Lastly, this is somewhat orthogonal, but you can fold the offset and _offset_sub attributes together by using the native attribute 'Code' trait:

has offset => (
    is          => 'bare',
    isa         => 'CodeRef',
    traits      => [ qw(Code DoNotSerialize) ],
    lazy        => 1,
    builder     => '_build_offset',
    init_arg    => undef,
    handles     => {
        offset  => 'execute_method',
    },
);

sub _build_offset {
    my ($self) = @_;

    # same as previous _build_offset_sub...
}
Ether
Well done! I've migrated to `MooseX::Storage`.
David B