百度空间 | 百度首页 
 
查看文章
 
Learning Perl 5th edition (perl 5.10) - part 2
2009-08-19 17:17

Note:

Chapter 1. Introduction

Unix: #!/usr/bin/perl -w or   #!/usr/bin/env perl (use -w because we like warnings)
windows: #!perl


Chapter 2. Scalar Data
Scalar data: undef, double(integer is actually doubles), string
List   data: list of scalar element. refer to Chapter 3.

undef data: it's another kind of scalar data. if you use a var without definition, it contains undef value, not string or doubles
eg.
$blank = $fred[142_857]; will try to get the 142_857th var which is not defined and an undef data tyep value is returned to $blank
undef value are widely used to represent "no ordinary value to return". eg. <STDIN> return undef if reaching the EOF. so we'll omit many such cases in the following note.
we can use defined(xxx) function to return true for defined value and false for undef value in condition test.

double begins with:
0(Octal base8)
0x(Hex base16)
0b(Bin base2)

string's char can be like:
\0.. char in octal
\x.. char in hex

string should be used with '' or ""
'': only \ can be used to escape sth.
"": \, $ and @ can be used. (@ is used to lead array, but unfortunately % is not allowed to lead hashes)

special operator:
"hello"."world" = "helloworld"
"fred"x3 = "fredfredfred"
5x4 = "5555"

how to use warnings:
(1) -w added to the perl command
(2) use warnings;
how to use diagnostics(warings with long message):
(1) use diagnostics;
(2) -Mdiagnostics added to the perl command

always use $ ahead of a variable !! (don't confuse it with shell var usage)

print:
(1) use , to seperate params:
print "the answer is", 6*7, ".\n";
(2) use ${} to keep clear:
print "fred ate ${what}s.\n"   or you can
print "fred ate $what"."s.\n"

unlike shell, single var need not "" to avoid empty string error

comparasion operator is opposite to shell:
doubles: == != < > <= >=
strings: eq ne lt gt le ge

boolean:
double: 0 false others true
string: '' false others true
others: convert them to double or string first

input:
just $line=<STDIN>; then you get the line including the '\n' in $line

chomp:
remove the last '\n' of a string
it's very useful because it's simplicity. and it's often used after $line=<STDIN> to
get rid of the last '\n'


Chapter 3 Lists and Arrays
List are list of scalar values(right value), Array is simply an variable to hold the list(left value)
ie. List are just collection of variables to represent collection of values. we can use ($fred, $barney) to represent the two variables as a whole. so you can do some operations on them as a whole. eg. assignment to them can be done like this: ($fred, $barney)=(1,2); so essentially list has nothing to do with array. But array use list internally to hold data.
And any place where scalar value is used, list can be used!!

we can use list to exchange two vars:
($fred, $barney)=($barney, $fred);

to use array, you don't need to define it, just use it! it will extend itself on need.
do it like this: (we use $ to refer an element, @ to refer the whole array)
$rocks[0]='haha';
$rocks[99]='schist'; (the var $#rocks indicate the last element index, ie. 99)
@rocks=(1,2,3,4,5,6);
@rocks=(1..10);
@rocks=("bedrock", "slate", "lava"); equals @rocks=qw(bedrock slate lava);
(qw can help us to avoid the "", it can use () !! ## // etc... to enclose values)
@home=(@rocks, "mother", "father");

pop, push, shift, unshift -- the faster way to resize the array.(compared with index)
We use them if possible instead of index !!!!!
@array=(1..10);
@m = pop @array;   #(1..9)
push @array,10;    #(1..10)
@n = shift @array; #(2..10)
unshift @array,1; #(1..10)

use foreach to iterate list(array) like this:
we iterate list, so () is needed after the $loopvar.
foreach $loopvar (@array) {
# do sth
}
foreach $loopvar ("bed", "room", "chair")) {
# do sth
}
foreach $loopvar (qw(bed room chair)) {
# do sth
}
but we always omit $loopvar, because the system defined $_ will play the role. and functions like print will by default use $_ if you just type print;
foreach (@array) {
print "$_";
}

reverse and sort: -- if you don't assigned it to left value, nothing happened !!
we can use them to do operation on a list/array:
@fred = reverse @fred;
@fred = sort @fred;

the most important section of this book: -- you must get used to it!!!
expression(like variable, function)'s value is dependent on what is expected, ie: scalar value or list value.
it may sound strange to C programmers because the function's return value is also dependent on what is expected. eg:
@list = @people # a list
$n = @people    # people list's elements count is assigned to $n !! very useful !!!
@backwards=reverse qw(yabba dabba doo); # a list is reversed and asigned
$backwards=reverse qw(yabba dabba doo); # a list is reversed and catenated to a string which is assigned to backwards.

<STDIN> can be used in list value context:
@lines = <STDIN>; # every line will be treated as an element and EOF will end the reading. CTL+D on Unix or CTL+Z on Windows leads to EOF.
chomp(@lines=<STDIN>); can also be used.


Chapter 4 Subroutines
-------- below is a perl script of quick reference to usage of subroutines ---------
#!perl
use strict;
# we always use strict to be strict to our potential errors.
# if use strict is used, global var is not allowed !!! always use my() before your vars

sub saysth {          
# my must be used if local var are to be defined. and () must be used if more than one vars.
# @_ is the predefined var for params list whose index starts from index 0.
# this line is very common to assign params to meaningful names, and use them later instead of @_.
# and $_[] is used to access @_'s elements if you want to use @_ directly.
# NOTICE: the $_[] has nothing to do with the $_(which is widely used, eg. the loop var of foreach)
my ($father, $son) = @_;
print $father, $_[0]; # the two var are the same
print $son, $_[1];     # the two var are the same

# this is the scalar context, so we assign @_'s elements count to arg_count
my $arg_count = @_;    # always use my to define local variables ! we seldom need global ones.
print "$arg_count\n";

# use wantarray fun to test where we return to scalar or list context.
# but if no proper value can be returned , we simply use "return" to automatically
# return undef in scalar context and null list in list context
if (wantarray) {
   (1..10);      # we always omit return if this is the last sentence to execute.
}else {
   return 5;     # strict programmers like to use return.
}
}

my @cows = &saysth;
my $sheep = &saysth;

print "@cows\n";
print "$sheep\n";

-------- endof perl script --------

NOTE: about ()
sth you must know: fun(a, b, c); is the same as what we see in C language. but we often omit (), ie. fun a, b, c;


Chapter 5 Input and Output
1. how to input
we use:
while (<STDIN>) {
chomp($_);
print "I saw $_";
}
instead of
while (defined(my $line=<STDIN>)) {
chomp($line);
print "I saw $line";
}
because it's complicated,
instead of
foreach (<STDIN>) {
print "I saw $_";
}
because foreach requires a list value, which cause <STDIN> to hold the whole input until EOF is encountered,
and then enter the foreach loop which will cause bad performance in reading large files !!!

NOTE: <STDIN> may return a scalar of a list too.

2. how to act like unix tool behavior:
(1) file arg can be replaced with -
(2) perl script can be used in pipe condition
eg. "cat file1.txt file2.txt" can be replaced with "cat -" (or just cat) if you prefer STDIN
we use:
while (<>) {
chomp;
print "It was $_ that I saw!\n";
}
instead of
while (define(my $line = <>)) {
chomp($line);
print "It was $line that I saw!\n"
}
because it's complicated,
NOTE: <> may return a scalar of a list too.

3. @ARGV
the cmd line args array which we can use "shift" or "foreach" to iterate
eg.
my $arg1 = shift @ARGV;

4. output the array:
my @array=qw(sheep cow chick);
print @array; # sheepcowchick
print "@array" # sheep cow chick

5. cat and sort
print <>;        # <> return a list. and print display it.
print sort <>;   # the unix sort function

6. weird print:
print (2+3)*4; # only 5 is printed. because if there's () behind print, print will be used as a function. it will only print the result in () and return , saying 1.
so do it like this:
print ((2+3)*4);

NOTE: if () is given, print only print the result in (). if not given, print will print all the stuff following itself, ie. treat them all as a list value.

7. printf:
the same as C printf.
eg.
printf ("%12.3f\n", 6*7+2/3); # width is 12, right alignment, allow 3 digit after the dot of float

except:
(1)%g is provided to automatically select float, int or exp
(2)%% can be used to print "%". not \% !!!!! \% won't work :(
(3)print array:
printf "The items are:\n".("%10s\n" x @items), @items;
# the first @items is in the scalar context and return the size of the array.
# the second @items is in the list context and return the list of the array.

8. the filehandle
6 predefined: STDIN, STDOUT, STDERR, DATA, ARGV, ARGVOUT
(1) open file for read,write,append:
open CONFIG, "<dino.txt";    # open dino.txt for read, CONFIG is the filehandler
open BEDROCK, ">fred.txt";   # open fred.txt for write, BEDROCK is the filehandler
open LOG, ">>logfile.txt";   # open logfile.txt for appending, LOG is the filehandler
(2) close file:
just "close filehandle;"
(3) check open error:
if (!open LOG, ">>logfile.txt") {
die "open logfile.txt error: $!";
    # we use $! to get what perror give us, ie. system error info
# if we dont use the linux system API, omit the $! here.
}
or you can use a var to hold the return value:
my $success = open LOG, ">>logfile.txt";
if (!$success) {
die "...";
}
or we can just use "warn" to warn users without exit.
(4) read from/write to filehandler (predefined or user-defined filehandler)
read:
if (!open PASSWD, "/etc/passwd") {
die "how did you get logged in?($!)";
}
while(<PASSWD>){
chomp;
#...
}
write: use print or printf
print LOG "Captain's log, stardate 3.14159\n";
printf LOG "%d percent complete.\n", $done/$total *100;
or look more like c:
printf (LOG "%d percent complete.\n", $done/$total *100);
(5) how to make the default output to other filehandle other than STDOUT ?
select PASSWD; # select can be only used to choose which filehandler to output
# do sth dirty
select STDOUT; # set it back
(6) how to direct STDERR etc. to files instead of let user use > in command line ?
just reopen them:
if (!open stderr, ">>/home/barney/.error_log") {
die "Can't open error log for append:$!"
}
now, every stderr message will be sent to .error_log


Chapter 6 Hashes
example makes every clear:
--------
#!perl
use strict;

my %stupid_hash = ("she",20,                 # we can create a hash table like this
       "me", 21);
my %silly_hash = ("she"=>20, "me"=>21);      # we can also create a hash table like this using => instead of ,
$silly_hash{"we"} = "41";                    # we can create a new "key-value" pair like this

print %silly_hash,"\n";          # result is "she20we41me21", in which we can see that the sequence
            # is based on the actual storing structure not the input sequence
            # and % is not special in " " !
my @hash_array = %silly_hash;      # we can also do assignment from hash to list(array).
print "@hash_array\n";


my %clever_hash = reverse %silly_hash;         # now values become the keys !
my @keys = keys %silly_hash;             # only get the keys list
my @values = values %silly_hash;       # only get the values list
my $count = keys %silly_hash;             # here the keys are in scalar context which return the count of keys
print %clever_hash, "\n@keys\n@values\n$count\n";

# method 1 for iteration:
# the each function will return a list contains only the current pair. when there's no more pairs,
# the each will return empty list to ($key, $value) which will cause $key and $value to be undef.
# but the key points here is: the empty list in while() scalar context will return 0 to indicate
# the element is has. so the while will quit. (in condition, like C, 0 indicates false)
while((my $key, my $value) = each %silly_hash) {     # each is only used in while in actual use.
print "$key => $value\n";
}

# method 2 for iteration:
# if you want to sort what the %silly_hash returns, use sort which return a list.
# then use foreach to iterate the list.
foreach my $key (sort keys %silly_hash) {
my $value = $silly_hash{$key};
print "$key=>$value\n";
}

# use exists to test where a key exists.
if (exists $silly_hash{"she"}) {
print "she exists!\n";
}

# delete a key=>value pair
delete $silly_hash{"she"};
print %silly_hash;
---------


Chapter 7 In the World of Regular Expressions
compared with Chapter 8&9, this chapter tell us the general RE patterns.
special points: (in addition to common sense)
(1) /./ dosen't match the new line char
(2) how to match any string including null string:
/(fred)*/ matches any string including null string.(because * can match 0 fred, which means every string)
(3) /fred (and|or) barney/ matches fred and barney, fred or barney.
(4) abbr.: [0-9] => \d    [A-Za-z0-9_] => \w    [\f\t\n\r ] => \s
so we often see \w+ \s+ etc ...
(5) abbr2: [^\d] => \D    [^\w] => \W     [^\s] => \S
(6) [\000-\177]+ matches every 7 bits ASCII char string
[\dA-Fa-f]+ matches any hex numbers
(7) how to match any char including new line char:
[\d\D] which means any digit and any non digit, ie. any chars
(8) to bound sth:
bound is the "visual char" which dosen't really exist in string.
^ head
$ tail(including \n)
\b bound of a word(\w) (every word has two bounds. actually \< \> is more common in general RE)
eg.
/\bhunt/ matches hunt, hunting, not anthunt.
/\bhunt\b/ matches hunt, not any other words.
\B is the opposite of \b which means not a bound.
(9) how many times:
eg.
/(fred){5,15}/
/(fred){5,}/    # equal or more than 5 times
/\w{9}/
(10) backreferences:
NOTICE: \n refer to the n th () before it. here we add {2} after \1 to match the "theretherethere"
eg.
$_="Hello theretherethere, neighbor";
if (/(t\w{4})\1{2}/) {
print "words were $1";
}


Chapter 8 & 9 Matching & Processing with Regular Expressions
this chapter tell us the especial perl style expression to use RE to process text.
these symbols are only for use in perl, like /i to ignore case.
1. m//
you can use m{} m<> ... but we often use m//. actually, // is the abbr of m//.
the m// return true of false, so we can use it directly in condition test.
NOTICE: if we choose // to enclose the RE, we must use \ to escape / in RE if we wanna match /.
(1) basic usage:
$_="Hello kitty!";
if (/kitty/) {
print "found!\n";
}
(2) useful flags:
/i: ignore case
if (/Kitty/i) {
print "found!\n";
}
/s: to let . to include \n
if (/Barney.*Fred/s) {
print "found!\n"
}
/x: to let you use space and comment
you may wanna know this topic if you wanna you RE more readable.
(3) "matching variable":
() in perl has special usage except grouping REs. we can use $1 ~ $n to refer to them after matching completes, which is very powerful.
NOTICE: VERY IMPORTANT!!! use it only when you know that the matching will succeed, otherwise the "matching variables" will remain the value as that of last time successful matching.
eg.
$_="Hello there, neighbor";
if (/(\S+) (\S+), (\S+)/) {
print "words were $1 $2 $3\n";
}
(4) slow "matching variable":
these 3 vars cause other perl RE processing slow. but if convenience is what you want,use them.
int the following case, $& is the matching part, $` is anything before that, $' is anything after that. so if you put these 3 vars together, you get the whole string.
eg.
if ("Hello there, neighbor" =~ /\S(\w+),/) {
print "That was ($`)($&)($')";
}
(5) the "binding operator" =~ can help us to use self-defined var instead of $_:
NOTICE: =~ return true of false which can be used in conditon testing.
eg.
my $str = "I dream of betty rubble.";
if ($str =~ /\brub/) {
print "Aye, there's the rub.\n";
}

2. s/A/B/
return a bool value. true for successfully replace. false for failure.
NOTICE: A is a Regular Pattern, and B is a normal string(so don't need escape char like \ in B)
(1) basic:
---- use $_ -----
$_ = "cow is not sheep!";
s/cow/dog/;
print "$_\n";
---- use local var ----
my $filename =~ s/cow/dog/; # the =~ here also returns true for matching, false for no matching
print "$filename\n"
(2) common replace and insertion:
$_="green scaly dinosaur";
s/(\w+) (\w+)/$2,$1/; # replace eg. result "scaly, green dinosaur"
s/^/huge, /;           # insert at the beginning. result "huge, scaly, green dinosaur"
s/$/ child/;           # insert at the end. result "huge, scaly, green dinosaur child"
s/\w+$/($`!)$&/;       # example of using $` and $& (possibly $' to do insertion)
s/\s+/ /g;             # use g to do global replacement. here we shrink spaces.
(3) case swith:
$_="I saw Barney with Fred.";
s/(fred|barney)/\U$1\E/gi; # result "I saw BARNEY with FRED.";
# here we use \U to make $1 in upper case. use \E to indicate the end of conversion.
we can also use \L to make them in lower case. use \u to make only the first char in upper case and \l to make the first char in lower case.
(4) use bake file:
$^I=".bak"; # if we set $^I, s/// will do real change, and bake the old file as *.bak
while(<>) {
s/^Author:.*/Author: Randal/;
s/^Phone:.*\n//;
s/^Date:.*/Date: $date/;
print;
}

3. split and join
my $x="4,6,8,10,12";
my @values = split /:/, $x; # the string in // can be regular patterns. now we get @values as list (4,6,8,10,12);
my $z = join "-", @values; # now we get $z as a scalor "4-6-8-10-12"

4. useful m// in list context:
we often use m// in list context to return the matching strings list!! (or we can say, to extract what we want out of the target string. it's simpler than $1,$2,...):
eg.
my($first, $second, $third) = /(\S+) (\S+), (\S+)/; # now we get the 3 matching strings in these 3 my vars
my @words = /[a-z]+/ig; # now we get all matching in @words. (notice: we use g here)
my %last_name = /(\w+)\s+(\w+)/g; # we use hash to store every pair of matching.

5. don't be too greedy:
use ? after + * {3,8} ? to try to be not greedy (ie. don't try to match the maximum string)
eg. we want to remove all the paired <BOLD></BOLD>, but keep what between them:
   I thought you said Fred and <BOLD>Velma</BOLD>,not <BOLD>Wilma</BOLD>
if we use s/<BOLD>(.*)</BOLD>/$1/g, the result is not what expected.
so we use s/<BOLD>(.*?)</BOLD>/$1/g, the result is what we want.

6. command line:
(1) behave like sed:
ls | perl -e 'while(<>){s/try/cow/;print;}'
ls | perl -p -e 's/try/cow;' # we use -p to replace the while(<>), which make it more like sed.
(2) behave like sed -n:
ls | perl -n -e 'print if s/try/cow;'

7. use () only for grouping, not var --- use ?:
/(?:bronto)?saurus (steak|burger)/
# here we add ?: before bronto, because the bronoto here is just for grouping sths togther(here we only use bronoto) to use ?. we don't want (bronto) to be $1.


Chapter 10 More Control Structure
don't need to know. recognizing them when meeting them is enough.


Chapter 11 Perl Modules
1. basic usage:
just type "using modules_name;", then you can use the function or objects names imported.
(1) use File::Basename;        # import all names from File::Basename. eg. you can use "dirname" function now.
(2) use File::Basename qw/ /; # don't import functions names. you can only use these functions using full name, eg "File::Basename::dirname". this allow you to use your own function with the same name.

2. modules introduced in this Chapter
(1) File::Basename
extract parts from a path name, the frequently used functions are dirname and basename
eg.
use File::Basename;
print "Please enter a filename:";
chomp(my $name = <STDIN>);
my $dirname = dirname $name;
my $basename = basename $name;
(2) File::Spec
this module is frequently used to deal with file system related differences. for example: we don't need to care about using \ or / to seperate path parts. so if you need to write plateform-independent code, use File::Spec
eg.
use File::Spec;
...
my $new_name = File::Spec->catfile($dirname, $basename);
rename($old_name, $new_name)
or warn "Can't rename '$old_name' to '$new_name': $!";
(3) DBI
the DBI module is used to deal with DB operations. the interface is uniform.


Chapter 12 File Tests
this chapter introduce some useful functions to abtain file info
1. file tests:
these test flags return bool(true/false) or file info(eg. file size)
eg. return type is bool
if -r $filename {
...
}

eg. return type is size
my $size = -s "hello.pl";
print $size;

eg. multiple flags
if (-r $file and -w $file) {
...
}
(refer to P180 for all test flags)

2. stat and lstat:
we use them to abtain inode info about the file( lstat for link file)
eg.
my($dev, $ino, $mode, $nlink, $uid, $gid, $rdev,
   $size, $atime, $mtime, $ctime, $blksize, $blocks)
= stat($filename);

3. time
we use time to get current timestamp, use localtime to convert timestamp to human readable localtime, and use gmtime to convert timestamp to human readable Universal Time(Greenwich Mean Time).
my $timestamp = time;
my $date = localtime $timestamp; # scalar context: Fri Jul 24 15:43:40 2009
my ($sec, $min, $hour, $day, $mon, $year, $wday, $yday, $isdst)
= localtime $timestamp;         # list context
(notice: if using localtime and gmtime without params, they use the current timestamp by default.)

4. Bitwise Operators:
&, |, ^, <<, >>, ~   they are the same as C.

Chapter 13 Directory Operations
this Chapter just tell us: perl supplies many Unix API functions(most of them is with the same name!!)
so we don't need to check them one by one. If we need an operation, just use the Unix API/command
name to look up in the perldoc.
eg.
1. chdir "/etc" or die "cannot chdir to /etc: $!";
2. shell globbing:
foreach $arg (@ARGV) {
print "one arg is $arg\n";
}
the result of running "./perl_script *.pm " in shell line:
one arg is barney.pm
one arg is dino.pm
one arg is fred.pm
one arg is wilma.pm
3. perl globbing:
use "glob" operator:
eg.
# use space to seperate patterns. here we seperate .*(.files) and * (all other files)
my @all_files_including_dot = glob ".* *"; # without dir, .* and * refer to files in current path.
my @all_files_including_dot = <.* *>;       # <> is another syntax to do perl globbing
4. rename
foreach my $file (glob "*.old") {
my $newfile = $file;
$newfile =~ s/\.old$/.new/;
if (-e $newfile) {
   warn "cannot rename $file to $newfile: $newfile exist\n";
}elsif (rename $file, $newfile) {
   #success, do nothing
}else {
   warn "rename $file to $newfile failed: $!\n";
}
}
5. $$ is the PID
my $temp_dir = "/tmp/scratch_$$";
6. other functions:
mkdir "fred", 0755 or warn "cannot make fred dir: $!"
opendir, readdir, closedir
File::Find (like unix find command) --- very good!!! if you want to do recursive dir work.
unlink, rmdir, rmtree (eg. unlink glob "*.o";)
link, symlink
chmod 0755, "fred"
chown $user,$group,glob "*.o"
utime ( it's used to change timestamp of file, access, modification time)

Chapter 14 Strings and Sorting
perl supplies us with some string manipulating functions to ease the string operation instead of Regular Expression.
1. Strings manipulation:
my $where1 = index($stuff, "wor");
my $where2 = index($stuff, "wor", $where1+1);
my $last_slash = rindex("/etc/passwd", "/");    # value is 4
my $part = substr($string, $init_position, $length);
my $out = substr("string", -3, 2);    # value is "in"
substr("$string", 0, 5) = "Goodbye"   # cool! the substr can be replaced like this.
substr($string, -20) =~ s/fred/barney/g;   # use substr to restrict the RE to work in the last 20 chars
my $date_tag = sprintf "%4d/%02d/%02d %2d:%02d:%02d", $yr, $mo, $da, $h, $m, $s;
my $money = sprintf "%.2f", 2.49997;

good example:
# this line uses loop and regular expression to add , between every 3 digits, cool!!
1 while $number =~ s/^(-?\d+)(\d\d\d)/$1,$2/;

2. Sorting:
before we simply use "sort" function, here we talk about the advance use of "sort".
usage:
sort fun @list
here fun is the function you define yourself which takes the same effect as "function object" in C++ STL algorithm method.
this book give 2 example to illustrate the use of advanced sort. They are "sorting a hash by value" (we can just sort keys in normal use), and "sorting by multiple keys"

Chapter 15 Smart Matching and given-when
1. Smart Matching:
It's too powerful! because if you use ~~, the perl will decide how to compare the left and the right operands.
In the condition of comparing each items in hash or list to a pattern, etc. it will save your effert by typing just one line!!!!
look for the table 15-1 in P224 to see how to use ~~
eg.
(1) array comparasion:
use 5.010;
say "The arrays have the same elements!" if @names1 ~~ @names2; # traditionally we have to use a loop to compare.
(2) finding hash key matching RE:
use 5.010;
say "I found a key matching 'Fred'" if %names ~~ /Fred/;   # traditionally we have to use a loop to compare.

2. given-when -- the C switch equivalent:
it's more powerful than switch, because you can do any comparison in the when block.
NOTICE: break is implicitly added. so if you want to "fall down", add "continue" manually.
eg.
use 5.010;
given( $ARGV[0] ) {
when( /fred/i )    { say 'Name has fred in it'; continue;}    # RE
when( 'Fred' )    { say 'Name is Fred'}       # string
when( ! 'Fred' )    { say 'Name is not Fred'}         # use !
when( $_ ~~ /^Fred/ ) { say 'Name is Fred'}                      # $_ is explicitly used
when( $_ > 10 )       { say 'Number is less than 10'}          # > is used
when( sub($_) )       { say 'Number is cool!'}        # we can use sub here
when( 1 == 1 )        { say 'I don't see a Fred'}        # we can use anything here
default            { say "I don't see a Fred"}
}

3. foreach-when:
this structure is used when there are many items to be processed by given-when.
eg.
use 5.010;
foreach ( @names ) { # don't use a named variable!
when( /fred/i ) { say 'Name has fred in it'; continue }
when( /^Fred/ ) { say 'Name starts with Fred'; continue }
when( 'Fred' ) { say 'Name is Fred'; }
default    { say "I don't see a Fred" }
}


Chapter 16 Process Management
1. system
it create a child process and then wait for its ending.(if we add & after command, the father won't wait)
the "system" function in perl has two version:
(1) the single argument version:
system $command_line;   # shell is automatically called to process $command_line.
eg.
! system "rm -rf files_to_delete" or die "something went wrong";
(2) the multiple argument version:
system "/bin/sh", "-c", $command_line;   # the command "/bin/sh" is called by system with arguments.
(this version doesn't call shell automatically, it just call the first argument which is a command)

2. exec
use the command to replace the current process.
eg.
exec "date";
die "date couldn't run: $!";

3. environment variables:
actually, when we envoke perl from shell, the PATH and other env vars are inherited by perl.
the vars are stored in %ENV hash.
we can change it before we launch new process to affect the child.
eg.
$ENV{'PATH'} = "/home/rootbeer/bin:$ENV{'PATH'}";
delete $ENV{'IFS'};
my $make_result = system "make";

4. using Backquotes:
NOTICE: `` in perl will return scalar or list according to the enviroment!!!
foreach (`who`) {
my($user, $tty, $date) = /(\S+)\s+(\S+)\s+(.*)/;
$ttys{$user} .= "$tty at $date\n";
}

5. the popen equivalent:
it's very useful to do piping between perl and system command!!!!
just use command as the file name, adding | after or before it.
then we get two running process with pipe relationship.
eg.
open DATE, "date|" or die "cannot pipe from date: $!";
open MAIL, "|mail merlyn" or die "cannot pipe to mail: $!";

remember to close it after reading or writing.

6. dirty things:
if you want to use raw fork and signal, check this section


Chapter 17. Some Advanced Perl Techniques
1. trapping errors with eval
the "eval" is used to trap(or register) fatal errors.
the difference is:
if you use eval, the program will continue to run when fatal errors happens.
I found it no use for me.

2. grep items from a list:
syntax:
the first param is a {} which contain a bool expression which returns true or false.
the second param is a list.
if {} return true, the item will be included.
eg.
my @odd_numbers = grep { $_ % 2 } 1..1000;          # get odd numbers from list
my @matching_lines = grep { /\bfred\b/i } <FILE>; # get lines containing fred from file

3. transform items from a list to another list:
we use map to do change to every item and store them in a new list.
the syntax is much the same as the grep.
eg. here the function &big_money is used to change a item
my @data = (4.75, 1.5, 2, 1234, 6.9456, 12345678.9, 29.95);
my @formatted_data = map { &big_money($_) } @data;

4. slices: -- powerful sub list !!!
the 3 kinds of slices below are all list.
(1) split slices:
before we use split to split a line into several fields storing in a list.
but actually we just wanna one or some fields of the string, we can simply add [ ] after the split:
eg.
my($card_num, $count) = (split /:/)[1, 5]; # here we get the 1st and the 5th item
(2) array slices:
we just wanna to refer to some fields of a array:
eg.
my @numbers = ( @names )[9, 0, 2, 1, 0];   # we can omit the () here: @names[9, 0, 2, 1, 0];
@names[2, 3] = ("cow", "sheep");
(3) hash slices:
eg.
my @three_scores = @score{ qw/ barney fred dino/ };
NOTICE: hash slice is a list! so we use @ here to indicate we have a list

Appendix B. Beyond the LIama
this part tells us what else can perl do! very exciting.
1. Some Important Modules
CGI Cwd Fatal File::Basename File::Copy File::Spec Image::Size Net::SMTP POSIX Sys::Hostname Text::Wrap Time::Local DBI Getopt::Long Getopt::Std
2. the rest:
so many field!



类别:知识体系 | 添加到搜藏 | 浏览() | 评论 (0)
 
最近读者:
 
网友评论:
发表评论:
姓 名:
网址或邮箱: (选填)
内 容:
验证码: 请点击后输入四位验证码,字母不区分大小写
      

     

©2009 Baidu