File Coverage

blib/lib/Acme/constant.pm
Criterion Covered Total %
statement 26 33 78.7
branch 5 8 62.5
condition 2 3 66.6
subroutine 7 7 100.0
pod 0 1 0.0
total 40 52 76.9


line stmt bran cond sub pod time code
1             package Acme::constant;
2             {
3             $Acme::constant::VERSION = '0.1.3';
4             }
5 1     1   30473 use 5.014;
  1         4  
  1         49  
6 1     1   13 use strictures 1;
  1         8  
  1         26  
7 1     1   77 use Carp ();
  1         1  
  1         160  
8              
9             sub generate_constant {
10 6     6 0 16 my ($package, $name, @values) = @_;
11             # Prototype is used to make it work like a constant (constants
12             # shouldn't take arguments). While anonymous subroutines don't use
13             # prototypes, the prototype gets meaning when this subroutine is
14             # assigned to type glob.
15             my $constant = sub () : lvalue {
16             # When constant used as array, it's very simple to understand
17             # user wants an array. The !defined wantarray check is intended
18             # to detect use of wantarray() in void context.
19 26 100 66 26   229 if (wantarray || !defined wantarray) {
    50          
20 14         880 @values;
21             }
22             # When constant has one element, writing to it in scalar
23             # context is fine.
24             elsif (@values == 1) {
25 12         56 $values[0];
26             }
27             # This shows an error, as otherwise, this could cause a strange
28             # situation where scalar A shows (A)[0], when A has one
29             # element, and 2 when A has two elements. The behavior of Array
30             # constructor in ECMAScript is already confusing enough (new
31             # Array(3) is [,,,], but new Array(3, 3) is [3, 3]).
32             else {
33 0         0 Carp::croak "Can't call ${package}::$name in scalar context";
34              
35             # Return lvalue in order to make older versions of Perl
36             # happy, even when it's not going to be used.
37 0         0 @values;
38             }
39 6         30 };
40             # Make a block, to make a scope for strict "refs".
41             {
42             # Because of symbol table modifications, I have to allow
43             # symbolic references.
44 1     1   7 no strict qw(refs);
  1         3  
  1         225  
  6         9  
45 6         7 *{"${package}::$name"} = $constant;
  6         74  
46             }
47             }
48              
49             sub import {
50 6     6   10944 my $package = caller;
51              
52             # The first argument is this package name
53 6         9 my $name = shift;
54              
55             # Without arguments, simply fail.
56 6 50       25 if (@_ == 0) {
    50          
57 0         0 Carp::carp qq[Useless use of "$name" pragma];
58             }
59              
60             # When called with one argument, this argument would be hash
61             # reference.
62             elsif (@_ == 1) {
63 0         0 my %hash = %{shift()};
  0         0  
64             # each is safe here, as %hash is lexical variable.
65 0         0 while (my ($name, $value) = each %hash) {
66 0         0 generate_constant $package, $name, $value;
67             }
68             }
69              
70             # Otherwise, assume one constant, that possibly could return a list
71             # of values.
72             else {
73 6         9 my $name = shift;
74 6         16 generate_constant $package, $name, @_;
75             }
76 6         53 return;
77             }
78              
79             # Return positive value to make Perl happy.
80             'Acme!';
81              
82             __END__