PerlRob has asked for the wisdom of the Perl Monks concerning the following question:

Hi all, I'm attempting to pass a conditional statement to a subroutine for evaluation in a while loop, but I'm having trouble getting Perl to DWIM. Here's a code snippet:
my $condition = '!-d $someDir'; my $result = checkForDirectory($condition); sub checkForDirectory { my $condition = shift; # This is where the problem is. I want to interpolate # the text in this variable and use it as my condition. # How can I get Perl to DWIM here? if ($condition) { doSomethingElse(); } }

Replies are listed 'Best First'.
Re: Pass conditions to a subroutine
by ikegami (Patriarch) on May 13, 2008 at 17:37 UTC

    You could use eval EXPR, but passing a sub reference is safer, clearer and easier.

    my $condition = sub { !-d $_[0] }; my $result = checkForDirectory($condition); sub checkForDirectory { my $condition = shift; ... if ($condition->($someDir)) { doSomethingElse(); } }

      Of course you could take advantage of one of the few times you would actually want to use a prototype and allow a more streamlined syntax:

      sub checkForDirectory (&) { my $cond = shift; ## ... } ## ... my $result = checkForDirectory { ! -d $_[0] }; my $also_result = checkForDirectory sub { -M $_[0] > 2 }

      Although doing it this way means that if your coderefs aren't inline (say they're coming from an array or hash based on some other external condition) you'll need to use a leading & to override the prototype check . . .

      my $predicate = sub { $_[0] =~ /^\d{4}-\d{2}-\d{2}/ }; my $other_result = &checkForDirectory( $predicate );

      The cake is a lie.
      The cake is a lie.
      The cake is a lie.

      Thanks to all--exactly what I was looking for!
Re: Pass conditions to a subroutine
by pc88mxer (Vicar) on May 13, 2008 at 17:37 UTC
    An anonymous subroutine would work here:
    my $cond = sub { !-d $_[0] }; perform_check($cond); sub perform_check { my $cond = shift; ... if ($cond->($possible_directory)) { doSomethingElse(); } }
Re: Pass conditions to a subroutine
by dragonchild (Archbishop) on May 13, 2008 at 17:38 UTC
    my $condition = sub { !-d $_[0] }; my $result = check( $condition ); sub check { my ($condition) = @_; # Obviously, you'll need to find $param from somewhere. if ( $condition->( $param ) ) { blah(); } }

    My criteria for good software:
    1. Does it work?
    2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?