File Coverage

blib/lib/Data/MultiValued/UglySerializationHelperRole.pm
Criterion Covered Total %
statement 20 21 95.2
branch 3 6 50.0
condition n/a
subroutine 4 4 100.0
pod 2 2 100.0
total 29 33 87.8


line stmt bran cond sub pod time code
1             package Data::MultiValued::UglySerializationHelperRole;
2             {
3             $Data::MultiValued::UglySerializationHelperRole::VERSION = '0.0.1_4';
4             }
5             {
6             $Data::MultiValued::UglySerializationHelperRole::DIST = 'Data-MultiValued';
7             }
8 1     1   1250 use Moose::Role;
  1         2  
  1         13  
9 1     1   6968 use namespace::autoclean;
  1         3  
  1         12  
10              
11             # ABSTRACT: only use this if you know what you're doing
12              
13              
14             sub new_in_place {
15 1     1 1 13473 my ($class,$hash) = @_;
16              
17 1         5 my $self = bless $hash,$class;
18              
19 1         10 for my $attr ($class->meta->get_all_attributes) {
20 3 50       119 if ($attr->does('Data::MultiValued::AttributeTrait')) {
21 3         1952 $attr->_rebless_slot($self);
22             }
23             }
24 1         7 return $self;
25             }
26              
27              
28             sub as_hash {
29 1     1 1 207 my ($self) = @_;
30              
31 1         12 my %ret = %$self;
32 1         9 for my $attr ($self->meta->get_all_attributes) {
33 3 50       95 if ($attr->does('Data::MultiValued::AttributeTrait')) {
34 3         1846 my $st = $attr->_as_hash($self);
35 3 50       8 if ($st) {
36 3         137 $ret{$attr->full_storage_slot} = $st;
37             }
38             else {
39 0         0 delete $ret{$attr->full_storage_slot};
40             }
41             }
42             }
43 1         6 return \%ret;
44             }
45              
46              
47             1;
48              
49             __END__
50             =pod
51              
52             =encoding utf-8
53              
54             =head1 NAME
55              
56             Data::MultiValued::UglySerializationHelperRole - only use this if you know what you're doing
57              
58             =head1 VERSION
59              
60             version 0.0.1_4
61              
62             =head1 SYNOPSIS
63              
64             package My::Class;
65             use Moose;
66             use Data::MultiValued::AttributeTrait::Tags;
67              
68             with 'Data::MultiValued::UglySerializationHelperRole';
69              
70             has tt => (
71             is => 'rw',
72             isa => 'Int',
73             traits => ['MultiValued::Tags'],
74             default => 3,
75             predicate => 'has_tt',
76             clearer => 'clear_tt',
77             );
78              
79             Later:
80              
81             my $json = JSON::XS->new->utf8;
82             my $obj = My::Class->new(rr=>'foo');
83              
84             my $str = $json->encode($obj->as_hash);
85              
86             my $obj2 = My::Class->new_in_place($json->decode($str));
87              
88             # $obj and $obj2 have the same contents
89              
90             =head1 DESCRIPTION
91              
92             This is an ugly hack. It pokes inside the internals of your objects,
93             and will break if you're not careful. It assumes that your instances
94             are hashref-based. It mostly assumes that you're not storing blessed
95             refs inside the multi-value attributes. It goes to these lengths to
96             give a decent serialisation performance, without lots of unnecessary
97             copies. Oh, and on de-serialise it will skip all type constraint
98             checking and bypass the accessors, so it may well give you an unusable
99             object.
100              
101             =head1 METHODS
102              
103             =head2 C<new_in_place>
104              
105             my $obj = My::Class->new_in_place($hashref);
106              
107             Directly C<bless>es the hashref into the class, then calls
108             C<_rebless_slot> on any multi-value attribute.
109              
110             This is very dangerous, don't try this at home without the supervision
111             of an adult.
112              
113             =head2 C<as_hash>
114              
115             my $hashref = $obj->as_hash;
116              
117             Performs a shallow copy of the object's hash, then replaces the values
118             of all the multi-value slots with the results of calling C<_as_hash>
119             on the corresponding multi-value attribute.
120              
121             This is very dangerous, don't try this at home without the supervision
122             of an adult.
123              
124             =head1 FINAL WARNING
125              
126             my $obj_clone = My::Class->new_in_place($obj->as_hash);
127              
128             This will create a shallow clone. Most internals will be
129             shared. Things may break. Just don't do it, C<dclone> the hashref, or
130             do something equivalent (as in the synopsis), instead.
131              
132             =head1 AUTHOR
133              
134             Gianni Ceccarelli <dakkar@thenautilus.net>
135              
136             =head1 COPYRIGHT AND LICENSE
137              
138             This software is copyright (c) 2011 by Net-a-Porter.com.
139              
140             This is free software; you can redistribute it and/or modify it under
141             the same terms as the Perl 5 programming language system itself.
142              
143             =cut
144