Skip to content

Commit

Permalink
Merge branch 'optimisation/must_be-compiler' into optimisations
Browse files Browse the repository at this point in the history
The must_be compiler benefits to Sub::Exporter.
  • Loading branch information
dolmen committed Feb 26, 2016
2 parents 8c4e3a5 + b0e7634 commit 07267d6
Showing 1 changed file with 23 additions and 16 deletions.
39 changes: 23 additions & 16 deletions lib/Data/OptList.pm
Expand Up @@ -131,23 +131,11 @@ BEGIN {
);
}

sub __is_a {
my ($got, $expected) = @_;

return List::Util::first { __is_a($got, $_) } @$expected if ref $expected;

return defined (
exists($test_for{$expected})
? $test_for{$expected}->($got)
: Params::Util::_INSTANCE($got, $expected) ## no critic
);
}

sub mkopt {
my ($opt_list) = shift;

my ($moniker, $require_unique, $must_be); # the old positional args
my $name_test;
my ($name_test, $is_a);

if (@_) {
if (@_ == 1 and Params::Util::_HASHLIKE($_[0])) {
Expand All @@ -156,9 +144,28 @@ sub mkopt {
} else {
($moniker, $require_unique, $must_be) = @_;
}
}

$moniker = 'unnamed' unless defined $moniker;
# Transform the $must_be specification into a closure $is_a
# that will check if a value matches the spec

if (defined $must_be) {
$must_be = [ $must_be ] unless ref $must_be;
my @checks = map {
my $class = $_;
$test_for{$_}
|| sub { $_[1] = $class; goto \&Params::Util::_INSTANCE }
} @$must_be;

$is_a = (@checks == 1)
? $checks[0]
: sub {
my $value = $_[0];
List::Util::first { defined($_->($value)) } @checks
};

$moniker = 'unnamed' unless defined $moniker;
}
}

return [] unless $opt_list;

Expand All @@ -185,7 +192,7 @@ sub mkopt {
$i++
} elsif (! $name_test->($opt_list->[$i+1])) {
$value = $opt_list->[++$i];
if ($must_be && !__is_a($value, $must_be)) {
if ($is_a && !$is_a->($value)) {
my $ref = ref $value;
Carp::croak "$ref-ref values are not valid in $moniker opt list";
}
Expand Down

0 comments on commit 07267d6

Please sign in to comment.