Sharing

2013年5月23日 星期四

Intermediate Perl 筆記 (二)

Chapter 6 Manipulating Complex Data Structures

Skip first

Chapter 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 subroutine

my $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';
                           }
         };



Chapter 8 Filehandle References

Skip first

Chapter 9 Regular Expression References

Skip first

Chapter 10 Practical Reference Tricks

Skip first

Chapter 11 Building Larger Programs

Skip first

Chapter 12 Creating Your Own Perl Distribution

Skip first

沒有留言: