2011年9月30日 星期五

perl note

#Perl Hash Howto
http://www.cs.mcgill.ca/~abatko/computers/programming/perl/howto/hash/#initialize_a_hash_reference

#Camel perl 駱馬書hash 教學
http://easun.org/perl/perl-toc/ch05.html


迭代器敘述
last
next
continue
redo

Next
Place it inside your loop and it will stop the current iteration and go on to the next one.
Continue
Executed after each loop iteration and before the conditional statement is evaluated. A good place to increment counters.
Last
Last stops the looping immediately (like break)
Redo
Redo will execute the same iteration over again.
gotoJumps to a specified label.

goto Syntax
goto LABEL      #
goto EXPR       #goto "ne"."xt";    <=>  goto next;  #維護性不高
goto &NAME    #Can't goto subroutine outside a subroutine 

next Syntax
next
next LABEL      #

flowcontrol.pl:

#!/usr/bin/perl

print "content-type: text/html \n\n";

# SET A VARIABLE
$count = 0;
while ($count <= 7) {
  
 # SET A CONDITIONAL STATEMENT TO INTERRUPT @ 4
 if ($count == 4) {
  print "Skip Four!<br />";
  next;
 }
 # PRINT THE COUNTER
 print $count."<br />";

}
 continue {
  $count++;
 };
print "Loop Finished!";

flowcontrol.pl:

0
1
2
3
Skip Four!
5
6
7
Finished Counting!
Above, we skip the fourth iteration by incrementing the variable again. In the example we also print a line, "Skip Four!" just to make things easier to follow



指標參照:
$scalar = "1...10";
@array = (1...10);
%hash = (1...10);
$scalar_ref = \$scalar;
$array_ref = \@array;
$hash_ref = \%hash;
指標取元素值,雜湊,陣列:
my @array = qw/John Paul May/;    # 一個陣列
my $array_ref = \@array;    # 取得這個陣列的參照
print @{$array_ref};     # 印出JohnPaulMary
print ${$array_ref}[1];      # 印出John
my @aray = qw/John Paul May/;
my $array_ref = \@array;
for (@{$array_ref}) {
    print "姓名:$_\n";
}


my %hash = qw/John 24 Paul 30 May 26/;
my $hash_ref = \%hash;
print ${$hash_ref}{John};    # 果然印出 24
for (keys %{$hash_ref}) {
    print ${$hash_ref}{$_}."\n";   # 印出 24, 26, 30
}
%myhash = (
  "k1" => 10,
  "k2" => 8,
  "k3" => -9,
);
#排序技巧(sort by keys ,sort by values,other sorting technical)

@sortKey = sort {$a <=> $b} keys %myhash;
print "@sortKey\n";

@sortHashValue = sort {$a <=>$b} values %myhash;
print "@sortHashValue\n";

@sortKeyTech = sort {$myhash{$a} <=> $myhash{$b}} keys %myhash;
print "@sortKeyTech\n";


#關於for 迴圈的技巧


print "---technical 1:C-like for loop---\n";
for ($count=0;$count<=10;$count++){
  print "the counter number is $count.\n";
}


print "---technical 2:range operator---\n";
for $count(1 .. 10){
  print "the counter number is $count.\n";
}


print "---technical 3:simplified range operator---\n";
for (1 .. 10){
  print "the counter number is $_."."\n";
}
print "---technical 4:push element into array with for loop---\n";
@arr=("initialization");
push (@arr, $_) for (1...10);
print "@arr";#initialization 1 2 3 4 5 6 7 8 9 10


#foreach 迴圈使用方法



@array=(1,2,3);
foreach my $element (@array)
print foreach (@array);   #印出123
不過這時候我們就用到了Perl最常用到的預設變數$_,當我們在迴圈中沒有指定任何變數時,Perl就會把取出來的值放入預設變數$_中。緊接著我們希望把迴圈取得的值列印出來,也就是執行
print $_;
這樣的式子,當然,這樣的式子在Perl出現的機率真是太少,因為大部份的時候,如果你只要列印單一的$_,Perl程式員也就會省略$_這個變數。而因為我們在迴圈中只打算執行print這個指令,所以倒裝句也就順勢產生。
#hash 的定義

%hash = (
  "k1" => "v1",
  "k2" => "v2",
  "k3" => "v3",
  "k4" => "v4",
);
#取出hash的keys存為陣列@keys
#取出hash的values存為陣列@values
#將陣列@keys中的元素取出使用
#利用while迴圈 each函數 取出%hash的pair
@keys = keys(%hash);
@values = values(%hash);
for (@keys){print "$_ => $hash{$_}\n";}


while (($key, $value) = each (%hash)) {
      # 取出雜湊中的每一對鍵值,並且分別放入$key, $value
      print "$key => $value\n";
}

