File Coverage

blib/lib/Begin/Declare.pm
Criterion Covered Total %
statement 54 62 87.1
branch 10 20 50.0
condition 1 3 33.3
subroutine 15 16 93.7
pod 0 9 0.0
total 80 110 72.7


line stmt bran cond sub pod time code
1             package Begin::Declare;
2 2     2   58892 use Devel::Declare;
  2         16852  
  2         12  
3 2     2   177 use warnings;
  2         5  
  2         58  
4 2     2   17 use strict;
  2         18  
  2         1085  
5            
6             sub croak {
7 0     0 0 0 s/\s+/ /g for my ($msg, $src) = @_;
8 0 0       0 $src =~ s/^(.{20}).*/$1'.../ or $src .= q(');
9 0         0 my $i;
10 0         0 1 while (caller ++$i) =~ /^(?:Begin|Devel)::Declare/;
11 0         0 my (undef, $file, $line) = caller $i;
12 0         0 die "Begin::Declare: $msg '$src at $file line $line.\n"
13             }
14            
15             my @types = qw (my our);
16             push @types, 'state' if $] >= 5.010;
17             my $type_re = join '|' => @types;
18            
19             sub import {
20 2     2   18 shift;
21 2         5 for (@_) {
22 0 0       0 /^($type_re)$/i or croak "not exported", $_;
23 0 0       0 /^[A-Z]/ or croak "first character must be uc in", $_;
24             }
25 2 100       9 @_ or @_ = map uc, grep {/my|our/ or $^H{feature_state}} @types;
  6 50       58  
26 2         5 my $caller = caller;
27 4         31 Devel::Declare->setup_for (
28 2         5 $caller => {map {$_ => {const => \&parser}} @_}
29             );
30 2     2   12 no strict 'refs';
  2         4  
  2         1849  
31 2     14   79 *{$caller.'::'.$_} = sub (@):lvalue {@_[0 .. $#_]} for @_
  4         71  
  14         11025  
32             }
33            
34             our $prefix = '';
35 140     140 0 675 sub get {substr Devel::Declare::get_linestr, length $prefix}
36 84     84 0 302 sub set { Devel::Declare::set_linestr $prefix . $_[0]}
37            
38             sub parser {
39 14     14 0 11284 local $prefix = substr get, 0, $_[1];
40 14         31 my $type = strip_type();
41 14         20 my $vars = strip_vars();
42 14         22 check_assign();
43 14         34 set "$type $vars; use Begin::Declare::Lift $vars " . get
44             }
45            
46             sub strip_space {
47 49     49 0 95 my $skip = Devel::Declare::toke_skipspace length $prefix;
48 49         65 set substr get, $skip;
49             }
50            
51             sub strip_type {
52 14     14 0 24 strip_space;
53 14 50       28 get =~ /^($type_re)(?:\b|$)/i or croak "not /$type_re/i", get;
54 14         31 $prefix .= $1 . ' ';
55 14         34 lc $1
56             }
57            
58             sub strip_vars {
59 14     14 0 22 strip_space;
60 14 100       27 strip_parens() or do {
61 7 50       10 (my $line = get) =~ s/^([\$\%\@])//
62             or croak "not a valid sigil", get =~ /(.)/;
63 7         12 my $sigil = $1;
64 7         12 set $line;
65 7         11 strip_space;
66 7 50       15 ($line = get) =~ s/^(\w+)//
67             or croak "not a lexical variable name", $sigil.$line;
68 7         14 set $line;
69 7         18 $sigil . $1
70             }
71             }
72            
73             sub strip_parens {
74 14 100   14 0 19 if (get =~ /^\(/) {
75 7         37 my $length = Devel::Declare::toke_scan_str length $prefix;
76 7         18 my $parens = Devel::Declare::get_lex_stuff;
77 7         14 Devel::Declare::clear_lex_stuff;
78 7         9 set substr get, $length;
79 7         36 $parens =~ s/\s+/ /g;
80 7         28 return "($parens)"
81             }
82             }
83            
84             sub check_assign {
85 14     14 0 23 strip_space;
86 14   33     28 /^=[^=]/ or croak "assignment '=' expected before", $_ for get
87             }
88            
89             $INC{'Begin/Declare/Lift.pm'}++;
90 14     14   1046 sub Begin::Declare::Lift::import {}
91            
92             our $VERSION = '0.06';
93            
94            
95             =head1 NAME
96            
97             Begin::Declare - compile time lexical variables
98            
99             =head1 VERSION
100            
101             version 0.06
102            
103             =head1 SYNOPSIS
104            
105             don't you hate writing:
106            
107             my ($foo, @bar);
108             BEGIN {
109             ($foo, @bar) = ('fooval', 1 .. 10);
110             }
111            
112             when you should be able to write:
113            
114             MY ($foo, @bar) = ('fooval', 1 .. 10);
115            
116             just C< use Begin::Declare; > and you can.
117            
118             =head1 EXPORT
119            
120             use Begin::Declare;
121            
122             is the same as:
123            
124             use Begin::Declare qw (MY OUR); # and STATE if "use feature 'state';"
125            
126             you can also write:
127            
128             use Begin::Declare qw (My Our);
129            
130             if you prefer those names.
131            
132             =head1 DECLARATIONS
133            
134             =head2 MY ... = ...;
135            
136             =over 4
137            
138             works just like the keyword C< my > except it lifts the assignment to compile
139             time.
140            
141             MY $x = 1; # my $x; BEGIN {$x = 1}
142             MY ($y, $z) = (2, 3); # my ($y, $z); BEGIN {($y, $z) = (2, 3)}
143            
144             =back
145            
146             =head2 OUR ... = ...;
147            
148             =over 4
149            
150             works just like the keyword C< our > except it lifts the assignment to compile
151             time.
152            
153             OUR ($x, @xs) = 1 .. 10; # our ($x, @xs); BEGIN {($x, @xs) = 1 .. 10}
154            
155             =back
156            
157             =head2 STATE ... = ...;
158            
159             =over 4
160            
161             works better than the keyword C< state > (since it supports list assignment
162             and is a proper lvalue (at least on it's rhs)) and it lifts the assignment to
163             compile time.
164            
165             STATE ($x, @xs) = 1 .. 10; # state ($x, @xs); BEGIN {($x, @xs) = 1 .. 10}
166            
167             for (1 .. 5) {
168             print ++STATE $x = 'a'; # bcdef
169             }
170            
171             =back
172            
173             =head1 AUTHOR
174            
175             Eric Strom, C<< >>
176            
177             =head1 BUGS
178            
179             please report any bugs or feature requests to
180             C, or through the web interface at
181             L. I will be
182             notified, and then you'll automatically be notified of progress on your bug as
183             I make changes.
184            
185             =head1 ACKNOWLEDGEMENTS
186            
187             the authors of L
188            
189             =head1 LICENSE AND COPYRIGHT
190            
191             copyright 2011 Eric Strom.
192            
193             This program is free software; you can redistribute it and/or modify it under
194             the terms of either: the GNU General Public License as published by the Free
195             Software Foundation; or the Artistic License.
196            
197             see http://dev.perl.org/licenses/ for more information.
198            
199             =cut
200            
201             1