Sharing

2013年5月5日 星期日

Perl 學習手冊第六版筆記(五)

Chapter 14 Strings and Sorting


String Functions


index, rindex, substr, sprintf,

String & Number Compare


sub by_number { $a <=> $b }
sub by_code_point { $a cmp $b }

Chapter 15 Smart Matching


http://perldoc.perl.org/perlsyn.html

use 5.010001;
say "I found a key matching 'Fred'" if %names ~~ /Fred/;

say "The arrays have the same elements!"
if @names1 ~~ @names2;

Example
Type of match
%a ~~ %b
hash keys identical
%a ~~ @b or @a ~~ %b
at least one key in %a is in @b
%a ~~ /Fred/ or /Fred/ ~~ %b
at least one key matches pattern
'Fred' ~~ %a
exists $a{Fred}
@a ~~ @b
arrays are the same
@a ~~ /Fred/
at least one element in @a matches pattern
$name ~~ undef
$name is not defined
$name ~~ /Fred/
pattern match
123 ~~ ’123.0’
numeric equality with “numish” string
’Fred’ ~~ ’Fred’
string equality
123 ~~ 456
numeric equality

The given Statement


Don't need to type "break" for each case. But you can add "continue", Perl tries next condition.

given ( $ARGV[0] ) {
    when ( 'Fred' )     {say 'Name is Fred' }
    when ( /fred/i )    {say 'Name has fred in it' }
    when ( /\AFred/ )   {say 'Name starts with Fred' }
    default             {say "I don't see a Fred" }
}


foreach ( @names ) { # don't use a named variable!
    when ( /fred/i )  { say 'Name has fred in it'; continue }
    when ( /\AFred/ ) { say 'Name starts with Fred'; continue }
    when ( 'Fred' )   { say 'Name is Fred'; }
    default           {say "I don't see a Fred" }
}


Chapter 16 Process Management


The system Function


system 'date';
exec 'date';
my $now = `date`;
my $output = qx(echo $$);
my $output = qx'echo $$';
my @who_lines = `who`;    #automatically get the data broken up by lines

Processes as File Handles


Pipe goes before or after the command that you want to run.
If you want a read filehandle, you use -|, and if you want a write filehandle, you use |- to show which side of the pipe you want to place the command.


open DATE, 'date|' or die "cannot pipe from date: $!";              # same as  date | my_program
open MAIL, '|mail merlyn' or die "cannot pipe to mail: $!";         # same as  my_program | mail merlyn
open my $date_fh, '-|', 'date' or die "cannot pipe from date: $!";
open my $mail_fh, '|-', 'mail merlyn' or die "cannot pipe to mail: $!";


Getting Down and Dirty with Fork

http://perldoc.perl.org/perlipc.html

Sending and Receiving Signals


Some Advanced Perl Techniques

Slices

#### Array Slice ########
my @names = qw{ zero one two three four five six seven eight nine };
my @numbers = ( @names )[ 9, 0, 2, 1, 0 ];
print "Bedrock @numbers\n"; # says Bedrock nine zero two one zero

#### Hash Slice ########
my @three_scores = ($score{"barney"}, $score{"fred"}, $score{"dino"});
my @three_scores = @score{ qw/ barney fred dino/ };


Trapping Errors

eval


As soon as the eval encounters a normally fatal error, it stops the entire block and continues with the rest
of the program. Notice that semicolon after the eval block. The return value of the eval is the last evaluated expression, just like a subroutine. If the eval caught a fatal error, it returns undef and puts the error
message in the $@ special variable, perhaps something like: Illegal division by zero
at my_program line 12.

my $barney = eval { $fred / $dino } // 'NaN';
if ($@) {
    print "An error occurred ($@), continuing\n";
}

Try::Tiny


use 5.010;
my $barney =
    try { 
        $fred / $dino 
    } catch {
        say "Error was $_"; # not $@
    } finally {
        say @_ ? 'There was an error' : 'Everything worked';
    };

autodie


use autodie;
open my $fh, '<', $filename; # still dies on error
Combine with Try:Tiny
se 5.010;
use autodie;
use Try::Tiny;
try {
    open my $fh, '<', $filename; # still dies on error
} catch {
    when( 'open' ) { say 'Got an open error' }
};

grep

my @odd_numbers = grep { $_ % 2 } 1..1000;

map

my @data = (4.75, 1.5, 2, 1234, 6.9456, 12345678.9, 29.95);
my @formatted_data = map { &big_money($_) } @data;

List::Util & List::MoreUtils

use List::Util qw(first);
my $first_match = first { /\bPebbles\b/i } @characters;

use List::Util qw(sum);
my $total = sum( 1..1000 ); # 500500

use List::Util qw(max);
my $max = max( 3, 5, 10, 4, 6 );

use List::Util qw(maxstr);
my $max = maxstr( @strings );

use List::Util qw(shuffle);
my @shuffled = shuffle(1..1000); # randomized order of elements

use List::MoreUtils qw(none any all);
if (none { $_ > 100 } @numbers) {
    print "No elements over 100\n"
} elsif (any { $_ > 50 } @numbers) {
    print "Some elements over 50\n";
} elsif (all { $_ < 10 } @numbers) {
    print "All elements are less than 10\n";
}

use List::MoreUtils qw(natatime);
my $iterator = natatime 3, @array;
while( my @triad = $iterator->() ) {
    print "Got @triad\n";
}

use List::MoreUtils qw(mesh);
my @abc = 'a' .. 'z';
my @numbers = 1 .. 20;
my @dinosaurs = qw( dino );
my @large_array = mesh @abc, @numbers, @dinosaurs;

沒有留言: