my ($name, $proto) = _check_name shift;
croak 'Optional arguments must be passed as key => value pairs' if @_ % 2;
my %opts = @_;
+
$opts{ref} ||= 'ref';
- $opts{sub} = 1 if not defined $opts{sub};
- $opts{compile} = 1 if not defined $opts{compile} and $opts{sub};
- $opts{wrong_ref} = 'undef' if not defined $opts{wrong_ref};
- my @cr;
+ $opts{sub} = 1 unless defined $opts{sub};
+ $opts{compile} = 1 if not defined $opts{compile} and $opts{sub};
+ $opts{wrong_ref} = 'undef' unless defined $opts{wrong_ref};
+
+ my @coderefs;
my $call;
if (defined $proto) {
- $call = _wrap $name, $proto, 0, '', \@cr, \%opts;
+ $call = _wrap $name, $proto, 0, '', \@coderefs, \%opts;
} else {
$call = _wrap $name, '', 0, '@_';
}
- if (@cr) {
- $call = 'my @c; '
- . join('', map { 'push @c, $_[' . $_ . ']; ' } @cr)
- . $call
+
+ if (@coderefs) {
+ my $decls = @coderefs > 1 ? 'my @c = @_[' . join(', ', @coderefs) . ']; '
+ : 'my @c = ($_[' . $coderefs[0] . ']); ';
+ $call = $decls . $call;
}
- $call = '{ ' . $call . ' }';
- $call = 'sub ' . $call if $opts{sub};
+
+ $call = "{ $call }";
+ $call = "sub $call" if $opts{sub};
+
if ($opts{compile}) {
- $call = eval $call;
- croak _clean_msg $@ if $@;
+ my $err;
+ {
+ local $@;
+ $call = eval $call;
+ $err = $@;
+ }
+ croak _clean_msg $err if $err;
}
+
return $call;
}
my $cb = wrap 'main::cb', sub => 0, wrong_ref => 'die';
my $x = ', sub{&{$c[0]}}, sub{&{$c[1]}}) ';
is($cb,
- join('', q!{ my @c; push @c, $_[2]; push @c, $_[3]; !,
+ join('', q!{ my @c = @_[2, 3]; !,
q!my $r = ref($_[0]); !,
q!if ($r eq 'SCALAR') { !,
q!my $r = ref($_[1]); !,