closures are a great idea to generate similar functions on the fly. one 
thing you should keep in mind is that when Perl search for variable, 
subroutine etc, it always search the lexical namespace before it search the 
symble table. consider the following:

$h->{'process'}->{'image'} = 1;
$h->{'process'}->{'text'} = 2;
$h->{'handle'}->{'image'} = 3;
$h->{'handle'}->{'text'} = 4;

foreach my $action (keys %{$h}){
        no strict 'refs';
        *$action = sub { return 0; };
}

sub process{
        #-- something really usual
        #-- but doesn't get called
        return 1;
}

sub handle{
        #-- something really usual
        #-- but doesn't get called
        return 1;
}

print handle(),"\n"; #-- print 0
print process(),"\n"; #-- print 0

the 2 suppose to be useful functions doesn't get called because Perl finds
the subroutines in the lexical namespace so it execute those instead.

this become more annoying if the keys to your hash is unknown(ie, comes from 
a CGI param, DB, file or user input) like:

while(<STDIN>){
        chop;
        push(@array,$_);
}

foreach my $i (@array){
        *$i = sub { #-- something
                    return 0; };
}

sub function1{  
        #-- will this be called?
        return 1;
}

sub function2{
        #-- will this be called?
        return 2;
}

sub function3{
        #-- will this be called?
        return 3;
}

print function1(),"\n"; #-- what will be printed here?

__END__

here you don't know what will be bound to the closure and thus can't be
sure if your function[1-3] will be called.

david

Gfoo wrote:

> Hello all...
> 
> A question regarding closures used as function templates:
> 
> Assume the following program #1:
> ------------------------------------------------------------
> use strict;
> my $food;
> 
> $food->{cat}->{young} = 'fish'; $food->{dog}->{young} = 'bones';
> $food->{dog}->{senior} = 'meat';
> 
> for my $pet (keys %{$food}){
> no strict 'refs';
> *$pet = sub   {
> my $argument = shift;
> return ($food->{$pet}->{$argument}) if
>     defined($food->{$pet}->{$argument});
> }
> }
> 
> print dog('young'),"\n";
> print cat('young'),"\n";
> 
> ------------------------------------------------------------
> 
> and the following program #2:
> ------------------------------------------------------------
> use strict;
> my $food;
> 
> sub dog {
>  my $argument = shift;
>  $food->{dog}->{young} = 'bones';
> $food->{dog}->{senior} = 'meat';
> 
> return ($food->{dog}->{$argument}) if
>     defined($food->{dog}->{$argument});
> }
> 
> sub cat {
> my $argument = shift;
>  $food->{cat}->{young} = 'fish';
> 
> return ($food->{cat}->{$argument}) if
>     defined($food->{cat}->{$argument});
> }
> 
> 
> print dog('young'),"\n";
> print cat('young'),"\n";
> 
> ------------------------------------------------------------
> 
> I like the first one (#1), because it is shorter (a nice abstract) and
> let me define many functions only by concetrating on the $food hash at
> the beginning of my file. Much code repetition avoided. My question is:
> Is it much better regarding memory usage to use the second one? If all
> the values of the $food hash are scalar strings that take up to 10 kb
> (all together) will I gain much savings in memory by using the second way
> (#2) and have the declarations of $food keys/values inside each function
> instead of putting them all on top of the file?
> 
> Another related question: I have these subs inside a module. Assume that
> I use the first way (#1). Since I 'use' this module in an other perl
> file, will all the $food hash stay in memory as long as the other perl
> file is running?
> 
> Thank you,
> GFoo


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to