#因為Perl會把副常式中最後一個運算的值當成預設的回傳值,所以你可以省略在進行運算後還必須再進行一次return的動作

my $return = &square(4);
print $return;

sub square {
    my $base = shift;
    $base**2;
}



my $return = &div(4, 2);   # 這時候有兩個參數
print $return;

sub div {
    $_[0]/$_[1];    # 只是進行除法
}

不過如果我們在叫用副常式的時候傳了三個參數,就像:

&div(4, 2, 6);

那會產生什麼結果呢?其實回傳值就跟原來的一樣,因為Perl並不會去在意參數的個數問題。f若程式有需要,應該去確認參數的個數,避免參數個數無法應付需要,以確保程式能正常而順利的進行。


#取得陣列或@_中的最大執與最小值


sub getmin{
  @sorted = sort @_;
  print "@sorted";
  $min = shift @_;
  print "\nmin : $min\n";
  return $min;
}
getmin(1,2,3,4);


sub getmax{
  @sorted = sort @_;
  print "@sorted";
  $max = shift @_;
  print "\nmax : $max\n";
  return $max;
}
getmax(1,2,3,4);


#陣列的資料 取出陣列 取出元素數量
@array = (1..10);
my @array2 = @array;  #指定陣列給@array2
my $eleNum = @array;  #取出陣列的元素數量

print "@array\n";
print "@array2\n";
print $eleNum;


my @array = (1...10);   # 利用串列賦值給陣列
my $scalar = @array + 4;   # 在純量語境中進行 $scalar=14
my @scalar_array = @array + 4;# 先以純量語境進行運算,然後以串列方式賦值給陣列

print "@array\n";
print "$scalar\n";           # 在純量語境中進行 $scalar=14
print "@scalar_array";  #@scalar_arrray=(14)


@arr=(1..10);
print $#arr; # 印出陣列arr的最大index值,其中$#arr 為9


##找出陣列元素是否存在的辦法
##exists argument MUST BE a HASH or ARRAY element or a subroutine !!
@arr -= (1..10);
print "IT EXIST!!!\n" if (exist $arr[11]);  #查看arr[11]是否存在

#找出hash值是否存在的辦法

my %hash = (
            'cd' => 2,
            'book' => 10,
            'video' => 0,
            );
my $media = 'video';
print "bingo" if ($hash{$media});


$_:預設參數
@_:預設參數陣列
$#_:預設參數的最大index值


#subroutine 的參數數量

sub stayFunc{
  $numPara = $#_+1;
  print "你輸入了$numPara個參數";
  print "這些參數分別為:\n";
  for (@_){
    print "[para]:".$_."\n";
  }
  print "\tstayFunc執行結束...\n";
}
stayFunc(1,2,"three");
##執行結果
##你輸入了3個參數這些參數分別為:
##[para]:1
##[para]:2
##[para]:three
## stayFunc執行結束...

#比較my和local之間的差別


$var1 = "global";
$var2 = "for local";
&sub1;      # 印出 local, for local
&sub2;      # 印出 global, for local

sub sub1 {
    local $var1 = "local";
    my $var2 = "my";
    &sub2;
}

sub sub2 {
    print "var1=$var1\tvar2=$var2\n";
}


#計數器在等於8時 執行redo敘述
#導致從block的開頭再執行一次程式碼 此時計數器仍為8
#故印出無窮個8
for (1..10){
   if ($_ == 8){
     print $_;
     redo;
    }
}
#印出無限個88888888....


Syntax

redo LABEL
redo

myLabel{
print "Hello";
redo myLabel;
}

#三元運算符

my ($a, $b) = (42, 22);
my $max = ($a > $b) ? $a : $b;
print "$max\n";



Syntax(Raise an Exception)

die LIST

Definition and Usage

Prints the value of LIST to STDERR and calls exit with the error value contained in $!.

Return Value

  • Nothing

Example

Following are the usage...
die "Can't cd to spool: $!\n" unless chdir '/usr/spool/news';
or
    chdir '/usr/spool/news' or die "Can't cd to spool: $!\n"
or
    open( FILEH, ">/tmp/test" ) || die( "Can't open file test $!\n" );


output() || die "沒有回傳值";

sub output {
    return 0;
}
#do 敘述的使用

do BLOCK
do SUBROUTINE(LIST)
do EXPR

open FILE,"myfile.txt" or die "Exception:$!";
print FILE "my message";


#取出陣列@arr裡面前兩個元素指定給變數
@arr  = (1..10);
($first,$secondary)=@arr;
print "$first\t$secondary"; # $first 為1#$secondary為2

 #將字串轉成字元陣列後再進行操作

@strArr = split ("",$input ); #字串轉成字元陣列
print "\@strArr = >@strArr";
print "$_\n" for(@strArr);
print $strArr[0];