File Coverage

blib/lib/MooseX/Declare.pm
Criterion Covered Total %
statement 25 25 100.0
branch n/a
condition n/a
subroutine 8 8 100.0
pod 0 1 0.0
total 33 34 97.0


line stmt bran cond sub pod time code
1 24     24   3841096 use strict;
  24         59  
  24         1016  
2 24     24   133 use warnings;
  24         48  
  24         1400  
3              
4             package MooseX::Declare;
5             # git description: 0.38-13-g6688142
6             $MooseX::Declare::VERSION = '0.39';
7             # ABSTRACT: Declarative syntax for Moose
8             # KEYWORDS: moose extension declaration syntax sugar method class
9              
10 24     24   21659 use aliased 'MooseX::Declare::Syntax::Keyword::Class', 'ClassKeyword';
  24         28573  
  24         137  
11 24     24   3005 use aliased 'MooseX::Declare::Syntax::Keyword::Role', 'RoleKeyword';
  24         63  
  24         161  
12 24     24   3330 use aliased 'MooseX::Declare::Syntax::Keyword::Namespace', 'NamespaceKeyword';
  24         64  
  24         210  
13              
14 24     24   2864 use namespace::clean 0.11;
  24         842  
  24         204  
15              
16             sub import {
17 87     87   13909 my ($class, %args) = @_;
18              
19 87         253 my $caller = caller();
20              
21 87         1873 strict->import;
22 87         1958 warnings->import;
23              
24 87         399 for my $keyword ($class->keywords) {
25 261         16122 $keyword->setup_for($caller, %args, provided_by => $class);
26             }
27             }
28              
29             sub keywords {
30 87     87 0 1116 ClassKeyword->new(identifier => 'class'),
31             RoleKeyword->new(identifier => 'role'),
32             NamespaceKeyword->new(identifier => 'namespace'),
33             }
34              
35             #pod =head1 SYNOPSIS
36             #pod
37             #pod use MooseX::Declare;
38             #pod
39             #pod class BankAccount {
40             #pod has 'balance' => ( isa => 'Num', is => 'rw', default => 0 );
41             #pod
42             #pod method deposit (Num $amount) {
43             #pod $self->balance( $self->balance + $amount );
44             #pod }
45             #pod
46             #pod method withdraw (Num $amount) {
47             #pod my $current_balance = $self->balance();
48             #pod ( $current_balance >= $amount )
49             #pod || confess "Account overdrawn";
50             #pod $self->balance( $current_balance - $amount );
51             #pod }
52             #pod }
53             #pod
54             #pod class CheckingAccount extends BankAccount {
55             #pod has 'overdraft_account' => ( isa => 'BankAccount', is => 'rw' );
56             #pod
57             #pod before withdraw (Num $amount) {
58             #pod my $overdraft_amount = $amount - $self->balance();
59             #pod if ( $self->overdraft_account && $overdraft_amount > 0 ) {
60             #pod $self->overdraft_account->withdraw($overdraft_amount);
61             #pod $self->deposit($overdraft_amount);
62             #pod }
63             #pod }
64             #pod }
65             #pod
66             #pod =head1 DESCRIPTION
67             #pod
68             #pod This module provides syntactic sugar for Moose, the postmodern object system
69             #pod for Perl 5. When used, it sets up the C<class> and C<role> keywords.
70             #pod
71             #pod B<Note:> Please see the L</WARNING> section below!
72             #pod
73             #pod =head1 KEYWORDS
74             #pod
75             #pod =head2 class
76             #pod
77             #pod class Foo { ... }
78             #pod
79             #pod my $anon_class = class { ... };
80             #pod
81             #pod Declares a new class. The class can be either named or anonymous, depending on
82             #pod whether or not a classname is given. Within the class definition Moose and
83             #pod L<MooseX::Method::Signatures> are set up automatically in addition to the other
84             #pod keywords described in this document. At the end of the definition the class
85             #pod will be made immutable. namespace::autoclean is injected to clean up Moose and
86             #pod other imports for you.
87             #pod
88             #pod Because of the way the options are parsed, you cannot have a class named "is",
89             #pod "with" or "extends".
90             #pod
91             #pod It's possible to specify options for classes:
92             #pod
93             #pod =over 4
94             #pod
95             #pod =item extends
96             #pod
97             #pod class Foo extends Bar { ... }
98             #pod
99             #pod Sets a superclass for the class being declared.
100             #pod
101             #pod =item with
102             #pod
103             #pod class Foo with Role { ... }
104             #pod class Foo with Role1 with Role2 { ... }
105             #pod class Foo with (Role1, Role2) { ... }
106             #pod
107             #pod Applies a role or roles to the class being declared.
108             #pod
109             #pod =item is mutable
110             #pod
111             #pod class Foo is mutable { ... }
112             #pod
113             #pod Causes the class not to be made immutable after its definition.
114             #pod
115             #pod Options can also be provided for anonymous classes using the same syntax:
116             #pod
117             #pod my $meta_class = class with Role;
118             #pod
119             #pod =back
120             #pod
121             #pod =head2 role
122             #pod
123             #pod role Foo { ... }
124             #pod
125             #pod my $anon_role = role { ... };
126             #pod
127             #pod Declares a new role. The role can be either named or anonymous, depending on
128             #pod whether or not a name is given. Within the role definition Moose::Role and
129             #pod MooseX::Method::Signatures are set up automatically in addition to the other
130             #pod keywords described in this document. Again, namespace::autoclean is injected to
131             #pod clean up Moose::Role and other imports for you.
132             #pod
133             #pod It's possible to specify options for roles:
134             #pod
135             #pod =over 4
136             #pod
137             #pod =item with
138             #pod
139             #pod role Foo with Bar { ... }
140             #pod
141             #pod Applies a role to the role being declared.
142             #pod
143             #pod =back
144             #pod
145             #pod =head2 before / after / around / override / augment
146             #pod
147             #pod before foo ($x, $y, $z) { ... }
148             #pod after bar ($x, $y, $z) { ... }
149             #pod around baz ($x, $y, $z) { ... }
150             #pod override moo ($x, $y, $z) { ... }
151             #pod augment kuh ($x, $y, $z) { ... }
152             #pod
153             #pod Add a method modifier. Those work like documented in L<Moose|Moose>, except for
154             #pod the slightly nicer syntax and the method signatures, which work like documented
155             #pod in L<MooseX::Method::Signatures|MooseX::Method::Signatures>.
156             #pod
157             #pod For the C<around> modifier an additional argument called C<$orig> is
158             #pod automatically set up as the invocant for the method.
159             #pod
160             #pod =head2 clean
161             #pod
162             #pod Sometimes you don't want the automatic cleaning the C<class> and C<role>
163             #pod keywords provide using namespace::autoclean. In those cases you can specify the
164             #pod C<dirty> trait for your class or role:
165             #pod
166             #pod use MooseX::Declare;
167             #pod class Foo is dirty { ... }
168             #pod
169             #pod This will prevent cleaning of your namespace, except for the keywords imported
170             #pod from C<Moose> or C<Moose::Role>. Additionally, a C<clean> keyword is provided,
171             #pod which allows you to explicitly clean all functions that were defined prior to
172             #pod calling C<clean>. Here's an example:
173             #pod
174             #pod use MooseX::Declare;
175             #pod class Foo is dirty {
176             #pod sub helper_function { ... }
177             #pod clean;
178             #pod method foo ($stuff) { ...; return helper_function($stuff); }
179             #pod }
180             #pod
181             #pod With that, the helper function won't be available as a method to a user of your
182             #pod class, but you're still able to use it inside your class.
183             #pod
184             #pod =head1 NOTE ON IMPORTS
185             #pod
186             #pod When creating a class with MooseX::Declare like:
187             #pod
188             #pod use MooseX::Declare;
189             #pod class Foo { ... }
190             #pod
191             #pod What actually happens is something like this:
192             #pod
193             #pod {
194             #pod package Foo;
195             #pod use Moose;
196             #pod use namespace::autoclean;
197             #pod ...
198             #pod __PACKAGE__->meta->make_immutable;
199             #pod }
200             #pod
201             #pod So if you declare imports outside the class, the symbols get imported into the
202             #pod C<main::> namespace, not the class' namespace. The symbols then cannot be called
203             #pod from within the class:
204             #pod
205             #pod use MooseX::Declare;
206             #pod use Data::Dump qw/dump/;
207             #pod class Foo {
208             #pod method dump($value) { return dump($value) } # Data::Dump::dump IS NOT in Foo::
209             #pod method pp($value) { $self->dump($value) } # an alias for our dump method
210             #pod }
211             #pod
212             #pod To solve this, only import MooseX::Declare outside the class definition
213             #pod (because you have to). Make all other imports inside the class definition.
214             #pod
215             #pod use MooseX::Declare;
216             #pod class Foo {
217             #pod use Data::Dump qw/dump/;
218             #pod method dump($value) { return dump($value) } # Data::Dump::dump IS in Foo::
219             #pod method pp($value) { $self->dump($value) } # an alias for our dump method
220             #pod }
221             #pod
222             #pod Foo->new->dump($some_value);
223             #pod Foo->new->pp($some_value);
224             #pod
225             #pod B<NOTE> that the import C<Data::Dump::dump()> and the method C<Foo::dump()>,
226             #pod although having the same name, do not conflict with each other, because the
227             #pod imported C<dump> function will be cleaned during compile time, so only the
228             #pod method remains there at run time. If you want to do more esoteric things with
229             #pod imports, have a look at the C<clean> keyword and the C<dirty> trait.
230             #pod
231             #pod =head1 WARNING
232             #pod
233             #pod =for comment rafl agreed we should have a warning, and mst wrote this:
234             #pod
235             #pod B<Warning:> MooseX::Declare is based on L<Devel::Declare>, a giant bag of crack
236             #pod originally implemented by mst with the goal of upsetting the perl core
237             #pod developers so much by its very existence that they implemented proper
238             #pod keyword handling in the core.
239             #pod
240             #pod As of perl5 version 14, this goal has been achieved, and modules such
241             #pod as L<Devel::CallParser>, L<Function::Parameters>, and L<Keyword::Simple> provide
242             #pod mechanisms to mangle perl syntax that don't require hallucinogenic
243             #pod drugs to interpret the error messages they produce.
244             #pod
245             #pod If you want to use declarative syntax in new code, please for the love
246             #pod of kittens get yourself a recent perl and look at L<Moops> instead.
247             #pod
248             #pod =head1 SEE ALSO
249             #pod
250             #pod =for :list
251             #pod * L<Moose>
252             #pod * L<Moose::Role>
253             #pod * L<MooseX::Method::Signatures>
254             #pod * L<namespace::autoclean>
255             #pod * vim syntax: L<http://www.vim.org/scripts/script.php?script_id=2526>
256             #pod * emacs syntax: L<http://github.com/jrockway/cperl-mode>
257             #pod * Geany syntax + notes: L<http://www.cattlegrid.info/blog/2009/09/moosex-declare-geany-syntax.html>
258             #pod * L<Devel::CallParser>
259             #pod * L<Function::Parameters>
260             #pod * L<Keyword::Simple>
261             #pod * L<Moops>
262             #pod
263             #pod =cut
264              
265              
266             1;
267              
268             __END__
269              
270             =pod
271              
272             =encoding UTF-8
273              
274             =head1 NAME
275              
276             MooseX::Declare - Declarative syntax for Moose
277              
278             =head1 VERSION
279              
280             version 0.39
281              
282             =head1 SYNOPSIS
283              
284             use MooseX::Declare;
285              
286             class BankAccount {
287             has 'balance' => ( isa => 'Num', is => 'rw', default => 0 );
288              
289             method deposit (Num $amount) {
290             $self->balance( $self->balance + $amount );
291             }
292              
293             method withdraw (Num $amount) {
294             my $current_balance = $self->balance();
295             ( $current_balance >= $amount )
296             || confess "Account overdrawn";
297             $self->balance( $current_balance - $amount );
298             }
299             }
300              
301             class CheckingAccount extends BankAccount {
302             has 'overdraft_account' => ( isa => 'BankAccount', is => 'rw' );
303              
304             before withdraw (Num $amount) {
305             my $overdraft_amount = $amount - $self->balance();
306             if ( $self->overdraft_account && $overdraft_amount > 0 ) {
307             $self->overdraft_account->withdraw($overdraft_amount);
308             $self->deposit($overdraft_amount);
309             }
310             }
311             }
312              
313             =head1 DESCRIPTION
314              
315             This module provides syntactic sugar for Moose, the postmodern object system
316             for Perl 5. When used, it sets up the C<class> and C<role> keywords.
317              
318             B<Note:> Please see the L</WARNING> section below!
319              
320             =head1 KEYWORDS
321              
322             =head2 class
323              
324             class Foo { ... }
325              
326             my $anon_class = class { ... };
327              
328             Declares a new class. The class can be either named or anonymous, depending on
329             whether or not a classname is given. Within the class definition Moose and
330             L<MooseX::Method::Signatures> are set up automatically in addition to the other
331             keywords described in this document. At the end of the definition the class
332             will be made immutable. namespace::autoclean is injected to clean up Moose and
333             other imports for you.
334              
335             Because of the way the options are parsed, you cannot have a class named "is",
336             "with" or "extends".
337              
338             It's possible to specify options for classes:
339              
340             =over 4
341              
342             =item extends
343              
344             class Foo extends Bar { ... }
345              
346             Sets a superclass for the class being declared.
347              
348             =item with
349              
350             class Foo with Role { ... }
351             class Foo with Role1 with Role2 { ... }
352             class Foo with (Role1, Role2) { ... }
353              
354             Applies a role or roles to the class being declared.
355              
356             =item is mutable
357              
358             class Foo is mutable { ... }
359              
360             Causes the class not to be made immutable after its definition.
361              
362             Options can also be provided for anonymous classes using the same syntax:
363              
364             my $meta_class = class with Role;
365              
366             =back
367              
368             =head2 role
369              
370             role Foo { ... }
371              
372             my $anon_role = role { ... };
373              
374             Declares a new role. The role can be either named or anonymous, depending on
375             whether or not a name is given. Within the role definition Moose::Role and
376             MooseX::Method::Signatures are set up automatically in addition to the other
377             keywords described in this document. Again, namespace::autoclean is injected to
378             clean up Moose::Role and other imports for you.
379              
380             It's possible to specify options for roles:
381              
382             =over 4
383              
384             =item with
385              
386             role Foo with Bar { ... }
387              
388             Applies a role to the role being declared.
389              
390             =back
391              
392             =head2 before / after / around / override / augment
393              
394             before foo ($x, $y, $z) { ... }
395             after bar ($x, $y, $z) { ... }
396             around baz ($x, $y, $z) { ... }
397             override moo ($x, $y, $z) { ... }
398             augment kuh ($x, $y, $z) { ... }
399              
400             Add a method modifier. Those work like documented in L<Moose|Moose>, except for
401             the slightly nicer syntax and the method signatures, which work like documented
402             in L<MooseX::Method::Signatures|MooseX::Method::Signatures>.
403              
404             For the C<around> modifier an additional argument called C<$orig> is
405             automatically set up as the invocant for the method.
406              
407             =head2 clean
408              
409             Sometimes you don't want the automatic cleaning the C<class> and C<role>
410             keywords provide using namespace::autoclean. In those cases you can specify the
411             C<dirty> trait for your class or role:
412              
413             use MooseX::Declare;
414             class Foo is dirty { ... }
415              
416             This will prevent cleaning of your namespace, except for the keywords imported
417             from C<Moose> or C<Moose::Role>. Additionally, a C<clean> keyword is provided,
418             which allows you to explicitly clean all functions that were defined prior to
419             calling C<clean>. Here's an example:
420              
421             use MooseX::Declare;
422             class Foo is dirty {
423             sub helper_function { ... }
424             clean;
425             method foo ($stuff) { ...; return helper_function($stuff); }
426             }
427              
428             With that, the helper function won't be available as a method to a user of your
429             class, but you're still able to use it inside your class.
430              
431             =head1 NOTE ON IMPORTS
432              
433             When creating a class with MooseX::Declare like:
434              
435             use MooseX::Declare;
436             class Foo { ... }
437              
438             What actually happens is something like this:
439              
440             {
441             package Foo;
442             use Moose;
443             use namespace::autoclean;
444             ...
445             __PACKAGE__->meta->make_immutable;
446             }
447              
448             So if you declare imports outside the class, the symbols get imported into the
449             C<main::> namespace, not the class' namespace. The symbols then cannot be called
450             from within the class:
451              
452             use MooseX::Declare;
453             use Data::Dump qw/dump/;
454             class Foo {
455             method dump($value) { return dump($value) } # Data::Dump::dump IS NOT in Foo::
456             method pp($value) { $self->dump($value) } # an alias for our dump method
457             }
458              
459             To solve this, only import MooseX::Declare outside the class definition
460             (because you have to). Make all other imports inside the class definition.
461              
462             use MooseX::Declare;
463             class Foo {
464             use Data::Dump qw/dump/;
465             method dump($value) { return dump($value) } # Data::Dump::dump IS in Foo::
466             method pp($value) { $self->dump($value) } # an alias for our dump method
467             }
468              
469             Foo->new->dump($some_value);
470             Foo->new->pp($some_value);
471              
472             B<NOTE> that the import C<Data::Dump::dump()> and the method C<Foo::dump()>,
473             although having the same name, do not conflict with each other, because the
474             imported C<dump> function will be cleaned during compile time, so only the
475             method remains there at run time. If you want to do more esoteric things with
476             imports, have a look at the C<clean> keyword and the C<dirty> trait.
477              
478             =head1 WARNING
479              
480             =for comment rafl agreed we should have a warning, and mst wrote this:
481              
482             B<Warning:> MooseX::Declare is based on L<Devel::Declare>, a giant bag of crack
483             originally implemented by mst with the goal of upsetting the perl core
484             developers so much by its very existence that they implemented proper
485             keyword handling in the core.
486              
487             As of perl5 version 14, this goal has been achieved, and modules such
488             as L<Devel::CallParser>, L<Function::Parameters>, and L<Keyword::Simple> provide
489             mechanisms to mangle perl syntax that don't require hallucinogenic
490             drugs to interpret the error messages they produce.
491              
492             If you want to use declarative syntax in new code, please for the love
493             of kittens get yourself a recent perl and look at L<Moops> instead.
494              
495             =head1 SEE ALSO
496              
497             =over 4
498              
499             =item *
500              
501             L<Moose>
502              
503             =item *
504              
505             L<Moose::Role>
506              
507             =item *
508              
509             L<MooseX::Method::Signatures>
510              
511             =item *
512              
513             L<namespace::autoclean>
514              
515             =item *
516              
517             vim syntax: L<http://www.vim.org/scripts/script.php?script_id=2526>
518              
519             =item *
520              
521             emacs syntax: L<http://github.com/jrockway/cperl-mode>
522              
523             =item *
524              
525             Geany syntax + notes: L<http://www.cattlegrid.info/blog/2009/09/moosex-declare-geany-syntax.html>
526              
527             =item *
528              
529             L<Devel::CallParser>
530              
531             =item *
532              
533             L<Function::Parameters>
534              
535             =item *
536              
537             L<Keyword::Simple>
538              
539             =item *
540              
541             L<Moops>
542              
543             =back
544              
545             =head1 AUTHOR
546              
547             Florian Ragwitz <rafl@debian.org>
548              
549             =head1 CONTRIBUTORS
550              
551             =for stopwords Karen Etheridge Ash Berlin Robert 'phaylon' Sedlacek Piers Cawley Nelo Onyiah Nick Perez Chas. J. Owens IV Yanick Champoux Stevan Little Devin Austin leedo Chris Prather Dave Rolsky Frank Wiegand Hans Dieter Pearcey Justin Hunter Matt Kraai Michele Beltrame Rafael Kitover Tomas Doran
552              
553             =over 4
554              
555             =item *
556              
557             Karen Etheridge <ether@cpan.org>
558              
559             =item *
560              
561             Ash Berlin <ash_github@firemirror.com>
562              
563             =item *
564              
565             Robert 'phaylon' Sedlacek <rs@474.at>
566              
567             =item *
568              
569             Piers Cawley <pdcawley@bofh.org.uk>
570              
571             =item *
572              
573             Nelo Onyiah <nelo.onyiah@gmail.com>
574              
575             =item *
576              
577             Nick Perez <nperez@cpan.org>
578              
579             =item *
580              
581             Chas. J. Owens IV <chas.owens@gmail.com>
582              
583             =item *
584              
585             Yanick Champoux <yanick@babyl.dyndns.org>
586              
587             =item *
588              
589             Stevan Little <stevan.little@iinteractive.com>
590              
591             =item *
592              
593             Devin Austin <dhoss@cpan.org>
594              
595             =item *
596              
597             leedo <lee@laylward.com>
598              
599             =item *
600              
601             Chris Prather <chris@prather.org>
602              
603             =item *
604              
605             Dave Rolsky <autarch@urth.org>
606              
607             =item *
608              
609             Frank Wiegand <fwie@cpan.org>
610              
611             =item *
612              
613             Hans Dieter Pearcey <hdp@cpan.org>
614              
615             =item *
616              
617             Justin Hunter <justin.d.hunter@gmail.com>
618              
619             =item *
620              
621             Matt Kraai <kraai@ftbfs.org>
622              
623             =item *
624              
625             Michele Beltrame <arthas@cpan.org>
626              
627             =item *
628              
629             Rafael Kitover <rkitover@io.com>
630              
631             =item *
632              
633             Tomas Doran <bobtfish@bobtfish.net>
634              
635             =back
636              
637             =head1 COPYRIGHT AND LICENSE
638              
639             This software is copyright (c) 2008 by Florian Ragwitz.
640              
641             This is free software; you can redistribute it and/or modify it under
642             the same terms as the Perl 5 programming language system itself.
643              
644             =cut