File Coverage

blib/lib/MooX/Attribute/ENV.pm
Criterion Covered Total %
statement 39 40 97.5
branch 17 22 77.2
condition n/a
subroutine 11 11 100.0
pod n/a
total 67 73 91.7


line stmt bran cond sub pod time code
1             package MooX::Attribute::ENV;
2              
3             our $VERSION = '0.01';
4              
5             # this bit would be MooX::Utils but without initial _ on func name
6 1     1   77346 use strict;
  1         2  
  1         27  
7 1     1   5 use warnings;
  1         2  
  1         20  
8 1     1   5 use Moo ();
  1         2  
  1         11  
9 1     1   439 use Moo::Role ();
  1         8507  
  1         25  
10 1     1   7 use Carp qw(croak);
  1         2  
  1         431  
11             #use base qw(Exporter);
12             #our @EXPORT = qw(override_function);
13             sub _override_function {
14 1     1   3 my ($target, $name, $func) = @_;
15 1 50       16 my $orig = $target->can($name) or croak "Override '$target\::$name': not found";
16 1 50       7 my $install_tracked = Moo::Role->is_role($target) ? \&Moo::Role::_install_tracked : \&Moo::_install_tracked;
17 1     5   38 $install_tracked->($target, $name, sub { $func->($orig, @_) });
  5     5   21078  
18             }
19             # end MooX::Utils;
20              
21             sub import {
22 1     1   10 my $target = scalar caller;
23             _override_function($target, 'has', sub {
24 5     5   21 my ($orig, $namespec, %opts) = @_;
25 5         11 my $old_default = $opts{default};
26 5 50       17 for my $name (ref $namespec ? @$namespec : $namespec) {
27 5         13 my $envkey = _generate_key($name, \%opts, $target);
28 5 50       15 $orig->($namespec, %opts), return if !defined $envkey; # non env
29             $orig->($name, %opts, default => sub {
30 60 100       9981 return $ENV{$envkey} if defined $ENV{$envkey};
31 55 100       190 return $ENV{uc $envkey} if defined $ENV{uc $envkey};
32 50 100       103 return $old_default->() if ref $old_default eq 'CODE';
33 40         489 $old_default;
34 5         32 });
35             }
36 1         7 });
37             }
38              
39             sub _generate_key {
40 5     5   12 my ($attr, $opts, $target) = @_;
41 5 100       17 return $attr if $opts->{env};
42 3 100       8 return $opts->{env_key} if $opts->{env_key};
43 2 100       8 return "$opts->{env_prefix}_$attr" if $opts->{env_prefix};
44 1 50       4 if ($opts->{env_package_prefix}) {
45 1         4 $target =~ s/:+/_/g;
46 1         4 return "${target}_$attr";
47             }
48 0           undef;
49             }
50              
51             =head1 NAME
52              
53             MooX::Attribute::ENV - Allow Moo attributes to get their values from %ENV
54              
55             =begin markdown
56              
57             # PROJECT STATUS
58              
59             | OS | Build status |
60             |:-------:|--------------:|
61             | Linux | [![Build Status](https://travis-ci.org/mohawk2/moox-attribute-env.svg?branch=master)](https://travis-ci.org/mohawk2/moox-attribute-env) |
62              
63             [![CPAN version](https://badge.fury.io/pl/moox-attribute-env.svg)](https://metacpan.org/pod/MooX::Attribute::ENV) [![Coverage Status](https://coveralls.io/repos/github/mohawk2/moox-attribute-env/badge.svg?branch=master)](https://coveralls.io/github/mohawk2/moox-attribute-env?branch=master)
64              
65             =end markdown
66              
67             =head1 SYNOPSIS
68              
69             package MyMod;
70             use Moo;
71             use MooX::Attribute::ENV;
72             # look for $ENV{attr_val} and $ENV{ATTR_VAL}
73             has attr => (
74             is => 'ro',
75             env_key => 'attr_val',
76             );
77             # looks for $ENV{otherattr} and $ENV{OTHERATTR}, then any default
78             has otherattr => (
79             is => 'ro',
80             env => 1,
81             default => 7,
82             );
83             # looks for $ENV{xxx_prefixattr} and $ENV{XXX_PREFIXATTR}
84             has prefixattr => (
85             is => 'ro',
86             env_prefix => 'xxx',
87             );
88             # looks for $ENV{MyMod_packageattr} and $ENV{MYMOD_PACKAGEATTR}
89             has packageattr => (
90             is => 'ro',
91             env_package_prefix => 1,
92             );
93              
94             $ perl -MMyMod -E 'say MyMod->new(attr => 2)->attr'
95             # 2
96             $ ATTR_VAL=3 perl -MMyMod -E 'say MyMod->new->attr'
97             # 3
98             $ OTHERATTR=4 perl -MMyMod -E 'say MyMod->new->otherattr'
99             # 4
100              
101             =head1 DESCRIPTION
102              
103             This is a L extension. It allows other attributes for L. If
104             any of these are given, then instead of the normal value-setting "chain"
105             for attributes of given, default; the chain will be given, environment,
106             default.
107              
108             The environment will be searched for either the given case, or upper case,
109             version of the names discussed below.
110              
111             When a prefix is mentioned, it will be prepended to the mentioned name,
112             with a C<_> in between.
113              
114             =head1 ADDITIONAL ATTRIBUTES
115              
116             =head2 env
117              
118             Boolean. If true, the name is the attribute, no prefix.
119              
120             =head2 env_key
121              
122             String. If true, the name is the given value, no prefix.
123              
124             =head2 env_prefix
125              
126             String. The prefix is the given value.
127              
128             =head2 env_package_prefix
129              
130             Boolean. If true, use as the prefix the current package-name, with C<::>
131             replaced with C<_>.
132              
133             =head1 AUTHOR
134              
135             Ed J, porting John Napiorkowski's excellent L.
136              
137             =head1 LICENCE
138              
139             The same terms as Perl itself.
140              
141             =cut
142              
143             1;