File Coverage

blib/lib/MooseX/Traits.pm
Criterion Covered Total %
statement 41 41 100.0
branch 10 12 83.3
condition 3 4 75.0
subroutine 9 9 100.0
pod 2 3 66.6
total 65 69 94.2


line stmt bran cond sub pod time code
1             package MooseX::Traits; # git description: v0.12-22-g1b6e7ce
2             # ABSTRACT: Automatically apply roles at object creation time
3              
4             our $VERSION = '0.13';
5              
6 7     7   795200 use Moose::Role;
  7         1342489  
  7         56  
7              
8 7     7   41852 use MooseX::Traits::Util qw(new_class_with_traits);
  7         19  
  7         44  
9              
10 7     7   1306 use warnings;
  7         14  
  7         185  
11 7     7   49 use warnings::register;
  7         13  
  7         1112  
12              
13 7     7   3691 use namespace::autoclean;
  7         38865  
  7         77  
14              
15             has '_trait_namespace' => (
16             # no accessors or init_arg
17             init_arg => undef,
18             isa => 'Str',
19             is => 'bare',
20             );
21              
22             sub with_traits {
23 22     22 1 59659 my ($class, @traits) = @_;
24              
25 22         94 my $new_class = new_class_with_traits(
26             $class,
27             @traits,
28             );
29              
30 22         196 return $new_class->name;
31             }
32              
33             # somewhat deprecated, but use if you want to
34             sub new_with_traits {
35 16     16 1 109149 my $class = shift;
36              
37 16         38 my ($hashref, %args) = 0;
38 16 100       58 if (ref($_[0]) eq 'HASH') {
39 1         2 %args = %{ +shift };
  1         5  
40 1         2 $hashref = 1;
41             } else {
42 15         53 %args = @_;
43             }
44              
45 16   100     74 my $traits = delete $args{traits} || [];
46              
47 16 100       76 my $new_class = $class->with_traits(ref $traits ? @$traits : $traits );
48              
49 16         82 my $constructor = $new_class->meta->constructor_name;
50 16 50       306 confess "$class ($new_class) does not have a constructor defined via the MOP?"
51             if !$constructor;
52              
53 16 100       149 return $new_class->$constructor($hashref ? \%args : %args);
54              
55             }
56              
57             # this code is broken and should never have been added. i probably
58             # won't delete it, but it is definitely not up-to-date with respect to
59             # other features, and never will be.
60             #
61             # runtime role application is fundamentally broken. if you really
62             # need it, write it yourself, but consider applying the roles before
63             # you create an instance.
64              
65             #pod =for Pod::Coverage apply_traits
66             #pod
67             #pod =cut
68              
69             sub apply_traits {
70 2     2 0 16714 my ($self, $traits, $rebless_params) = @_;
71              
72             # disable this warning with "use MooseX::Traits; no warnings 'MooseX::Traits'"
73 2         203 warnings::warnif('apply_traits is deprecated due to being fundamentally broken. '.
74             q{disable this warning with "no warnings 'MooseX::Traits'"});
75              
76             # arrayify
77 2         6 my @traits = $traits;
78 2 100       10 @traits = @$traits if ref $traits;
79              
80 2 50       7 if (@traits) {
81 2         12 @traits = MooseX::Traits::Util::resolve_traits(
82             $self, @traits,
83             );
84              
85 2         8 for my $trait (@traits){
86 3   50     7318 $trait->meta->apply($self, rebless_params => $rebless_params || {});
87             }
88             }
89             }
90              
91 7     7   2891 no Moose::Role;
  7         21  
  7         67  
