Chapter 6 Manipulating Complex Data Structures
Skip firstChapter 7 Subroutine References
Anonymous Subroutines
my $ginger = sub {
my $person = shift;
print "Ginger: (in a sultry voice) Well hello, $person!\n";
};
$ginger−>('Skipper');
Returning a Subroutine from a Subroutine
sub create_find_callback_that_counts {
my $count = 0;
return sub { print ++$count, ": $File::Find::name\n" };
}
Closure Variables
利用 closure variable,可以實做出 function generator.use File::Find;
sub print_bigger_than {
my $minimum_size = shift;
return sub { print "$File::Find::name\n" if −f and −s >= $minimum_size };
}
my $bigger_than_512 = print_bigger_than(512);
find($bigger_than_512, 'bin');
my $bigger_than_1024 = print_bigger_than(1024);
find($bigger_than_1024, 'bin');
The BEGIN keyword tells the Perl compiler that as soon as this block has been parsed successfully, jump for a moment to run phase and run the block as well.
BEGIN {
my $countdown = 10;
sub count_down { $countdown−− }
sub count_remaining { $countdown }
}
Local static variable, "state" key word. The state variable has a limitation, though. So far, we can initialize only scalar variable swith state. We can declare other types of variables, but we can’t initialize them:
use v5.10;
sub countdown {
state $countdown = 10;
$countdown−−;
}
sub add_to_tab {
state @castaways = qw(Ginger Mary Ann Gilligan); # compilation error
state %tab = map { $_, 0 } @castaways; # compilation error
$countdown{'main'}−−;
}
But, References are scalars, so we can initialize array or hash references.
use v5.10;
sub add_to_tab {
my $castaway = shift;
state $castaways = qw(Ginger Mary Ann Gilligan); # works!
state %tab = map { $_, 0 } @$castaways; # works!
$tab−>{$castaway}++;
}
Finding Out Who We Are
To get around this, v5.16 introduces the __SUB__ token to return a reference to the current subroutinemy $sub = sub {
state $n = 5;
return unless $n > -1;
say $n--;
__SUB__->();
};
$sub->();
Dump the function code
use v5.14;
use Data::Dump qw(dump);
use Data::Dump::Streamer;
my @luxuries = qw(Diamonds Furs Caviar);
my $hash = {
Gilligan => sub {say 'Gilligan'},
Skipper => sub {say 'SKipper'},
'Mr. Howell' => sub {say 'Mr.Howell'},
Ginger => sub {say $luxuries[rand @luxuries]},
};
Dump $hash;
The Output
my (@luxuries);
@luxuries = (
'Diamonds',
'Furs',
'Caviar'
);
$HASH1 = {
Gilligan => sub {
use strict 'refs';
BEGIN {
$^H{'feature_unicode'} = q(1);
$^H{'feature_say'} = q(1);
$^H{'feature_state'} = q(1);
$^H{'feature_switch'} = q(1);
}
say 'Gilligan';
},
Ginger => sub {
use strict 'refs';
BEGIN {
$^H{'feature_unicode'} = q(1);
$^H{'feature_say'} = q(1);
$^H{'feature_state'} = q(1);
$^H{'feature_switch'} = q(1);
}
say $luxuries[rand @luxuries];
},
"Mr. Howell" => sub {
use strict 'refs';
BEGIN {
$^H{'feature_unicode'} = q(1);
$^H{'feature_say'} = q(1);
$^H{'feature_state'} = q(1);
$^H{'feature_switch'} = q(1);
}
say 'Mr.Howell';
},
Skipper => sub {
use strict 'refs';
BEGIN {
$^H{'feature_unicode'} = q(1);
$^H{'feature_say'} = q(1);
$^H{'feature_state'} = q(1);
$^H{'feature_switch'} = q(1);
}
say 'SKipper';
}
};
沒有留言:
張貼留言