List::Util
このモジュールをuseすると使える関数の定義は、↓のようになってるんだけど、
sub sum (@) { reduce { $a + $b } @_ } sub min (@) { reduce { $a < $b ? $a : $b } @_ } sub max (@) { reduce { $a > $b ? $a : $b } @_ } sub minstr (@) { reduce { $a lt $b ? $a : $b } @_ } sub maxstr (@) { reduce { $a gt $b ? $a : $b } @_ }
このreduceなる関数がめちゃ簡潔且つめちゃ便利なわけ。
で、この簡潔さを出すための仕掛けがまた、
短いコードながら難すぃ。
sub reduce (&@) { my $code = shift; no strict 'refs'; return shift unless @_ > 1; use vars qw($a $b); my $caller = caller; local(*{$caller."::a"}) = \my $a; local(*{$caller."::b"}) = \my $b; $a = shift; foreach (@_) { $b = $_; $a = &{$code}(); } $a; }