Hello Monks, I was reading through Effective Perl Programming, and at the end of Item 29, the author describes using closures with eval to "generate subroutines that have particular regular expressions 'locked in' with the same flexibility (and efficiency!) as if the expressions were specified at compile time." (pg. 114) Here is the sample subroutine that produces closures, along with extra code I added for testing:
#!/usr/local/bin/perl -w use strict; use re 'debug'; sub make_grep { my $pat = shift; eval 'sub { grep /$pat/o, @_ }'; } my $foo = make_grep( q/sacked/); warn 'assigned coderef to $foo'; my @mtchs = $foo->( qw(sacked soccer) ); warn 'called $foo->()';
I added use re 'debug' so I could see when $pat gets compiled, and I found that it doesn't until $foo->() is called (the output from the warn statements appears in red):

assigned coderef to $foo at anon line 11.
Compiling REx `sacked'
size 4 first at 1
1: EXACT <sacked>(4)
4: END(0)
anchored `sacked' at 0 (checking anchored isall) minlen 6
Guessing start of match, REx `sacked' against `sacked'...
Found anchored substr `sacked' at offset 0...
Guessed: match at offset 0
Guessing start of match, REx `sacked' against `soccer'...
Did not find anchored substr `sacked'...
Match rejected by optimizer
called $foo->() at anon line 13.
Freeing REx: `sacked'


Then I started wondering what the difference was between assigning an eval'ed single-quoted string containing an anonymous sub declaration (as above, that produces a coderef) and assigning a coderef without eval. So I changed make_grep above to this:
sub make_grep { my $pat = shift; sub { grep /$pat/o, @_ }; }
The rest of the code stayed the same, and here is the output, (warnings in red again):

assigned coderef to $foo at anon line 11.
Compiling REx `sacked'
size 4 first at 1
1: EXACT <sacked>(4)
4: END(0)
anchored `sacked' at 0 (checking anchored isall) minlen 6
Guessing start of match, REx `sacked' against `sacked'...
Found anchored substr `sacked' at offset 0...
Guessed: match at offset 0
Guessing start of match, REx `sacked' against `soccer'...
Did not find anchored substr `sacked'...
Match rejected by optimizer
called $foo->() at anon line 13.


What, if any, are the advantages of either method over the other? I have read many times that string eval should usually be avoided. In this case, it seems that both methods produce the same subroutine, where the regex will only be compiled the first time the method is invoked. I am confused as to why the author suggest using eval when it appears that assigning a coderef alone accomplishes the same thing. This topic was touched on in eval with sub, but I did not find a satisfactory answer in that thread.

Also, does anyone know why the eval'ed version triggers the "Freeing REx" output while the other version does not? (This occurs with Perl 5.6.0. Perl 5.7.2 (Devel) does not give the message for either version of the program.)

Thanks!

--sacked

In reply to coderef assignment with and without eval by sacked

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.