File Coverage

blib/lib/Const/Fast/Exporter.pm
Criterion Covered Total %
statement 33 33 100.0
branch 2 2 100.0
condition 3 3 100.0
subroutine 7 7 100.0
pod n/a
total 45 45 100.0


line stmt bran cond sub pod time code
1             package Const::Fast::Exporter;
2             $Const::Fast::Exporter::VERSION = '0.01';
3             require 5.010;
4              
5 2     2   46147 use strict;
  2         4  
  2         46  
6 2     2   9 use warnings;
  2         2  
  2         44  
7 2     2   475 use Const::Fast;
  2         3529  
  2         8  
8              
9             my %is_readonly = (
10             SCALAR => sub { Internals::SvREADONLY(${ $_[0] }) },
11             HASH => sub { Internals::SvREADONLY(%{ $_[0] }) },
12             ARRAY => sub { Internals::SvREADONLY(@{ $_[0] }) },
13             );
14              
15             my @TYPES = keys %is_readonly;
16              
17             #=======================================================================
18             # This is the import function that we put in the module which is
19             # exporting const::fast variables. We look for all const variables
20             # and export them into the namespace that use'd the constants module.
21             #
22             # NOTE:
23             # when @FOOBAR is defined, the glob will also have *{...::FOOBAR}{SCALAR}
24             # defined. This is due to an assumption made in early versions of Perl 5.
25             # So we find all names in the symbol table, and then check whether
26             # (a) the relevant glob slot is filled, and then (b) whether the package
27             # variable has been marked as readonly (i.e. looks to be a Const::Fast
28             # immutable variable. If so, then we export it.
29             #
30             # Another approach would be to use Package::Stash::has_symbol('@FOOBAR'),
31             # or if we wanted to keep the number of dependencies down, we could
32             # lift the code here:
33             # https://metacpan.org/source/DOY/Package-Stash-0.37/lib/Package/Stash/PP.pm#L244-256
34             # Thanks to HAARG and Nicholas, who answered questions about this on #p5p
35             #=======================================================================
36              
37             my $immutable_variables_exporter = sub {
38 1     1   128 my $exporting_package = shift;
39 1         2 my $importing_package = caller();
40 1         43 my $symbol_table_ref = eval "\\\%${exporting_package}::";
41              
42 1         5 foreach my $variable (keys %$symbol_table_ref) {
43 7         8 foreach my $type (@TYPES) {
44 2     2   317 no strict 'refs';
  2         6  
  2         196  
45 21         21 my $globref = *{"${exporting_package}::${variable}"}{$type};
  21         37  
46 21 100 100     173 if (defined($globref) && &{ $is_readonly{$type} }($globref)) {
  9         13  
47 3         4 *{"${importing_package}::${variable}"} = $globref;
  3         11  
48             }
49             }
50             }
51             };
52              
53             #=======================================================================
54             # When someone uses Const::Fast::Exporter we drop Const::Fast::const
55             # into their namespace (so they don't have to use Const::Fast as well)
56             # and we also give their package an import() function, which will
57             # export all Const::Fast read-only variables.
58             #=======================================================================
59             sub import
60             {
61 1     1   7 my $exporting_package = shift;
62 1         3 my $importing_package = caller();
63              
64 2     2   10 no strict 'refs';
  2         4  
  2         144  
65              
66 1         2 *{"${importing_package}::const"} = *{"Const::Fast::const"}{CODE};
  1         4  
  1         4  
67 1         6 *{"${importing_package}::import"} = $immutable_variables_exporter;
  1         67  
68             }
69              
70             1;
71              
72             =head1 NAME
73              
74             Const::Fast::Exporter - create a module that exports Const::Fast immutable variables
75              
76             =head1 SYNOPSIS
77              
78             Create your module that defines the constants:
79              
80             package MyConstants;
81             use Const::Fast::Exporter;
82              
83             const our $ANSWER => 42;
84             const our @COLORS => qw/ red green blue /;
85             const our %ORIGIN => { x => 0, y => 0 };
86              
87             1;
88              
89             And then to use the constants:
90              
91             use MyConstants;
92              
93             print "The answer = $ANSWER\n";
94              
95             =head1 DESCRIPTION
96              
97             This module is helpful if you want to create a module
98             that defines L immutable variables,
99             which are then exported.
100             The SYNOPSIS provides just about everything you need to know.
101             When you use C,
102             it loads C for you,
103             which is why there isn't a C line in the SYNOPSIS.
104              
105             B the interface should be considered unstable.
106             At the moment it is very simple -- it just exports all symbols.
107             Possibly there should be an option to specify whether everything is an optional export, with a C<-all> switch. Maybe you'd do something like:
108              
109             use Const::Fast::Exporter -requested;
110              
111             Which says that people have to specifically request the constants they want,
112             rather than getting all of them by default.
113              
114             If you want to define tags,
115             then you should probably just use L or similar.
116              
117              
118             =head1 SEE ALSO
119              
120             L - lets you define read-only scalars, hashes, and arrays.
121              
122              
123             =head1 REPOSITORY
124              
125             L
126              
127              
128             =head1 AUTHOR
129              
130             Neil Bowers Eneilb@cpan.orgE
131              
132              
133             =head1 COPYRIGHT AND LICENSE
134              
135             This software is copyright (c) 2017 by Neil Bowers .
136              
137             This is free software; you can redistribute it and/or modify it under
138             the same terms as the Perl 5 programming language system itself.
139              
140             =cut
141