File Coverage

blib/lib/SQL/Translator/Role/ListAttr.pm
Criterion Covered Total %
statement 35 35 100.0
branch 16 16 100.0
condition 3 3 100.0
subroutine 8 8 100.0
pod 0 1 0.0
total 62 63 98.4


line stmt bran cond sub pod time code
1             package SQL::Translator::Role::ListAttr;
2              
3 74     74   464 use warnings;
  74         155  
  74         2305  
4 74     74   358 use strict;
  74         140  
  74         1900  
5              
6             =head1 NAME
7              
8             SQL::Translator::Role::ListAttr - context-sensitive list attributes
9              
10             =head1 SYNOPSIS
11              
12             package Foo;
13             use Moo;
14             use SQL::Translator::Role::ListAttr;
15              
16             with ListAttr foo => ( uniq => 1, append => 1 );
17              
18             =head1 DESCRIPTION
19              
20             This package provides a variable L for context-sensitive list
21             attributes.
22              
23             =cut
24              
25 74     74   356 use SQL::Translator::Utils qw(parse_list_arg ex2err uniq);
  74         143  
  74         3360  
26 74     74   2850 use Sub::Quote qw(quote_sub);
  74         24158  
  74         4222  
27              
28             use Package::Variant (
29 74         553 importing => {
30             'Moo::Role' => [],
31             },
32             subs => [qw(has around)],
33 74     74   31484 );
  74         306546  
34              
35             =head1 FUNCTIONS
36              
37             =head2 ListAttr $name => %parameters;
38              
39             Returns a L providing an arrayref attribute named C<$name>,
40             and wrapping the accessor to provide context-sensitivity both for
41             setting and getting. If no C or C is provided, the
42             default value is the empty list.
43              
44             On setting, the arguments are parsed using
45             L, and the accessor will return
46             an array reference or a list, depending on context.
47              
48             =head3 Parameters
49              
50             =over
51              
52             =item append
53              
54             If true, the setter will append arguments to the existing ones, rather
55             than replacing them.
56              
57             =item uniq
58              
59             If true, duplicate items will be removed, keeping the first one seen.
60              
61             =item may_throw
62              
63             If accessing the attribute might L
64             an exception (e.g. from a C or C check), this should be
65             set to make the accessor store the exception using
66             L and return undef.
67              
68             =item undef_if_empty
69              
70             If true, and the list is empty, the accessor will return C
71             instead of a reference to an empty in scalar context.
72              
73             =back
74              
75             Unknown parameters are passed through to the L call for
76             the attribute.
77              
78             =cut
79              
80             sub make_variant {
81 724     724 0 464747 my ($class, $target_package, $name, %arguments) = @_;
82              
83 724         1727 my $may_throw = delete $arguments{may_throw};
84 724         1357 my $undef_if_empty = delete $arguments{undef_if_empty};
85 724         1276 my $append = delete $arguments{append};
86             my $coerce = delete $arguments{uniq}
87 1006     1006   37210 ? sub { [ uniq @{parse_list_arg($_[0])} ] }
  1006         2910  
88 724 100       2791 : \&parse_list_arg;
89              
90             has($name => (
91             is => 'rw',
92             (!$arguments{builder} ? (
93 724 100       3321 default => quote_sub(q{ [] }),
94             ) : ()),
95             coerce => $coerce,
96             %arguments,
97             ));
98              
99             around($name => sub {
100 4405     4405   119445 my ($orig, $self) = (shift, shift);
101 4405         9860 my $list = parse_list_arg(@_);
102 4405 100       9122 $self->$orig([ @{$append ? $self->$orig : []}, @$list ])
  173 100       2832  
103             if @$list;
104              
105 4405         9301 my $return;
106 4405 100       7328 if ($may_throw) {
107 518 100       1276 $return = ex2err($orig, $self) or return;
108             }
109             else {
110 3887         53485 $return = $self->$orig;
111             }
112 4394 100 100     29176 my $scalar_return = !@{$return} && $undef_if_empty ? undef : $return;
113 4394 100       16626 return wantarray ? @{$return} : $scalar_return;
  1004         4363  
114 724         659942 });
115             }
116              
117             =head1 SEE ALSO
118              
119             =over
120              
121             =item L
122              
123             =item L
124              
125             =back
126              
127             =cut
128              
129             1;