Currying Patterns

Contents

One of the most dangerous books I’ve ever even partially read is MJD’s Higher Order Perl. In particular, its description of subroutine currying – that is, building more specific functions out of more general purpose ones – is a pattern I find incredibly useful.

The other day I found myself writing a number of routines that were surprisingly similar… kinda. They all implemented a common pattern, but across routines that were rather… different. I found myself wistfully longing for the familiar pattern of currying, and then realized – I’m working in PERL, DAMNIT.

  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17  sub validate_thing { _validate_subtest_wrapper(\&_validate_thing_guts, @_) } sub validate_class { _validate_subtest_wrapper(\&_validate_class_guts, @_) } sub validate_role { _validate_subtest_wrapper(\&_validate_role_guts, @_) } sub _validate_subtest_wrapper { my (func,func, func,thing, %args) = @_; # note incrementing by 2 because of our upper curried function local $Test::Builder::Level =$Test::Builder::Level + 2; # run tests w/o a subtest wrapper... return $func->($thing => %args) unless $args{-subtest}; # ...or with one. return$tb->subtest(delete $args{-subtest} => sub {$func->(\$thing => %args) }); } 

This is part of recent work of mine, extending Test::Moose::More to use subtests where they make sense. Here I was able to curry one function – _validate_subtest_wrapper() – by passing it a reference to another function, that it then invokes.

Excellent. Life is easier, as it should be.