# factor out accumulating behavior: sub make_acc_fn(&@) { my $f = shift; $f->(@_); $f; } # mean sub mean { mean_acc(@_)->() } # all-at-once version sub mean_acc { # accumulating-function version my ($tot, $cnt); make_acc_fn { $cnt += @_; $tot += $_ for @_; $cnt ? $tot / $cnt : undef; } @_ ; } # uniq sub uniq { uniq_acc(@_)->() } sub uniq_acc { my %uniq; make_acc_fn { @uniq{ @_ } = (); wantarray ? keys %uniq : scalar keys %uniq; } @_ ; } # examples print mean(1,2,3,5), $/; # 2.5 my $m = mean_acc(); print "$_ => ", $m->($_), $/ for 1..5; # 1 => 1 # 2 => 1.5 # 3 => 2 # 4 => 2.5 # 5 => 3 print uniq(1,2,3,1..5), $/; # 41325 my $u = uniq_acc(1,2,3); print "$_ => ", $u->($_), $/ for 1..5; # 1 => 132 # 2 => 132 # 3 => 132 # 4 => 4132 # 5 => 41325