92              
93             1;
94              
95             __END__
96              
97             =pod
98              
99             =encoding UTF-8
100              
101             =head1 NAME
102              
103             MooseX::Traits - Automatically apply roles at object creation time
104              
105             =head1 VERSION
106              
107             version 0.13
108              
109             =head1 SYNOPSIS
110              
111             Given some roles:
112              
113             package Role;
114             use Moose::Role;
115             has foo => ( is => 'ro', isa => 'Int' required => 1 );
116              
117             And a class:
118              
119             package Class;
120             use Moose;
121             with 'MooseX::Traits';
122              
123             Apply the roles to the class at C<new> time:
124              
125             my $class = Class->with_traits('Role')->new( foo => 42 );
126              
127             Then use your customized class:
128              
129             $class->isa('Class'); # true
130             $class->does('Role'); # true
131             $class->foo; # 42
132              
133             =head1 DESCRIPTION
134              
135             Often you want to create components that can be added to a class
136             arbitrarily. This module makes it easy for the end user to use these
137             components. Instead of requiring the user to create a named class
138             with the desired roles applied, or apply roles to the instance
139             one-by-one, he can just create a new class from yours with
140             C<with_traits>, and then instantiate that.
141              
142             There is also C<new_with_traits>, which exists for compatibility
143             reasons. It accepts a C<traits> parameter, creates a new class with
144             those traits, and then instantiates it.
145              
146             Class->new_with_traits( traits => [qw/Foo Bar/], foo => 42, bar => 1 )
147              
148             returns exactly the same object as
149              
150             Class->with_traits(qw/Foo Bar/)->new( foo => 42, bar => 1 )
151              
152             would. But you can also store the result of C<with_traits>, and call
153             other methods:
154              
155             my $c = Class->with_traits(qw/Foo Bar/);
156             $c->new( foo => 42 );
157             $c->whatever( foo => 1234 );
158              
159             And so on.
160              
161             =for Pod::Coverage apply_traits
162              
163             =head1 METHODS
164              
165             =over 4
166              
167             =item B<< $class->with_traits( @traits ) >>
168              
169             Return a new class with the traits applied. Use like:
170              
171             =item B<< $class->new_with_traits(%args, traits => \@traits) >>
172              
173             C<new_with_traits> can also take a hashref, e.g.:
174              
175             my $instance = $class->new_with_traits({ traits => \@traits, foo => 'bar' });
176              
177             =back
178              
179             =head1 ATTRIBUTES YOUR CLASS GETS
180              
181             This role will add the following attributes to the consuming class.
182              
183             =head2 _trait_namespace
184              
185             You can override the value of this attribute with C<default> to
186             automatically prepend a namespace to the supplied traits. (This can
187             be overridden by prefixing the trait name with C<+>.)
188              
189             Example:
190              
191             package Another::Trait;
192             use Moose::Role;
193             has 'bar' => (
194             is => 'ro',
195             isa => 'Str',
196             required => 1,
197             );
198              
199             package Another::Class;
200             use Moose;
201             with 'MooseX::Traits';
202             has '+_trait_namespace' => ( default => 'Another' );
203              
204             my $instance = Another::Class->new_with_traits(
205             traits => ['Trait'], # "Another::Trait", not "Trait"
206             bar => 'bar',
207             );
208             $instance->does('Trait') # false
209             $instance->does('Another::Trait') # true
210              
211             my $instance2 = Another::Class->new_with_traits(
212             traits => ['+Trait'], # "Trait", not "Another::Trait"
213             );
214             $instance2->does('Trait') # true
215             $instance2->does('Another::Trait') # false
216              
217             =head1 AUTHOR
218              
219             Jonathan Rockway <jrockway@cpan.org>
220              
221             =head1 CONTRIBUTORS
222              
223             =for stopwords Karen Etheridge Florian Ragwitz Tomas Doran Hans Dieter Pearcey Rafael Kitover Stevan Little Alexander Hartmaier
224              
225             =over 4
226              
227             =item *
228              
229             Karen Etheridge <ether@cpan.org>
230              
231             =item *
232              
233             Florian Ragwitz <rafl@debian.org>
234              
235             =item *
236              
237             Tomas Doran <bobtfish@bobtfish.net>
238              
239             =item *
240              
241             Hans Dieter Pearcey <hdp@weftsoar.net>
242              
243             =item *
244              
245             Rafael Kitover <rkitover@cpan.org>
246              
247             =item *
248              
249             Stevan Little <stevan.little@iinteractive.com>
250              
251             =item *
252              
253             Alexander Hartmaier <abraxxa@cpan.org>
254              
255             =back
256              
257             =head1 COPYRIGHT AND LICENSE
258              
259             This software is copyright (c) 2008 by Infinity Interactive, Inc. http://www.iinteractive.com.
260              
261             This is free software; you can redistribute it and/or modify it under
262             the same terms as the Perl 5 programming language system itself.
263              
264             =cut