Start with Paul Bennett, who is a Perl guy I know from Google Plus. He pointed to a function in Ramda.js, which allows you to create a number of filters as anonymous functions, put them in an array, pass that array, and do that test in one line.
- // Instead of
- if ( x > 10 && x % 2 --- 0 ) { console.log( 'Big and Even' ) }
- var gt10 = function(x) { return x > 10 }
- var even = R.allPredicates( [ gt10,even ] ) ;
- if ( f( x ) ) { console.log( 'Big and Even' ) }
Now, imagine if we're testing several things, rather than just one.
I thought "Hey, there's so much I could do with this in Perl. I've been thinking about writing a mail filter that takes a function Higher Order Perl style, so could generate a function based on the config file and pass it into the middle of Mail::IMAPClient
so I don't have to generate a menagerie of one-trick ponies. This, of course, is a fairly big idea to work with, and the allPredicates
is small enough that, with a half-hour of working through Perl I mostly thought I knew, I came up with this. Fifteen lines of code. I am happy.
#!/usr/bin/env perl | |
use feature qw'say state' ; | |
use strict ; | |
use utf8 ; | |
use warnings ; | |
use Data::Dumper ; | |
# https://plus.google.com/u/0/+PaulBennett/posts/EvLLxiAMjKR | |
# http://ramdajs.com/docs/R.html | |
# SAMPLE CODE | |
# var gt10 = function(x) { return x > 10; }; | |
# var even = function(x) { return x % 2 === 0}; | |
# var f = R.allPredicates([gt10, even]); | |
# f(11); //=> false | |
# f(12); //=> true | |
my $gt10 = sub { my $i = shift ; return $i > 10 } ; | |
my $even = sub { my $i = shift ; return $i % 2 == 0 } ; | |
my $odd = sub { my $i = shift ; return $i % 2 == 1 } ; | |
my $test = sub { say Dumper \@_ } ; | |
# my $f = allPredicates( $test ) ; | |
my $f = allPredicates( $gt10 , $even ) ; | |
my $g = allPredicates( $gt10 , $odd ) ; | |
for my $i ( 9 .. 20 ) { | |
if ( &$f( $i ) ) { say $i . ' big and even' } | |
} | |
for my $i ( map { $_ * 3 } 1 .. 10 ) { | |
if ( &$g( $i ) ) { say $i . ' big and odd' } | |
} | |
# say &$gt10( 1 ); | |
# say &$gt10( 12 ); | |
# say &$even( 1 ); | |
# say &$even( 12 ); | |
# say &$odd( 1 ); | |
# say &$odd( 12 ); | |
sub allPredicates { | |
my @functions = @_ ; | |
my $function = sub { | |
my $val = shift ; | |
my @tests = @functions ; | |
my @results ; | |
for my $t ( @tests ) { | |
my $r = &$t( $val ) ; | |
push @results, $r if $r ; | |
} | |
return 1 if scalar @tests == scalar @results ; | |
return 0 ; | |
} ; | |
return $function ; | |
} |
No comments:
Post a Comment