File Coverage

blib/lib/MooseX/XSAccessor.pm
Criterion Covered Total %
statement 32 35 91.4
branch 2 4 50.0
condition 1 3 33.3
subroutine 11 11 100.0
pod 2 2 100.0
total 48 55 87.2


line stmt bran cond sub pod time code
1             package MooseX::XSAccessor;
2              
3 42     42   17525278 use 5.008;
  42         154  
4 42     42   217 use strict;
  42         80  
  42         869  
5 42     42   191 use warnings;
  42         78  
  42         1321  
6              
7 42     42   188 use Moose 2.0600 ();
  42         642  
  42         684  
8 42     42   11530 use MooseX::XSAccessor::Trait::Attribute ();
  42         139  
  42         1096  
9 42     42   234 use Scalar::Util qw(blessed);
  42         73  
  42         2426  
10              
11             BEGIN {
12 42     42   128 $MooseX::XSAccessor::AUTHORITY = 'cpan:TOBYINK';
13 42         836 $MooseX::XSAccessor::VERSION = '0.008';
14             }
15              
16             our $LVALUE;
17              
18 42     42   209 use Moose::Exporter;
  42         77  
  42         199  
19             "Moose::Exporter"->setup_import_methods;
20              
21             sub init_meta
22             {
23 136     136 1 1246315 shift;
24 136         553 my %p = @_;
25             Moose::Util::MetaRole::apply_metaroles(
26             for => $p{for_class},
27 136         797 class_metaroles => {
28             attribute => [qw( MooseX::XSAccessor::Trait::Attribute )],
29             },
30             );
31             }
32              
33             sub is_xs
34             {
35 30     30 1 58047 my $sub = $_[0];
36            
37 30 50 33     193 if (blessed($sub) and $sub->isa("Class::MOP::Method"))
    50          
38             {
39 0         0 $sub = $sub->body;
40             }
41             elsif (not ref $sub)
42             {
43 42     42   4990 no strict "refs";
  42         85  
  42         2965  
44 0         0 $sub = \&{$sub};
  0         0  
45             }
46            
47 30         176 require B;
48 30         277 !! B::svref_2object($sub)->XSUB;
49             }
50              
51             1;
52              
53             __END__
54              
55             =pod
56              
57             =for stopwords Auto-deref Mouse/Class::XSAccessor
58              
59             =encoding utf-8
60              
61             =head1 NAME
62              
63             MooseX::XSAccessor - use Class::XSAccessor to speed up Moose accessors
64              
65             =head1 SYNOPSIS
66              
67             package MyClass;
68            
69             use Moose;
70             use MooseX::XSAccessor;
71            
72             has foo => (...);
73              
74             =head1 DESCRIPTION
75              
76             This module accelerates L<Moose>-generated accessor, reader, writer and
77             predicate methods using L<Class::XSAccessor>. You get a speed-up for no
78             extra effort. It is automatically applied to every attribute in the
79             class.
80              
81             =begin private
82              
83             =item init_meta
84              
85             =end private
86              
87             The use of the following features of Moose attributes prevents a reader
88             from being accelerated:
89              
90             =over
91              
92             =item *
93              
94             Lazy builder or lazy default.
95              
96             =item *
97              
98             Auto-deref. (Does anybody use this anyway??)
99              
100             =back
101              
102             The use of the following features prevents a writer from being
103             accelerated:
104              
105             =over
106              
107             =item *
108              
109             Type constraints (except C<Any>; C<Any> is effectively a no-op).
110              
111             =item *
112              
113             Triggers
114              
115             =item *
116              
117             Weak references
118              
119             =back
120              
121             An C<rw> accessor is effectively a reader and a writer glued together, so
122             both of the above lists apply.
123              
124             Predicates can always be accelerated, provided you're using Class::XSAccessor
125             1.17 or above.
126              
127             Clearers can not be accelerated (as of current versions of Class::XSAccessor).
128              
129             =head2 Functions
130              
131             This module also provides one function, which is not exported so needs to be
132             called by its full name.
133              
134             =over
135              
136             =item C<< MooseX::XSAccessor::is_xs($sub) >>
137              
138             Returns a boolean indicating whether a sub is an XSUB.
139              
140             C<< $sub >> may be a coderef, L<Class::MOP::Method> object, or a qualified
141             sub name as a string (e.g. C<< "MyClass::foo" >>).
142              
143             =back
144              
145             =head2 Chained accessors and writers
146              
147             L<MooseX::XSAccessor> can detect chained accessors and writers created
148             using L<MooseX::Attribute::Chained>, and can accelerate those too.
149              
150             package Local::Class;
151             use Moose;
152             use MooseX::XSAccessor;
153             use MooseX::Attribute::Chained;
154            
155             has foo => (traits => ["Chained"], is => "rw");
156             has bar => (traits => ["Chained"], is => "ro", writer => "_set_bar");
157             has baz => ( is => "rw"); # not chained
158            
159             my $obj = "Local::Class"->new;
160             $obj->foo(1)->_set_bar(2);
161             print $obj->dump;
162              
163             =head2 Lvalue accessors
164              
165             L<MooseX::XSAccessor> will detect lvalue accessors created with
166             L<MooseX::LvalueAttribute> and, by default, skip accelerating them.
167              
168             However, by setting C<< $MooseX::XSAccessor::LVALUE >> to true
169             (preferably using the C<local> Perl keyword), you can force it to
170             accelerate those too. This introduces a visible change in behaviour
171             though. L<MooseX::LvalueAttribute> accessors normally allow two
172             patterns for setting the value:
173              
174             $obj->foo = 42; # as an lvalue
175             $obj->foo(42); # as a method call
176              
177             However, once accelerated, they may I<only> be set as an lvalue.
178             For this reason, setting C<< $MooseX::XSAccessor::LVALUE >> to true is
179             considered an experimental feature.
180              
181             =head1 HINTS
182              
183             =over
184              
185             =item *
186              
187             Make attributes read-only when possible. This means that type constraints
188             and coercions will only apply to the constructor, not the accessors, enabling
189             the accessors to be accelerated.
190              
191             =item *
192              
193             If you do need a read-write attribute, consider making the main accessor
194             read-only, and having a separate writer method. (Like
195             L<MooseX::SemiAffordanceAccessor>.)
196              
197             =item *
198              
199             Make defaults eager instead of lazy when possible, allowing your readers
200             to be accelerated.
201              
202             =item *
203              
204             If you need to accelerate just a specific attribute, apply the attribute
205             trait directly:
206              
207             package MyClass;
208            
209             use Moose;
210            
211             has foo => (
212             traits => ["MooseX::XSAccessor::Trait::Attribute"],
213             ...,
214             );
215              
216             =item *
217              
218             If you don't want to add a dependency on MooseX::XSAccessor, but do want to
219             use it if it's available, the following code will use it optionally:
220              
221             package MyClass;
222            
223             use Moose;
224             BEGIN { eval "use MooseX::XSAccessor" };
225            
226             has foo => (...);
227              
228             =back
229              
230             =head1 CAVEATS
231              
232             =over
233              
234             =item *
235              
236             Calling a writer method without a parameter in Moose does not raise an
237             exception:
238              
239             $person->set_name(); # sets name attribute to "undef"
240              
241             However, this is a fatal error in Class::XSAccessor.
242              
243             =item *
244              
245             MooseX::XSAccessor does not play nice with attribute traits that alter
246             accessor behaviour, or define additional accessors for attributes.
247             L<MooseX::SetOnce> is an example thereof. L<MooseX::Attribute::Chained>
248             is handled as a special case.
249              
250             =item *
251              
252             MooseX::XSAccessor only works on blessed hash storage; not e.g.
253             L<MooseX::ArrayRef> or L<MooseX::InsideOut>. MooseX::XSAccessor is
254             usually able to detect such situations and silently switch itself off.
255              
256             =back
257              
258             =head1 BUGS
259              
260             Please report any bugs to
261             L<http://rt.cpan.org/Dist/Display.html?Queue=MooseX-XSAccessor>.
262              
263             =head1 SEE ALSO
264              
265             L<MooseX::XSAccessor::Trait::Attribute>.
266              
267             L<Moose>, L<Moo>, L<Class::XSAccessor>.
268              
269             =head1 AUTHOR
270              
271             Toby Inkster E<lt>tobyink@cpan.orgE<gt>.
272              
273             =head1 COPYRIGHT AND LICENCE
274              
275             This software is copyright (c) 2013, 2017 by Toby Inkster.
276              
277             This is free software; you can redistribute it and/or modify it under
278             the same terms as the Perl 5 programming language system itself.
279              
280             =head1 DISCLAIMER OF WARRANTIES
281              
282             THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
283             WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
284             MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
285