From: Stevan Little Date: Thu, 10 Jan 2008 01:13:19 +0000 (+0000) Subject: adding support for Deferred X-Git-Tag: 0.14~14 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=1f3074ea2b80c4c8dfc081414f87285bc7892c82;p=gitmo%2FMooseX-Storage.git adding support for Deferred --- diff --git a/Changes b/Changes index dee5c67..3d68ede 100644 --- a/Changes +++ b/Changes @@ -1,5 +1,14 @@ Revision history for MooseX-Storage +0.10 + ~~ updated copyright information ~~ + + * MooseX::Storage::Deferred + - added this role, which allows you to wait until + you actually call a method to determine what + formatter and/or IO engine you want to use + - added tests for this + 0.09 Tue. Oct. 23, 2007 * MooseX::Storage::Util - added support to deal with utf8 strings correctly diff --git a/README b/README index 9cc256f..8710fec 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -MooseX-Storage version 0.09 +MooseX-Storage version 0.10 INSTALLATION @@ -34,7 +34,7 @@ OPTIONAL DEPENDENCIES COPYRIGHT AND LICENCE -Copyright (C) 2007, Infinity Interactive +Copyright (C) 2007-2008 Infinity Interactive This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/lib/MooseX/Storage.pm b/lib/MooseX/Storage.pm index 2146601..f64ac68 100644 --- a/lib/MooseX/Storage.pm +++ b/lib/MooseX/Storage.pm @@ -4,7 +4,7 @@ use Moose qw(confess); use MooseX::Storage::Meta::Attribute::DoNotSerialize; -our $VERSION = '0.09'; +our $VERSION = '0.10'; our $AUTHORITY = 'cpan:STEVAN'; sub import { @@ -261,7 +261,7 @@ Yuval Kogman Eyuval.kogman@iinteractive.comE =head1 COPYRIGHT AND LICENSE -Copyright 2007 by Infinity Interactive, Inc. +Copyright 2007-2008 by Infinity Interactive, Inc. L diff --git a/lib/MooseX/Storage/Base/WithChecksum.pm b/lib/MooseX/Storage/Base/WithChecksum.pm index 0f1292d..207f388 100644 --- a/lib/MooseX/Storage/Base/WithChecksum.pm +++ b/lib/MooseX/Storage/Base/WithChecksum.pm @@ -143,7 +143,7 @@ Yuval Kogman =head1 COPYRIGHT AND LICENSE -Copyright 2007 by Infinity Interactive, Inc. +Copyright 2007-2008 by Infinity Interactive, Inc. L diff --git a/lib/MooseX/Storage/Basic.pm b/lib/MooseX/Storage/Basic.pm index a572668..d43d26a 100644 --- a/lib/MooseX/Storage/Basic.pm +++ b/lib/MooseX/Storage/Basic.pm @@ -92,7 +92,7 @@ Stevan Little Estevan.little@iinteractive.comE =head1 COPYRIGHT AND LICENSE -Copyright 2007 by Infinity Interactive, Inc. +Copyright 2007-2008 by Infinity Interactive, Inc. L diff --git a/lib/MooseX/Storage/Deferred.pm b/lib/MooseX/Storage/Deferred.pm new file mode 100644 index 0000000..586aef7 --- /dev/null +++ b/lib/MooseX/Storage/Deferred.pm @@ -0,0 +1,122 @@ +package MooseX::Storage::Deferred; +use Moose::Role; + +our $VERSION = '0.03'; +our $AUTHORITY = 'cpan:STEVAN'; + +with 'MooseX::Storage::Basic'; + +sub thaw { + my ( $class, $packed, $type, @args ) = @_; + + (exists $type->{format}) + || confess "You must specify a format type to thaw from"; + + my $class_to_load = 'MooseX::Storage::Format::' . $type->{format}; + Class::MOP::load_class($class_to_load); + + my $method_to_call = $class_to_load . '::thaw'; + + $class->$method_to_call($packed, @args); +} + +sub freeze { + my ( $self, $type, @args ) = @_; + + (exists $type->{format}) + || confess "You must specify a format type to freeze into"; + + my $class_to_load = 'MooseX::Storage::Format::' . $type->{format}; + Class::MOP::load_class($class_to_load); + + my $method_to_call = $class_to_load . '::freeze'; + + $self->$method_to_call(@args); +} + +1; + +__END__ + +=pod + +=head1 NAME + +MooseX::Storage::Deferred - A role for undecisive programmers + +=head1 SYNOPSIS + + package Point; + use Moose; + use MooseX::Storage; + + our $VERSION = '0.01'; + + with 'MooseX::Storage::Deferred'; + + has 'x' => (is => 'rw', isa => 'Int'); + has 'y' => (is => 'rw', isa => 'Int'); + + 1; + + my $p = Point->new(x => 10, y => 10); + + ## methods to freeze/thaw into + ## a specified serialization format + ## (in this case JSON) + + # pack the class into a JSON string + $p->freeze({ format => 'JSON' }); # { "__CLASS__" : "Point", "x" : 10, "y" : 10 } + + # unpack the JSON string into a class + my $p2 = Point->thaw( + '{ "__CLASS__" : "Point", "x" : 10, "y" : 10 }', + { format => 'JSON' } + ); + +=head1 DESCRIPTION + +This role is designed for those times when you need to +serialize into many different formats or I/O options. +It basically allows you to choose the format and IO +options only when you actually use them (see the +SYNOPSIS for more info) + +=head1 METHODS + +=over 4 + +=item B + +=item B + +=back + +=head2 Introspection + +=over 4 + +=item B + +=back + +=head1 BUGS + +All complex software has bugs lurking in it, and this module is no +exception. If you find a bug please either email me, or add the bug +to cpan-RT. + +=head1 AUTHOR + +Stevan Little Estevan.little@iinteractive.comE + +=head1 COPYRIGHT AND LICENSE + +Copyright 2007-2008 by Infinity Interactive, Inc. + +L + +This library is free software; you can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut diff --git a/lib/MooseX/Storage/Engine.pm b/lib/MooseX/Storage/Engine.pm index 081f5ed..a49cd07 100644 --- a/lib/MooseX/Storage/Engine.pm +++ b/lib/MooseX/Storage/Engine.pm @@ -422,7 +422,7 @@ Stevan Little Estevan.little@iinteractive.comE =head1 COPYRIGHT AND LICENSE -Copyright 2007 by Infinity Interactive, Inc. +Copyright 2007-2008 by Infinity Interactive, Inc. L diff --git a/lib/MooseX/Storage/Engine/IO/AtomicFile.pm b/lib/MooseX/Storage/Engine/IO/AtomicFile.pm index fc081df..ad453c4 100644 --- a/lib/MooseX/Storage/Engine/IO/AtomicFile.pm +++ b/lib/MooseX/Storage/Engine/IO/AtomicFile.pm @@ -68,7 +68,7 @@ Stevan Little Estevan.little@iinteractive.comE =head1 COPYRIGHT AND LICENSE -Copyright 2007 by Infinity Interactive, Inc. +Copyright 2007-2008 by Infinity Interactive, Inc. L diff --git a/lib/MooseX/Storage/Engine/IO/File.pm b/lib/MooseX/Storage/Engine/IO/File.pm index 02d1bcd..f8b63f1 100644 --- a/lib/MooseX/Storage/Engine/IO/File.pm +++ b/lib/MooseX/Storage/Engine/IO/File.pm @@ -77,7 +77,7 @@ Stevan Little Estevan.little@iinteractive.comE =head1 COPYRIGHT AND LICENSE -Copyright 2007 by Infinity Interactive, Inc. +Copyright 2007-2008 by Infinity Interactive, Inc. L diff --git a/lib/MooseX/Storage/Format/JSON.pm b/lib/MooseX/Storage/Format/JSON.pm index 27dfa48..654cb3b 100644 --- a/lib/MooseX/Storage/Format/JSON.pm +++ b/lib/MooseX/Storage/Format/JSON.pm @@ -97,7 +97,7 @@ Yuval Kogman Eyuval.kogman@iinteractive.comE =head1 COPYRIGHT AND LICENSE -Copyright 2007 by Infinity Interactive, Inc. +Copyright 2007-2008 by Infinity Interactive, Inc. L diff --git a/lib/MooseX/Storage/Format/Storable.pm b/lib/MooseX/Storage/Format/Storable.pm index 760d74e..5289407 100644 --- a/lib/MooseX/Storage/Format/Storable.pm +++ b/lib/MooseX/Storage/Format/Storable.pm @@ -97,7 +97,7 @@ Stevan Little Estevan.little@iinteractive.comE =head1 COPYRIGHT AND LICENSE -Copyright 2007 by Infinity Interactive, Inc. +Copyright 2007-2008 by Infinity Interactive, Inc. L diff --git a/lib/MooseX/Storage/Format/YAML.pm b/lib/MooseX/Storage/Format/YAML.pm index 8f38803..3cccc52 100644 --- a/lib/MooseX/Storage/Format/YAML.pm +++ b/lib/MooseX/Storage/Format/YAML.pm @@ -104,7 +104,7 @@ Stevan Little Estevan.little@iinteractive.comE =head1 COPYRIGHT AND LICENSE -Copyright 2007 by Infinity Interactive, Inc. +Copyright 2007-2008 by Infinity Interactive, Inc. L diff --git a/lib/MooseX/Storage/IO/AtomicFile.pm b/lib/MooseX/Storage/IO/AtomicFile.pm index a32638b..d0da088 100644 --- a/lib/MooseX/Storage/IO/AtomicFile.pm +++ b/lib/MooseX/Storage/IO/AtomicFile.pm @@ -78,7 +78,7 @@ Stevan Little Estevan.little@iinteractive.comE =head1 COPYRIGHT AND LICENSE -Copyright 2007 by Infinity Interactive, Inc. +Copyright 2007-2008 by Infinity Interactive, Inc. L diff --git a/lib/MooseX/Storage/IO/File.pm b/lib/MooseX/Storage/IO/File.pm index a276812..b8c646d 100644 --- a/lib/MooseX/Storage/IO/File.pm +++ b/lib/MooseX/Storage/IO/File.pm @@ -84,7 +84,7 @@ Stevan Little Estevan.little@iinteractive.comE =head1 COPYRIGHT AND LICENSE -Copyright 2007 by Infinity Interactive, Inc. +Copyright 2007-2008 by Infinity Interactive, Inc. L diff --git a/lib/MooseX/Storage/IO/StorableFile.pm b/lib/MooseX/Storage/IO/StorableFile.pm index eb5d5af..d261fcd 100644 --- a/lib/MooseX/Storage/IO/StorableFile.pm +++ b/lib/MooseX/Storage/IO/StorableFile.pm @@ -106,7 +106,7 @@ Stevan Little Estevan.little@iinteractive.comE =head1 COPYRIGHT AND LICENSE -Copyright 2007 by Infinity Interactive, Inc. +Copyright 2007-2008 by Infinity Interactive, Inc. L diff --git a/lib/MooseX/Storage/Meta/Attribute/DoNotSerialize.pm b/lib/MooseX/Storage/Meta/Attribute/DoNotSerialize.pm index 2ffd1da..298935c 100644 --- a/lib/MooseX/Storage/Meta/Attribute/DoNotSerialize.pm +++ b/lib/MooseX/Storage/Meta/Attribute/DoNotSerialize.pm @@ -75,7 +75,7 @@ Stevan Little Estevan.little@iinteractive.comE =head1 COPYRIGHT AND LICENSE -Copyright 2007 by Infinity Interactive, Inc. +Copyright 2007-2008 by Infinity Interactive, Inc. L diff --git a/lib/MooseX/Storage/Util.pm b/lib/MooseX/Storage/Util.pm index 761557b..0096b0b 100644 --- a/lib/MooseX/Storage/Util.pm +++ b/lib/MooseX/Storage/Util.pm @@ -142,7 +142,7 @@ Stevan Little Estevan.little@iinteractive.comE =head1 COPYRIGHT AND LICENSE -Copyright 2007 by Infinity Interactive, Inc. +Copyright 2007-2008 by Infinity Interactive, Inc. L diff --git a/t/060_basic_deferred.t b/t/060_basic_deferred.t new file mode 100644 index 0000000..75c36a9 --- /dev/null +++ b/t/060_basic_deferred.t @@ -0,0 +1,243 @@ +#!/usr/bin/perl +$|++; +use strict; +use warnings; + +use Test::More tests => 33; +use Storable; +use Test::JSON; +use Test::YAML::Valid; + +BEGIN { + $ENV{JSON_ANY_ORDER} = qw(JSON); + use_ok('MooseX::Storage'); +} + +{ + + package Foo; + use Moose; + use MooseX::Storage; + + with 'MooseX::Storage::Deferred'; + + has 'number' => ( is => 'ro', isa => 'Int' ); + has 'string' => ( is => 'ro', isa => 'Str' ); + has 'float' => ( is => 'ro', isa => 'Num' ); + has 'array' => ( is => 'ro', isa => 'ArrayRef' ); + has 'hash' => ( is => 'ro', isa => 'HashRef' ); + has 'object' => ( is => 'ro', isa => 'Object' ); +} + +{ + my $foo = Foo->new( + number => 10, + string => 'foo', + float => 10.5, + array => [ 1 .. 10 ], + hash => { map { $_ => undef } ( 1 .. 10 ) }, + object => Foo->new( number => 2 ), + ); + isa_ok( $foo, 'Foo' ); + + my $json = $foo->freeze({ 'format' => 'JSON' }); + + is_valid_json($json, '.. this is valid JSON'); + + is_json( + $json, +'{"array":[1,2,3,4,5,6,7,8,9,10],"hash":{"6":null,"3":null,"7":null,"9":null,"2":null,"8":null,"1":null,"4":null,"10":null,"5":null},"float":10.5,"object":{"number":2,"__CLASS__":"Foo"},"number":10,"__CLASS__":"Foo","string":"foo"}', + '... got the right JSON' + ); +} + +{ + my $foo = Foo->thaw( + '{"array":[1,2,3,4,5,6,7,8,9,10],"hash":{"6":null,"3":null,"7":null,"9":null,"2":null,"8":null,"1":null,"4":null,"10":null,"5":null},"float":10.5,"object":{"number":2,"__CLASS__":"Foo"},"number":10,"__CLASS__":"Foo","string":"foo"}', + { 'format' => 'JSON' } + ); + isa_ok( $foo, 'Foo' ); + + is( $foo->number, 10, '... got the right number' ); + is( $foo->string, 'foo', '... got the right string' ); + is( $foo->float, 10.5, '... got the right float' ); + is_deeply( $foo->array, [ 1 .. 10 ], '... got the right array' ); + is_deeply( + $foo->hash, + { map { $_ => undef } ( 1 .. 10 ) }, + '... got the right hash' + ); + + isa_ok( $foo->object, 'Foo' ); + is( $foo->object->number, 2, + '... got the right number (in the embedded object)' ); +} + +{ + my $foo = Foo->new( + number => 10, + string => 'foo', + float => 10.5, + array => [ 1 .. 10 ], + hash => { map { $_ => undef } ( 1 .. 10 ) }, + object => Foo->new( number => 2 ), + ); + isa_ok( $foo, 'Foo' ); + + my $stored = $foo->freeze({ 'format' => 'Storable' }); + + my $struct = Storable::thaw($stored); + is_deeply( + $struct, + { + '__CLASS__' => 'Foo', + 'float' => 10.5, + 'number' => 10, + 'string' => 'foo', + 'array' => [ 1 .. 10], + 'hash' => { map { $_ => undef } 1 .. 10 }, + 'object' => { + '__CLASS__' => 'Foo', + 'number' => 2 + }, + }, + '... got the data struct we expected' + ); +} + +{ + my $stored = Storable::nfreeze({ + '__CLASS__' => 'Foo', + 'float' => 10.5, + 'number' => 10, + 'string' => 'foo', + 'array' => [ 1 .. 10], + 'hash' => { map { $_ => undef } 1 .. 10 }, + 'object' => { + '__CLASS__' => 'Foo', + 'number' => 2 + }, + }); + + my $foo = Foo->thaw($stored, { 'format' => 'Storable' }); + isa_ok( $foo, 'Foo' ); + + is( $foo->number, 10, '... got the right number' ); + is( $foo->string, 'foo', '... got the right string' ); + is( $foo->float, 10.5, '... got the right float' ); + is_deeply( $foo->array, [ 1 .. 10 ], '... got the right array' ); + is_deeply( + $foo->hash, + { map { $_ => undef } ( 1 .. 10 ) }, + '... got the right hash' + ); + + isa_ok( $foo->object, 'Foo' ); + is( $foo->object->number, 2, + '... got the right number (in the embedded object)' ); +} + +{ + my $foo = Foo->new( + number => 10, + string => 'foo', + float => 10.5, + array => [ 1 .. 10 ], + hash => { map { $_ => undef } ( 1 .. 10 ) }, + object => Foo->new( number => 2 ), + ); + isa_ok( $foo, 'Foo' ); + + my $yaml = $foo->freeze({ 'format' => 'YAML' }); + + yaml_string_ok( $yaml, '... we got valid YAML out of it' ); + + is( + $yaml, + q{--- +__CLASS__: Foo +array: + - 1 + - 2 + - 3 + - 4 + - 5 + - 6 + - 7 + - 8 + - 9 + - 10 +float: 10.5 +hash: + 1: ~ + 10: ~ + 2: ~ + 3: ~ + 4: ~ + 5: ~ + 6: ~ + 7: ~ + 8: ~ + 9: ~ +number: 10 +object: + __CLASS__: Foo + number: 2 +string: foo +}, + '... got the same YAML' + ); + +} + +{ + my $foo = Foo->thaw( + q{--- +__CLASS__: Foo +array: + - 1 + - 2 + - 3 + - 4 + - 5 + - 6 + - 7 + - 8 + - 9 + - 10 +float: 10.5 +hash: + 1: ~ + 10: ~ + 2: ~ + 3: ~ + 4: ~ + 5: ~ + 6: ~ + 7: ~ + 8: ~ + 9: ~ +number: 10 +object: + __CLASS__: Foo + number: 2 +string: foo +}, { 'format' => 'YAML' } + ); + isa_ok( $foo, 'Foo' ); + + is( $foo->number, 10, '... got the right number' ); + is( $foo->string, 'foo', '... got the right string' ); + is( $foo->float, 10.5, '... got the right float' ); + is_deeply( $foo->array, [ 1 .. 10 ], '... got the right array' ); + is_deeply( + $foo->hash, + { map { $_ => undef } ( 1 .. 10 ) }, + '... got the right hash' + ); + + isa_ok( $foo->object, 'Foo' ); + is( $foo->object->number, 2, + '... got the right number (in the embedded object)' ); +} +