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

hi monks,
i have an expression...
$content_array[$location] =~ m/\. $/s;
i am using this expression in many test conditions and i want to store it in a variable that is easier to read. for example instead of having to do...
if ($content_array[$location] =~ m/\. $/s)
i want to be able to do...
$last_in_sentence = ($content_array[$location] =~ m/\. $/s)
and then use it like this...
if ($last_in_sentence)
or
if (!($last_in_sentence)).
The above way does not work so i was just wondering if there was any other way i could do this.
Thanks.

edit (broquaint): added formatting

Replies are listed 'Best First'.
Re: expressions as constants
by broquaint (Abbot) on Jul 15, 2004 at 06:10 UTC
    Just stuff it in an anonymous subroutine e.g
    my $last_in_sentence = sub { $content_array[$location] =~ m/\. $/s }; if(&$last_in_sentence) { ... }
    See. perlsub and perlref for more info.
    HTH

    _________
    broquaint

Re: expressions as constants
by purp (Novice) on Jul 15, 2004 at 06:16 UTC

    Hi!

    What you need is closure. Closures are little anonymous functions that you can assign to a scalar and call repeatedly. You do that like so:

    my $last_in_sentence = sub {return $content_array[$loc] =~ m/\.$/}; [...] if (&$last_in_sentence) { [...] }

    Voila! Hope that helps.

    --j

      Closures are little anonymous functions that you can assign to a scalar and call repeatedly

      Not to pick nits, but that's not exactly what a closure is. What you've described is just a standard anonymous subroutine. A closure is a bit more than that. A closure captures any surrounding lexical variables, and keeps their values between calls to the subroutine. Here's the canonical example:

      sub makecounter { my $count = 0; return sub { ++$count }; } my $counter1 = makecounter; my $counter2 = makecounter; for (1 .. 5) { print $counter1->(), "\n"; } print $counter2->(), "\n";

      Update: another small bit of clarification. Anonymous subroutines are not necessary for creating closures. Regular subroutines will cause closure around any surrounding lexical variables, too. It's not as flexible, since you only get one closed set of lexical variables, but it works the same. Here's an example:

      { # create a scope for the closure my $count = 0; sub counter { ++$count } } for (1 .. 5) { print counter, "\n"; }
Re: expressions as constants
by davidj (Priest) on Jul 15, 2004 at 06:06 UTC
    This is probably neither the most graceful nor most efficient way to do it, but all you need to do is store your expression in a variable and eval the variable whenever you want to use it. For example:

    #!/usr/bin/perl # my $expr = '$a + $b'; my $a = 4; my $b = 3; print eval $expr, "\n"; $a = 6; print eval $expr, "\n"; if( (eval $expr) == 9 ) { print "eval \$expr = 9\n"; }
    output:

    247.~/perl/tmp > a.pl 7 9 eval $expr = 9
    hope this helps,

    davidj
Re: expressions as constants
by ercparker (Hermit) on Jul 15, 2004 at 05:56 UTC