package Func; use Data::Dumper; require Exporter; @ISA = qw(Exporter); @EXPORT = qw(none any all); use overload ( '@{}', sub { my $this = shift; return $this->{data}; }, '""', sub { my $this = shift; return join($" , @{$this->{data}}) if $this->{type} eq 'all'; return $this->{data}->[int rand scalar @{$this->{data}}] if $this->{type} eq 'any'; return ''; }, 'bool', sub {my $this = shift; return $this->{bool}; } ); use vars qw/ $comparisons /; my @bins = qw(binary 3way_comparison num_comparison str_comparison); foreach my $op (split " ", "@overload::ops{ @bins }") { $comparisons->{$op} = eval "sub { return shift() $op shift() }"; eval "use overload '$op' => sub { handle( '$op', " . '@_' . ") };"; }; sub new { my $proto = shift; my $class = ref($proto) || $proto; my $type = shift || 'any'; return bless { type => $type , data => [@_], }, $class; } sub any { Func->new('any',@_); } sub all { Func->new('all',@_); } sub none { Func->new('none',@_); } sub true { my $self = shift; $self->{bool} = 1; return $self;} sub false { my $self = shift; $self->{bool} = 0; return $self;} sub handle { my ($how,$self,$compare, $reverse) = @_; my $true = all()->true(); my $false = all()->false(); foreach my $item (@{$self->{data}}) { my $test = $reverse ? $comparisons->{$how}->($compare,$item) : $comparisons->{$how}->($item,$compare); if ($test) { push @{$true->{data}}, $item; } else { push @{$false->{data}}, $item; } } return $true if (($self->{type} eq 'none') && scalar @{$true} == 0) or (($self->{type} eq 'all') && scalar @{$false} == 0) or (($self->{type} eq 'any') && scalar @{$true} != 0); return $false; } 1;