1 # Original package Data::OptList downloaded from CPAN on 6/15/2012. This module
2 # has been modified by Andreas Schuh on 6/15/2012 to make it part of BASIS.
6 package BASIS::Data::OptList;
8 $BASIS::Data::OptList::VERSION = '0.107';
10 # ABSTRACT: parse and validate simple name/value option pairs
13 use BASIS::Params::Util ();
14 use BASIS::Sub::Install 0.921 ();
20 CODE => \&BASIS::Params::Util::_CODELIKE, ## no critic
21 HASH => \&BASIS::Params::Util::_HASHLIKE, ## no critic
22 ARRAY => \&BASIS::Params::Util::_ARRAYLIKE, ## no critic
23 SCALAR => \&BASIS::Params::Util::_SCALAR0, ## no critic
28 my ($got, $expected) = @_;
30 return List::Util::first { __is_a($got, $_) } @$expected if ref $expected;
33 exists($test_for{$expected})
34 ? $test_for{$expected}->($got)
35 : BASIS::Params::Util::_INSTANCE($got, $expected) ## no critic
40 my ($opt_list) = shift;
42 my ($moniker, $require_unique, $must_be); # the old positional args
45 if (@_ == 1 and BASIS::Params::Util::_HASHLIKE($_[0])) {
47 ($moniker, $require_unique, $must_be, $name_test)
48 = @$arg{ qw(moniker require_unique must_be name_test) };
50 ($moniker, $require_unique, $must_be) = @_;
53 $moniker = 'unnamed' unless defined $moniker;
55 return [] unless $opt_list;
57 $name_test ||= sub { ! ref $_[0] };
60 map { $_ => (ref $opt_list->{$_} ? $opt_list->{$_} : ()) } keys %$opt_list
61 ] if ref $opt_list eq 'HASH';
66 for (my $i = 0; $i < @$opt_list; $i++) { ## no critic
67 my $name = $opt_list->[$i];
70 if ($require_unique) {
71 Carp::croak "multiple definitions provided for $name" if $seen{$name}++;
74 if ($i == $#$opt_list) { $value = undef; }
75 elsif (not defined $opt_list->[$i+1]) { $value = undef; $i++ }
76 elsif ($name_test->($opt_list->[$i+1])) { $value = undef; }
77 else { $value = $opt_list->[++$i] }
79 if ($must_be and defined $value) {
80 unless (__is_a($value, $must_be)) {
82 Carp::croak "$ref-ref values are not valid in $moniker opt list";
86 push @return, [ $name => $value ];
94 my ($opt_list, $moniker, $must_be) = @_;
95 return {} unless $opt_list;
97 $opt_list = mkopt($opt_list, $moniker, 1, $must_be);
98 my %hash = map { $_->[0] => $_->[1] } @$opt_list;
104 *import = BASIS::Sub::Install::exporter {
105 exports => [qw(mkopt mkopt_hash)],
116 BASIS::Data::OptList - parse and validate simple name/value option pairs
124 use BASIS::Data::OptList;
126 my $options = BASIS::Data::OptList::mkopt([
127 qw(key1 key2 key3 key4),
135 ...is the same thing, more or less, as:
142 [ key5 => { ... }, ],
143 [ key6 => [ ... ], ],
144 [ key7 => sub { ... }, ],
145 [ key8 => { ... }, ],
146 [ key8 => [ ... ], ],
151 Hashes are great for storing named data, but if you want more than one entry
152 for a name, you have to use a list of pairs. Even then, this is really boring
162 Just look at all those undefs! Don't worry, we can get rid of those:
165 map { $_ => undef } qw(foo bar baz),
169 Aaaauuugh! We've saved a little typing, but now it requires thought to read,
170 and thinking is even worse than typing... and it's got a bug! It looked right,
171 didn't it? Well, the C<< xyz => { ... } >> gets consumed by the map, and we
172 don't get the data we wanted.
174 With BASIS::Data::OptList, you can do this instead:
176 $values = BASIS::Data::OptList::mkopt([
181 This works by assuming that any defined scalar is a name and any reference
182 following a name is its value.
188 my $opt_list = BASIS::Data::OptList::mkopt($input, \%arg);
192 moniker - a word used in errors to describe the opt list; encouraged
193 require_unique - if true, no name may appear more than once
194 must_be - types to which opt list values are limited (described below)
195 name_test - a coderef used to test whether a value can be a name
196 (described below, but you probably don't want this)
198 This produces an array of arrays; the inner arrays are name/value pairs.
199 Values will be either "undef" or a reference.
201 Positional parameters may be used for compability with the old C<mkopt>
204 my $opt_list = BASIS::Data::OptList::mkopt($input, $moniker, $req_uni, $must_be);
206 Valid values for C<$input>:
209 hashref -> [ [ key1 => value1 ] ... ] # non-ref values become undef
210 arrayref -> every name followed by a non-name becomes a pair: [ name => ref ]
211 every name followed by undef becomes a pair: [ name => undef ]
212 otherwise, it becomes [ name => undef ] like so:
213 [ "a", "b", [ 1, 2 ] ] -> [ [ a => undef ], [ b => [ 1, 2 ] ] ]
215 By default, a I<name> is any defined non-reference. The C<name_test> parameter
216 can be a code ref that tests whether the argument passed it is a name or not.
217 This should be used rarely. Interactions between C<require_unique> and
218 C<name_test> are not yet particularly elegant, as C<require_unique> just tests
219 string equality. B<This may change.>
221 The C<must_be> parameter is either a scalar or array of scalars; it defines
222 what kind(s) of refs may be values. If an invalid value is found, an exception
223 is thrown. If no value is passed for this argument, any reference is valid.
224 If C<must_be> specifies that values must be CODE, HASH, ARRAY, or SCALAR, then
225 BASIS::Params::Util is used to check whether the given value can provide that
226 interface. Otherwise, it checks that the given value is an object of the kind.
230 [ qw(SCALAR HASH Object::Known) ]
234 _SCALAR0($value) or _HASH($value) or _INSTANCE($value, 'Object::Known')
238 my $opt_hash = BASIS::Data::OptList::mkopt_hash($input, $moniker, $must_be);
240 Given valid C<L</mkopt>> input, this routine returns a reference to a hash. It
241 will throw an exception if any name has more than one value.
245 Both C<mkopt> and C<mkopt_hash> may be exported on request.
249 Ricardo Signes <rjbs@cpan.org>
251 Modified by Andreas Schuh on 6/15/2012 in order to make it a subpackage
252 of the SBIA namespace for inclusion with the BASIS package.
254 =head1 COPYRIGHT AND LICENSE
256 This software is copyright (c) 2006 by Ricardo Signes.
258 This is free software; you can redistribute it and/or modify it under
259 the same terms as the Perl 5 programming language system itself.