File Coverage

blib/lib/MooseX/Blessed/Reconstruct.pm
Criterion Covered Total %
statement 2 4 50.0
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 4 6 66.6


line stmt bran cond sub pod time code
1             package MooseX::Blessed::Reconstruct;
2             BEGIN {
3 1     1   17924 $MooseX::Blessed::Reconstruct::AUTHORITY = 'cpan:YANICK';
4             }
5             # ABSTRACT: A L<Data::Visitor> for creating Moose objects from blessed placeholders
6             $MooseX::Blessed::Reconstruct::VERSION = '1.00';
7              
8 1     1   187 use Moose;
  0            
  0            
9              
10             use Carp qw(croak);
11              
12             use Class::MOP;
13             use Class::Load;
14             use Data::Visitor 0.21; # n-arity visit
15              
16             use Scalar::Util qw(reftype);
17              
18             use namespace::clean -except => 'meta';
19              
20             extends qw(Data::Visitor);
21              
22             has load_classes => (
23             isa => "Bool",
24             is => "rw",
25             default => 1,
26             );
27              
28             sub visit_object {
29             my ( $v, $obj ) = @_;
30              
31             my $class = ref $obj;
32              
33             Class::Load::load_class($class) if $v->load_classes;
34              
35             my $meta = Class::MOP::get_metaclass_by_name($class);
36              
37             if ( ref $meta ) {
38             return $v->visit_object_with_meta($obj, $meta);
39             } else {
40             return $v->visit_ref($obj);
41             }
42             }
43              
44             sub visit_object_with_meta {
45             my ( $v, $obj, $meta ) = @_;
46              
47             my $instance = $meta->get_meta_instance->create_instance;
48              
49             $v->_register_mapping( $obj => $instance );
50              
51             my $args = $v->prepare_args( $meta, $obj );
52              
53             $meta->new_object( %$args, __INSTANCE__ => $instance );
54              
55             return $instance;
56             }
57              
58             sub prepare_args {
59             my ( $v, $meta, $obj ) = @_;
60              
61             my @args;
62              
63             if ( reftype $obj eq 'HASH' ) {
64             @args = %$obj;
65             } elsif ( reftype $obj eq 'ARRAY' ) {
66             @args = @$obj;
67             } elsif ( reftype $obj eq 'SCALAR' ) {
68             @args = $$obj;
69             } else {
70             croak "unknown ref type $obj";
71             }
72              
73             my @processed = $v->visit(@args);
74              
75             return $meta->name->BUILDARGS(@processed);
76             }
77              
78             __PACKAGE__->meta->make_immutable;
79              
80             __PACKAGE__
81              
82             __END__
83              
84             =pod
85              
86             =encoding UTF-8
87              
88             =head1 NAME
89              
90             MooseX::Blessed::Reconstruct - A L<Data::Visitor> for creating Moose objects from blessed placeholders
91              
92             =head1 VERSION
93              
94             version 1.00
95              
96             =head1 SYNOPSIS
97              
98             use MooseX::Blessed::Reconstruct;
99              
100              
101             my $obj = bless( {
102             init_arg_foo => "Blah",
103             arf => "yay",
104             }, "Foo" );
105              
106             my $proper = MooseX::Blessed::Reconstruct->new->visit($obj);
107              
108              
109              
110             # equivalent to:
111              
112             my $proper = Foo->meta->new_object(%$obj);
113              
114             # but recursive (and works with shared references)
115              
116             =head1 DESCRIPTION
117              
118             The purpose of this module is to "fix up" blessed data into a real Moose
119             object.
120              
121             This is used internally by L<MooseX::YAML> but has no implementation details
122             having to do with L<YAML> itself.
123              
124             =head1 METHODS
125              
126             See L<Data::Visitor>
127              
128             =over 4
129              
130             =item visit_object $object
131              
132             Calls L<Class::MOP/load_class> on the C<ref> of $object.
133              
134             If there's a metaclass, calls C<visit_object_with_meta>, otherwise C<visit_ref>
135             is used to walk the object brutishly.
136              
137             Returns a deep clone of the input structure with all the L<Moose> objects
138             reconstructed "properly".
139              
140             =item visit_object_with_meta $obj, $meta
141              
142             Uses the metaclass C<$meta> to create a new instance, registers the instance
143             with L<Data::Visitor>'s cycle tracking, and then inflates it using
144             L<Moose::Meta::Class/new_object>.
145              
146             =item prepare_args $obj
147              
148             Collapses $obj into key value pairs to be used as init args to
149             L<Moose::Meta::Class/new_object>.
150              
151             =back
152              
153             =head1 AUTHORS
154              
155             =over 4
156              
157             =item *
158              
159             Yuval Kogman <nothingmuch@woobling.org>
160              
161             =item *
162              
163             Jonathan Rockway <jrockway@cpan.org>
164              
165             =back
166              
167             =head1 COPYRIGHT AND LICENSE
168              
169             This software is copyright (c) 2008 by Infinity Interactive, Yuval Kogman.
170              
171             This is free software; you can redistribute it and/or modify it under
172             the same terms as the Perl 5 programming language system itself.
173              
174             =cut