File Coverage

blib/lib/MooseX/SlurpyConstructor/Trait/Class.pm
Criterion Covered Total %
statement 9 9 100.0
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 12 12 100.0


line stmt bran cond sub pod time code
1             package MooseX::SlurpyConstructor::Trait::Class;
2              
3             our $VERSION = '1.30';
4              
5             # applied as class_metaroles => { class => [ __PACKAGE__ ] }.
6              
7 8     8   42 use Moose::Role;
  8         13  
  8         48  
8              
9 8     8   28008 use namespace::autoclean;
  8         12  
  8         45  
10              
11 8     8   364 use B ();
  8         10  
  8         3288  
12              
13             around '_inline_BUILDALL' => sub {
14             my $orig = shift;
15             my $self = shift;
16              
17             my @source = $self->$orig();
18              
19             my @attrs = (
20             '__INSTANCE__ => 1,',
21             map { B::perlstring($_) . ' => 1,' }
22             grep { defined }
23             map { $_->init_arg } $self->get_all_attributes
24             );
25              
26             my $slurpy_attr = $self->slurpy_attr;
27              
28             return (
29             @source,
30             'my %attrs = (' . ( join ' ', @attrs ) . ');',
31             'my @extra = sort grep { !$attrs{$_} } keys %{ $params };',
32             'if (@extra){',
33              
34             !$slurpy_attr
35             ? 'Moose->throw_error("Found extra construction arguments, but there is no \'slurpy\' attribute present!");'
36             : (
37             'my %slurpy_values;',
38             '@slurpy_values{@extra} = @{$params}{@extra};',
39              
40             '$instance->meta->slurpy_attr->set_value( $instance, \%slurpy_values );',
41             ),
42             '}',
43             );
44             }
45             if Moose->VERSION >= 1.9900;
46              
47             # quick access to the slurpy attribute
48             # (which holds the extra constructor arguments)
49             has slurpy_attr => (
50             is => 'rw',
51             isa => 'Maybe[Moose::Meta::Attribute]',
52             weak_ref => 1,
53             );
54              
55             # stores the location of the slurpy attribute; reader also looks up the class
56             # heirarchy
57             around slurpy_attr => sub {
58             my $orig = shift;
59             my $self = shift;
60              
61             # writer
62             return $self->$orig(@_) if @_;
63              
64             # reader
65              
66             my $result = $self->$orig;
67             return $result if $result;
68              
69             # we need to walk the inheritance tree, checking all metaclasses for
70             # the one that holds a slurpy_attr with a defined value.
71             my @slurpy_attr_values = map {
72             my $attr = $_->meta->meta->get_attribute('slurpy_attr');
73             !$attr
74             ? ()
75             : $attr->get_value($_->meta) || ();
76             }
77             $self->linearized_isa;
78              
79             foreach my $ancestor ($self->linearized_isa)
80             {
81             my $attr = $ancestor->meta->meta->find_attribute_by_name('slurpy_attr');
82             next if not $attr;
83             my $attr_value = $attr->get_value($ancestor->meta);
84             return $attr_value if $attr_value;
85             }
86              
87             # no slurpy_attrs found
88             return;
89             };
90              
91             # if the Object role is applied first, and then a superclass added, we just
92             # lost our BUILDALL modification.
93             after superclasses => sub
94             {
95             my $self = shift;
96             return if not @_;
97             Moose::Util::MetaRole::apply_base_class_roles(
98             for => $self->name,
99             roles => ['MooseX::SlurpyConstructor::Role::Object'],
100             )
101             };
102              
103             1;
104              
105             # ABSTRACT: A role to make immutable constructors slurpy, and add meta-information used to find slurpy attributes
106              
107             __END__
108              
109             =pod
110              
111             =encoding UTF-8
112              
113             =head1 NAME
114              
115             MooseX::SlurpyConstructor::Trait::Class - A role to make immutable constructors slurpy, and add meta-information used to find slurpy attributes
116              
117             =head1 VERSION
118              
119             version 1.30
120              
121             =head1 DESCRIPTION
122              
123             This role simply wraps C<_inline_BUILDALL()> (from
124             L<Moose::Meta::Class>) so that immutable classes have a
125             slurpy constructor.
126              
127             =head1 SUPPORT
128              
129             Bugs may be submitted through L<the RT bug tracker|https://rt.cpan.org/Public/Dist/Display.html?Name=MooseX-SlurpyConstructor>
130             (or L<bug-MooseX-SlurpyConstructor@rt.cpan.org|mailto:bug-MooseX-SlurpyConstructor@rt.cpan.org>).
131              
132             There is also a mailing list available for users of this distribution, at
133             L<http://lists.perl.org/list/moose.html>.
134              
135             There is also an irc channel available for users of this distribution, at
136             L<C<#moose> on C<irc.perl.org>|irc://irc.perl.org/#moose>.
137              
138             =head1 AUTHORS
139              
140             =over 4
141              
142             =item *
143              
144             Mark Morgan <makk384@gmail.com>
145              
146             =item *
147              
148             Karen Etheridge <ether@cpan.org>
149              
150             =back
151              
152             =head1 COPYRIGHT AND LICENSE
153              
154             This software is copyright (c) 2009 by Karen Etheridge.
155              
156             This is free software; you can redistribute it and/or modify it under
157             the same terms as the Perl 5 programming language system itself.
158              
159             =cut