File Coverage

blib/lib/Kwargs.pm
Criterion Covered Total %
statement 18 18 100.0
branch 6 6 100.0
condition n/a
subroutine 5 5 100.0
pod 2 2 100.0
total 31 31 100.0


line stmt bran cond sub pod time code
1             package Kwargs;
2              
3             # ABSTRACT: Simple, clean handing of named/keyword arguments.
4              
5 1     1   501 use strict;
  1         1  
  1         36  
6 1     1   5 use warnings;
  1         2  
  1         59  
7              
8 1         10 use Sub::Exporter -setup => {
9             exports => [ qw(kw kwn) ],
10             groups => {
11             default => [ qw(kw kwn) ],
12             }
13 1     1   884 };
  1         36294  
14              
15             sub kwn(\@@) {
16 9     9 1 15 my $array = shift;
17 9         11 my $npos = shift;
18 9 100       30 my @pos = splice(@$array, 0, $npos) if $npos > 0;
19 9 100       40 my $hash = @$array == 1 ? $array->[0] : { @$array };
20 9 100       61 return (@pos, $hash) unless @_;
21 3         6 return (@pos, @{$hash}{@_});
  3         31  
22             }
23              
24             sub kw(\@@) {
25 4     4 1 28 splice(@_, 1, 0, 0);
26 4         15 goto &kwn;
27             }
28              
29             1;
30              
31              
32              
33             =pod
34              
35             =head1 NAME
36              
37             Kwargs - Simple, clean handing of named/keyword arguments.
38              
39             =head1 VERSION
40              
41             version 0.01
42              
43             =head1 SYNOPSIS
44              
45             use Kwargs;
46              
47             # just named
48             my ($foo, $bar, baz) = kw @_, qw(foo bar baz);
49              
50             # positional followed by named
51             my ($pos, $opt_one, $opt_two) = kwn @_, 1, qw(opt_one opt_two)
52              
53             # just a hashref
54             my $opts = kw @_;
55              
56             # positional then hashref
57             my ($one, $two, $opts) = kwn @_, 2;
58              
59             =head1 WHY?
60              
61             Named arguments are good, especially when you take lots of (sometimes
62             optional) arguments. There are two styles of passing named arguments (by
63             convention) in perl though, with and without braces:
64              
65             sub foo {
66             my $args = shift;
67             my $bar = $args->{bar};
68             }
69              
70             foo({ bar => 'baz' });
71              
72             sub bar {
73             my %args = @_;
74             my $foo = $args{foo};
75             }
76              
77             bar(foo => 'baz');
78              
79             If you want to support both calling styles (because it should be mainly a
80             style issue), then you have to do something like this:
81              
82             sub foo {
83             my $args = ref $_[0] eq 'HASH' ? $_[0] : { @_ };
84             my $bar = $args->{bar};
85             }
86              
87             Which is annoying, and not even entirely correct. What if someone wanted to
88             pass in a tied object for their optional arguments? That could work, but what
89             are the right semantics for checking for it? It also gets uglier if you want
90             to unpack your keyword arguments in one line for clarity:
91              
92             sub foo {
93             my ($one, $two, $three) =
94             @{ ref $_[0] eq 'HASH' ? $_[0] : { @_ } }{qw(one two three) };
95             }
96              
97             Did I say clarity? B Surely no one would actually put something
98             like that in his code. Except I found myself typing this very thing, and
99             I.
100              
101             =head1 EXPORTS
102              
103             Two functions (L and L) are exported by default. You can also ask for
104             them individually or rename them to something else. See L for
105             details.
106              
107             =head2 kw(@array, @names)
108              
109             Short for C
110              
111             =head2 kwn(@array, $number_of_positional_args, @names)
112              
113             Conceptually shifts off n positional arguments from array, then figures out
114             whether the rest of the array is a list of key-value pairs or a single
115             argument (usually, but not necessarily, a hashref). If you passed in any
116             @names, these are used as keys into the hash, and the values at those keys are
117             appended to any positional arguments and returned. If you do not pass @names,
118             you will get a hashref (or whatever the single argument was, like a tied
119             object) back.
120              
121             Note that if the single argument cannot be dereferenced as a hashref, this can
122             die. No attempt is made by this module to handle the exception.
123              
124             =head1 AUTHOR
125              
126             Paul Driver
127              
128             =head1 COPYRIGHT AND LICENSE
129              
130             This software is copyright (c) 2011 by Paul Driver .
131              
132             This is free software; you can redistribute it and/or modify it under
133             the same terms as the Perl 5 programming language system itself.
134              
135             =cut
136              
137              
138             __END__