package Comp; use strict qw( vars subs ); use warnings; sub import { my( $class, $file, $line ) = caller(); # # comp { ... } ?VAR? => SUB, ... # my $comp; $comp = sub (&;@) { my( $sub, $var, $list, @x ) = @_; if ( my $r = ref($var) ) { if ( $r eq 'CODE' ) { push @x, $list; $list = $var; $var = undef; } # if elsif ( $r ne 'SCALAR' ) { die "Neither a SCALAR nor a CODE reference in comp() in file '$file' at line $line.\n"; } # elsif } # if else { $var = \${$class.'::'.$var}; } # else my @l; for ( $list->() ) { $$var = $_ if defined $var; push @l, @x ? $comp->( $sub, @x ) : $sub->(); } # for return @l; }; # # lcomp { ... } ?VAR? => LAZYSUB, ... # my $lcomp; $lcomp = sub (&;@) { my( $sub, $var, $list, @x ) = @_; if ( my $r = ref($var) ) { if ( $r eq 'CODE' ) { push @x, $list; $list = $var; $var = undef; } # if elsif ( $r ne 'SCALAR' ) { die "Neither a SCALAR nor a CODE reference in comp() in file '$file' at line $line.\n"; } # elsif } # if else { $var = \${$class.'::'.$var}; } # else while ( defined( my $elem = $list->() ) ) { $$var = $elem if defined $var; my($res) = @x ? $lcomp->( $sub, @x ) : $sub->(); return $res if defined $res; } # for return undef; }; # # lazy { ... } START # my $lazy = sub (&$) { my( $sub, $val ) = @_; my $start = $val; return sub{ my($res) = $sub->(\$val); $val = $start if ! defined $res; return $res; }; }; *{$class.'::comp' } = $comp ; *{$class.'::lcomp'} = $lcomp; *{$class.'::lazy' } = $lazy ; } # import 1; __END__