基本自訂副函式

# 基本自訂副函式

# (1) 基本自訂副函式
sub hello { # 自訂函式
        print "Hello World.\n";
}
&hello; # 使用自訂函式


# (2) my and local
$name = "Joe";  # 全域變數 (Global Variable)

sub hello {
    print "In hello: $name\n";
}

sub hello2 {
    # 宣告 local 變數,在 hello2 本身及其呼叫的函式使用
    local $name = "Bill";

    print "In hello2: $name\n";
    print "Call hello from hello2: ";
    &hello;
}

sub hello3 {
    # 宣告 my 變數,只能在 hello3 本身使用
    my $name = "Mary";

    print "In hello3: $name\n";
    print "Call hello from hello3: ";
    &hello;
}

&hello;
&hello2;
&hello3;


# (3) 自訂 max 函式
sub max {
    # 讀入參數:將 @_ 內的第一個與第二個元素讀入,剩下的捨棄
    my($a, $b) = @_;

    if ($a > $b) {
        return $a;
    } else {
        return $b;
    }
}

print &max(1,2);    # 2

排序(Sorting)

# 排序(Sorting)

# (1)
@arr = (2,3,1,4);

sub sort_by_num {   # 排序副函式
    if ($a < $b) {
        return -1;  # 代表 $a 排在 $b 之前
    } elsif ($a > $b) {
        return 1;   # 代表 $a 排在 $b 之後
    }else {
        return 0;
    }
}

# 將 & 去掉使用,結果為 (1,2,3,4)
@sorted = sort sort_by_number (@arr);

@rev = reverse(@sorted);    # (4,3,2,1)

# (2)
@arr = (2,3,1,4);
sub sort_by_number2{    # 作用與 sort_by_number 相同
    return $a <=> $b;
}
@sorted = sort sort_by_number2 (@arr);
@rev = reverse(@sorted);

# (3)
@arr = (2,3,1,4);

# Inline 方式撰寫排序副函式
@sorted = sort { $a <=> $b } (@arr);

@rev = reverse(@sorted);

# (4) hash 排序
%hash = (
    Joe     =>      32,
    Mary    =>      87,
    Bill    =>      98,
    John    =>      67
);

sub by_grade{
    return $hash{$a} <=> $hash{$b};
}

@name = reverse sort by_grade keys %hash;

print $_ . "\n" for(@name);



# 練習

# 1. 假設有一成績資料檔案如下

=pod

Joe 98  87  94  67
Mary    97  86  97  76
John    78  67  81  97
Bill    56  78  67  86
Seal    69  79  68  81
God 97  98  98  99

=cut

# 總成績計算方式為:
# 四次成績中刪去最低分的成績,剩下的三次做平均,
# 請寫一個 perl script 來計算,並將輸出成績存入檔案。

# 假設成績檔為 score.txt


open INFILE,"score.txt";
open OUTFILE,">output.txt";

while(<INFILE>){

    ($name, @score) = split;

    @score = reverse sort {$a <=> $b} @score;

    pop @score;

    $sum=0;

    foreach(@score){
                $sum+=$_;
        }

    $average = $sum / ($#score+1);

    print OUTFILE "$name\t$average\n";
}

close OUTFILE;
close INFILE;

繼續閱讀:Perl 程式設計教學