in reply to Style Question on Closures

Your use of BEGIN is entirely appropriate for the code you posted. A normal sub definition is processed at compile time. What you're doing with the assignment to $get_strings is basically a sub definition, but since it takes the form of an assignment, Perl doesn't know that it should be handled at compile time. The BEGIN block forces the assignment to happen when it's needed. That's what BEGIN is for.

That said....

I don't see any real use being made of the neat features of a closure here. You could replace $get_strings with a normal subroutine &get_strings and it would work the same.

Perhaps you should choose a different sandbox to build this particular kind of castle....

    -- Chip Salzenberg, Free-Floating Agent of Chaos

Replies are listed 'Best First'.
Re: Re: Style Question on Closures
by jynx (Priest) on Jan 01, 2002 at 07:59 UTC

    Hmm,

    Firstly, thanks for the reply, i probably should've read up on subroutine parsing before posting, but i was blind to that apparently as it didn't even occur to me (*sigh* a post wasted on an RTFM question, sorry about that). That said, while it's true i didn't need to use a closure, this was practice. The reason for making the sub anonymous was so that only the get_init_strings subroutine could call it, which is a good intent, although admittedly completely wasted here. If i weren't so intent on using something i've never used before it would probably be closer to this (this code needs you to see where the loop happens since it's basically an orcish manuever):

    # Code simplified for brevity (again) my @files = get_files(); my $strings_file = shift(@ARGV) || "default"; my @init_strings; foreach my $file (@files) { my @strings = @init_strings || get_init_strings($strings_file, \@init_strings); push @strings, extra_strings(); # manipulate files here ... } sub get_init_strings { my $file = shift; my $strings = shift; open FILE, $file or die "Couldn't open $file: $!\n"; push @$strings, $_ while <FILE>; close FILE, $file or warn "Couldn't close $file: $!\n"; return @$strings; }
    This isn't tested, just the first thing that came to mind. And it would do what i did without any of the hassle. But it's not as much of a learning experience nor as fun :-)

    jynx

      There are practical uses for call-backs. One use is to provide some user of a Perl module a way to modify the behavior of that module. Here is a very simple example:
      use strict; package Foo; use Carp; sub new { my ($class,$msg) = @_; my $self = {msg => $msg}; return bless $self,$class; } sub print_me { my ($self,$cb) = @_; croak "not a code ref" unless ref $cb eq 'CODE'; return $cb->($self->{'msg'}); } package main; my $foo = Foo->new('hello world'); print $foo->print_me(sub {ucfirst shift}), "\n";
      Now the user can specify how they want the message printed. Like i said, a very simple example, but i am sure you can imagine this module doing a lot more behind the scenes. In these cases, providing a call-back instead of providing a list of choices can make a module more flexible, and keep you from maintaining that list of choices.

      UPDATE - drats. Just when i though i knew what a closure was .... perrin pointed out that this is indeed, not a closure ... a good example for a anonymous subs maybe, but not a closure. I stand corrected and apologetic to the 13 people that voted this node up.

      jeffa

      L-LL-L--L-LL-L--L-LL-L--
      -R--R-RR-R--R-RR-R--R-RR
      F--F--F--F--F--F--F--F--
      (the triplet paradiddle)