nb: closure featured in question convenient example; 1 i'm working substantially more complex this. iow, please disregard details of closure; matters, afaict, refers lexical variables in parent scope.
i want redefine sub foo
below first argument in call list::util::reduce
replaced reference nested closure.
use strict; use warnings fatal => 'all'; use list::util; sub foo { ( $x, $y ) = @_; return list::util::reduce { $y->[ $b ]{ $x } ? $a + ( 1 << $b ) : $a } 0, 0 .. $#$y; }
my first attempt this:
sub foo { ( $x, $y ) = @_; sub z { our ( $a, $b ); return exists $y->[ $b ]{ $x } ? $a | ( 1 << $b ) : $a; } return list::util::reduce \&z, 0, 0 .. $#{ $y }; }
...but results in warning saying variable "$y" not stay shared
.
i've seen sort of error before, , way know around replace nested sub
definition anonymous sub assigned variable. therefore, tried instead:
sub foo { ( $x, $y ) = @_; $z = sub { our ( $a, $b ); return exists $y->[ $b ]{ $x } ? $a | ( 1 << $b ) : $a; }; return list::util::reduce( $z, 0, 0 .. $#{ $y } ); }
now error says type of arg 1 list::util::reduce must block or sub {} (not private variable)
.
this don't understand. why passing subref first argument reduce
not supported?
ps: following work:
sub foo { ( $x, $y ) = @_; $z = sub { our ( $a, $b ); return exists $y->[ $b ]{ $x } ? $a | ( 1 << $b ) : $a; }; return list::util::reduce { $z->( $a, $b ) } 0, 0 .. $#{ $y }; }
...but know (a) what's wrong using subref first argument list::util::reduce
(e.g. there technical impediment supporting variant?); , (b) there more direct approach (than { $z->( $a, $b ) }
) passing list::util::reduce
nested closure?
reduce
has prototype of &@
. means calls must use 1 of following syntax:
reduce block list reduce sub block, list # first form short this. reduce \&name, list reduce \&$name, list # same third form, via reference (short form) reduce \&block, list # same third form, via reference (long form)
you use of following equivalent statements:
return reduce { exists $y->[ $b ]{ $x } ? $a | ( 1 << $b ) : $a } 0, 0 .. $#$y;
# long way of writing first. return reduce(sub { exists $y->[ $b ]{ $x } ? $a | ( 1 << $b ) : $a }, 0, 0 .. $#$y);
my $z = sub { exists $y->[ $b ]{ $x } ? $a | ( 1 << $b ) : $a }; return reduce(\&$z, 0, 0 .. $#$y);
you have option of overriding prototype.
my $z = sub { exists $y->[ $b ]{ $x } ? $a | ( 1 << $b ) : $a }; return &reduce($z, 0, 0 .. $#$y);
Comments
Post a Comment