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.02';
3             require 5.010;
4              
5 2     2   67864 use strict;
  2         14  
  2         56  
6 2     2   10 use warnings;
  2         4  
  2         47  
7 2     2   895 use Const::Fast;
  2         4812  
  2         11  
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   157 my $exporting_package = shift;
39 1         2 my $importing_package = caller();
40 1         53 my $symbol_table_ref = eval "\\\%${exporting_package}::";
41              
42 1         5 foreach my $variable (keys %$symbol_table_ref) {
43 7         14 foreach my $type (@TYPES) {
44 2     2   420 no strict 'refs';
  2         4  
  2         292  
45 21         27 my $globref = *{"${exporting_package}::${variable}"}{$type};
  21         42  
46 21 100 100     57 if (defined($globref) && &{ $is_readonly{$type} }($globref)) {
  9         16  
47 3         5 *{"${importing_package}::${variable}"} = $globref;
  3         14  
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   9 my $exporting_package = shift;
62 1         3 my $importing_package = caller();
63              
64 2     2   24 no strict 'refs';
  2         3  
  2         212  
65              
66 1         2 *{"${importing_package}::const"} = *{"Const::Fast::const"}{CODE};
  1         5  
  1         3  
67 1         2 *{"${importing_package}::import"} = $immutable_variables_exporter;
  1         88  
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             L - another module you can use to create your
123             own module that exports constant and immutable variables.
124              
125             L - declare and export function-based constants,
126             similar to those declared with the L pragma.
127              
128             L - declare and export function-based constants.
129              
130             L - create a module that exports constants,
131             where the value is only generated the first time its used.
132              
133             =head1 REPOSITORY
134              
135             L
136              
137              
138             =head1 AUTHOR
139              
140             Neil Bowers Eneilb@cpan.orgE
141              
142              
143             =head1 COPYRIGHT AND LICENSE
144              
145             This software is copyright (c) 2017 by Neil Bowers .
146              
147             This is free software; you can redistribute it and/or modify it under
148             the same terms as the Perl 5 programming language system itself.
149              
150             =cut
151