File Coverage

blib/lib/Acme/MooseX/JSON.pm
Criterion Covered Total %
statement 66 90 73.3
branch n/a
condition n/a
subroutine 12 12 100.0
pod 1 1 100.0
total 79 103 76.7


line stmt bran cond sub pod time code
1             package Acme::MooseX::JSON;
2              
3 1     1   731536 use 5.008;
  1         4  
  1         41  
4 1     1   6 use strict;
  1         2  
  1         58  
5 1     1   6 use warnings;
  1         2  
  1         52  
6              
7             our $AUTHORITY = 'cpan:TOBYINK';
8             our $VERSION = '0.001';
9              
10 1     1   5 use Moose 2.00 ();
  1         16  
  1         24  
11 1     1   5 use Moose::Exporter;
  1         2  
  1         9  
12 1     1   51 use Moose::Util::MetaRole;
  1         2  
  1         21  
13 1     1   617 use Scalar::Accessors::LikeHash::JSON ();
  1         3  
  1         47  
14              
15             my $ACCESSORS = "Scalar::Accessors::LikeHash::JSON";
16              
17             BEGIN {
18             package Acme::MooseX::JSON::Trait::Class;
19 1     1   1454 use Moose::Role;
  1         5269  
  1         7  
20 1     1   6462 our $AUTHORITY = 'cpan:TOBYINK';
21 1         43 our $VERSION = '0.001';
22             };
23              
24             BEGIN {
25             package Acme::MooseX::JSON::Trait::Instance;
26 1     1   9 use Moose::Role;
  1         2  
  1         4  
27 1     1   6203 our $AUTHORITY = 'cpan:TOBYINK';
28 1         2 our $VERSION = '0.001';
29            
30             override create_instance => sub {
31 1         2415 my $meta = shift;
32 1         11 my $class = $meta->associated_metaclass;
33 1         4 my $str = "{}";
34 1         8 bless \$str, $class->name;
35 1         7 };
36            
37             override clone_instance => sub {
38 0         0 my ($meta, $instance) = @_;
39 0         0 my $class = $meta->associated_metaclass;
40 0         0 my $str = $$instance;
41 0         0 bless \$str, $class->name;
42 1         182 };
43            
44             override get_slot_value => sub {
45 0         0 my ($meta, $instance, $slot_name) = @_;
46 0         0 return $ACCESSORS->fetch($instance, $slot_name);
47 1         113 };
48            
49             override set_slot_value => sub {
50 1         348 my ($meta, $instance, $slot_name, $value) = @_;
51 1         12 return $ACCESSORS->store($instance, $slot_name, $value);
52 1         107 };
53            
54 1         105 override initialize_slot => sub { 1 };
  0         0  
55            
56             override deinitialize_slot => sub {
57 0         0 my ($meta, $instance, $slot_name) = @_;
58 0         0 return $ACCESSORS->delete($instance, $slot_name);
59 1         106 };
60            
61             override deinitialize_all_slots => sub {
62 0         0 my ($meta, $instance) = @_;
63 0         0 return $ACCESSORS->clear($instance);
64 1         104 };
65            
66             override is_slot_initialized => sub {
67 0         0 my ($meta, $instance, $slot_name) = @_;
68 0         0 return $ACCESSORS->exists($instance, $slot_name);
69 1         133 };
70            
71             override weaken_slot_value => sub {
72 0         0 my ($meta, $instance, $slot_name) = @_;
73 0         0 my $class = $meta->associated_metaclass;
74 0         0 confess "$class is implemented using Acme::MooseX::JSON, so cannot store weakened references.";
75 1         107 };
76            
77 1         106 override slot_value_is_weak => sub { 0 };
  0         0  
78            
79             override inline_create_instance => sub {
80 1         2041 my ($meta, $klass) = @_;
81 1         20 qq{ bless \\(my \$json = '{}'), $klass }
82 1         146 };
83            
84             override inline_slot_access => sub {
85 1         7 my ($meta, $instance, $slot_name) = @_;
86 1         7 qq{ '$ACCESSORS'->fetch($instance, '$slot_name') }
87 1         130 };
88            
89             override inline_get_slot_value => sub {
90 1         109 my ($meta, $instance, $slot_name) = @_;
91 1         4 $meta->inline_slot_access($instance, $slot_name);
92 1         106 };
93            
94             override inline_set_slot_value => sub {
95 2         4161 my ($meta, $instance, $slot_name, $value) = @_;
96 2         20 qq{ '$ACCESSORS'->store($instance, '$slot_name', $value) }
97 1         104 };
98            
99             override inline_deinitialize_slot => sub {
100 0         0 my ($meta, $instance, $slot_name) = @_;
101 0         0 qq{ '$ACCESSORS'->delete($instance, '$slot_name') }
102 1         105 };
103            
104             override inline_is_slot_initialized => sub {
105 0         0 my ($meta, $instance, $slot_name) = @_;
106 0         0 qq{ '$ACCESSORS'->exists($instance, '$slot_name') }
107 1         110 };
108            
109             override inline_weaken_slot_value => sub {
110 0         0 my ($meta, $instance, $slot_name) = @_;
111 0         0 my $class = $meta->associated_metaclass;
112 0         0 confess "$class is implemented using Acme::MooseX::JSON, so cannot store weakened references.";
113 1         106 };
114             };
115              
116             Moose::Exporter->setup_import_methods(
117             also => [qw( Moose )],
118             );
119            
120             sub init_meta
121             {
122 1     1 1 159 shift;
123 1         4 my %p = @_;
124 1         8 Moose->init_meta(%p);
125 1         5102 Moose::Util::MetaRole::apply_metaroles(
126             for => $p{for_class},
127             class_metaroles => {
128             instance => [qw( Acme::MooseX::JSON::Trait::Instance )],
129             class => [qw( Acme::MooseX::JSON::Trait::Class )],
130             },
131             );
132             }
133              
134             1;
135              
136             __END__
137              
138             =head1 NAME
139              
140             Acme::MooseX::JSON - Moose objects that are internally blessed scalar refs containing JSON
141              
142             =head1 SYNOPSIS
143              
144             {
145             package Local::Person;
146             use Acme::MooseX::JSON;
147             has name => (is => 'rw', isa => 'Str');
148             }
149            
150             my $object = Local::Person->new(name => "Bob");
151             print $$object; # JSON
152              
153             =head1 DESCRIPTION
154              
155             This L<Moose> extension is akin to L<MooseX::InsideOut>, L<MooseX::GlobRef>
156             and L<MooseX::ArrayRef> in that it allows you to create Moose classes where
157             the instances aren't blessed hashes.
158              
159             However, unlike those fine modules, Acme::MooseX::JSON chooses just about
160             the most insane way of implementing an instance's internals possible: they're
161             serialized as a JSON string, which is then used as a blessed scalar reference.
162              
163             The use of JSON to serialize the object's internals places fairly strong
164             restrictions on what kind of data can be held in the object's attributes.
165             Strings, numbers and undef are all OK; arrayrefs and hashrefs are OK
166             provided you don't create cyclical data structures, and provided they
167             don't contain any non-OK data as values.
168              
169             This module requires L<JSON> 2.00+ and L<Moose> 2.00+ to be installed.
170              
171             =begin private
172              
173             =item init_meta
174              
175             =end private
176              
177             =head1 BUGS
178              
179             Please report any bugs to
180             L<http://rt.cpan.org/Dist/Display.html?Queue=Scalar-Accessors-LikeHash>.
181              
182             =head1 SEE ALSO
183              
184             L<Scalar::Accessors::LikeHash>, L<JSON>, L<Moose>.
185              
186             L<MooseX::InsideOut>, L<MooseX::GlobRef>, L<MooseX::ArrayRef>.
187              
188             =head1 AUTHOR
189              
190             Toby Inkster E<lt>tobyink@cpan.orgE<gt>.
191              
192             =head1 COPYRIGHT AND LICENCE
193              
194             This software is copyright (c) 2013 by Toby Inkster.
195              
196             This is free software; you can redistribute it and/or modify it under
197             the same terms as the Perl 5 programming language system itself.
198              
199             =head1 DISCLAIMER OF WARRANTIES
200              
201             THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
202             WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
203             MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
204