File Coverage

blib/lib/MooX/SingleArg.pm
Criterion Covered Total %
statement 33 35 94.2
branch 13 18 72.2
condition 3 3 100.0
subroutine 11 11 100.0
pod 3 4 75.0
total 63 71 88.7


line stmt bran cond sub pod time code
1             package MooX::SingleArg;
2             our $VERSION = '0.08';
3              
4             =encoding utf8
5              
6             =head1 NAME
7              
8             MooX::SingleArg - Support single-argument instantiation.
9              
10             =head1 SYNOPSIS
11              
12             package Foo;
13             use Moo;
14             with 'MooX::SingleArg';
15             Foo->single_arg('bar');
16             has bar => ( is=>'ro' );
17            
18             my $foo = Foo->new( 'goo' );
19             print $foo->bar(); # goo
20              
21             =cut
22              
23 1     1   8469 use Class::Method::Modifiers qw( install_modifier );
  1         1305  
  1         48  
24 1     1   6 use Carp qw( croak );
  1         2  
  1         31  
25              
26 1     1   5 use Moo::Role;
  1         1  
  1         6  
27 1     1   301 use strictures 2;
  1         5  
  1         37  
28 1     1   584 use namespace::clean;
  1         9279  
  1         5  
29              
30             with 'MooX::BuildArgsHooks';
31              
32             around NORMALIZE_BUILDARGS => sub{
33             my ($orig, $class, @args) = @_;
34              
35             @args = $class->NORMALIZE_SINGLE_ARG_BUILDARGS( @args );
36              
37             return $class->$orig( @args );
38             };
39              
40             sub NORMALIZE_SINGLE_ARG_BUILDARGS {
41 4     4 0 8 my ($class, @args) = @_;
42              
43             # Force force_single_arg to be set as we want it immutable
44             # on this class once the first object has been instantiated.
45 4 100       43 $class->force_single_arg( 0 ) if !defined $class->force_single_arg();
46              
47 4 50       10 croak "No single_arg was declared for the $class class" unless $class->has_single_arg();
48              
49 4 100       10 return( @args ) if @args!=1;
50              
51 3 100 100     39 return( @args ) unless ref($args[0]) ne 'HASH' or $class->force_single_arg();
52              
53 2         30 return( $class->single_arg() => $args[0] );
54             }
55              
56             =head1 CLASS ARGUMENTS
57              
58             =head2 single_arg
59              
60             __PACKAGE__->single_arg( 'foo' );
61              
62             Use this to declare the C of the single argument.
63              
64             =cut
65              
66             sub single_arg {
67 2     2 1 1546 my ($class, $value) = @_;
68              
69             install_modifier(
70             $class, 'around', 'single_arg' => sub{
71 6 50   6   108 if (@_>2) { croak "single_arg has already been set to $value on $class" }
  0         0  
72 6         18 return $value;
73             },
74 2 50       16 ) if defined $value;
75              
76 2         518 return $value;
77             }
78              
79             =head2 force_single_arg
80              
81             __PACKAGE__->force_single_arg( 1 );
82              
83             Causes single-argument processing to happen even if a hashref
84             is passed in as the single argument.
85              
86             =cut
87              
88             sub force_single_arg {
89 3     3 1 9 my ($class, $value) = @_;
90              
91             install_modifier(
92             $class, 'around', 'force_single_arg' => sub{
93 5 50   5   88 if (@_>2) { croak "force_single_arg has already been set to $value on $class" }
  0         0  
94 5         15 return $value;
95             },
96 3 100       17 ) if defined $value;
97              
98 3         495 return $value;
99             }
100              
101             =head1 CLASS METHODS
102              
103             =head2 has_single_arg
104              
105             Returns true if L has been called.
106              
107             =cut
108              
109             sub has_single_arg {
110 4     4 1 6 my $class = shift;
111 4 50       65 return defined( $class->single_arg() ) ? 1 : 0;
112             }
113              
114             1;
115             __END__