perl基本語法筆記

數據類型

perl數據類型有:標量,數組和哈希三種,具體看下錶。

數據類型 說明 示例
標量 perl內部保存的數據都是以雙精度浮點數形式保存的 $myfirst=123;  #數字123 $mysecond="123"; #字符串123
數組 @a
哈希 鍵值對 %a

注意:@符號表示獲取的是整個列表,$符號表示獲取單個元素.%表示整個哈希,花括號代表程序檢索的是哈希成員

標量操作

  • chomp操作符: 用途是取出字符串末尾的換行符(即 \n ),函數輸出移除的字符個數(爲1)。需要注意的是當字符串末尾有來兩個以上的換行符時,chomp()只刪除一個換行符。
  • < STDIN > : 表示行輸入操作符。
  • undef :是一種特殊的標量類型。在變量首次賦值前,初始值定義爲undef類型。當在數字類型上下文時,undef表現像零;當在字符串上下文時,表現像空字符串。
  • defined函數:判斷某個字符串是空字符串類型還是undef類型。

數組操作

列表是標量的有序集合,而數組是存儲列表的變量.

  • 列表賦值:
@rocks = qw/ bedrock slate lava /;
@tiny = ( );# the empty list
@giant = 1..1e5;# a list with 100,000 elements
@stuff = (@giant, undef, @giant);# a list with 200,001 elements
$dino = "granite";
@quarry = (@rocks, "crushed rock", @tiny, $dino);

($fred, $barney) = ($barney, $fred); # swap those values
  • 訪問數組元素:以下標索引來得到數組元素
  • pop:取出數組最後一個元素,並作爲返回值返回
#創建數組
@array = 5..9;
# $fred gets 9, @array now has (5, 6, 7, 8)
$fred= pop(@array);
# $barney gets 8, @array now has (5, 6, 7)
$barney = pop @array;
# @array now has (5, 6). (The 7 is discarded.)
pop @array;
  • push: 添加一個元素(或者一串元素)到數組尾端
# @array now has (5, 6, 0)
push(@array, 0);
# @array now has (5, 6, 0, 8)
push @array, 8;
# @array now has those 10 new elements
push @array, 1..10;
# @array now has those five new elements (19 total)
@others = qw/ 9 0 2 1 0 /;
push @array, @others;
  • shift: 取出數組第一個元素,並作爲返回值返回
  • unshift: 添加一個元素(或者一串元素)到數組開頭
@array = qw# dino fred barney #;
$m = shift(@array);# $m gets "dino", @array now has ("fred", "barney")
$n = shift @array;# $n gets "fred", @array now has ("barney")
shift @array;# @array is now empty 
$o = shift @array;# $o gets undef, @array is still empty
unshift(@array, 5);# @array now has the one-element list (5)
unshift @array, 4;# @array now has (4, 5)
@others = 1..3;
unshift @array, @others; # @array now has (1, 2, 3, 4, 5)
  • splice操作符: 能夠在數組中間添加或者移除某些元素。語法格式如下:

// @ARRAY:要替換的數組。
// OFFSET:起始位置。
//LENGTH:替換的元素個數。
// LIST:替換元素列表。
splice @ARRAY, OFFSET [ , LENGTH [ , LIST ] ]

@array = qw( pebbles dino fred barney betty );
# remove dino, fred
# @removed is qw(dino fred)
# @array is qw(pebbles wilma barney betty)
@removed = splice @array, 1, 2, qw(wilma); 
  • reverse: 讀取列表的值,並按相反的次序返回列表
@fred = 6..10;
@barney = reverse(@fred);# gets 10, 9, 8, 7, 6
@wilma = reverse 6..10;# gets the same thing, without the other array
@fred = reverse @fred;# puts the result back into the original array

reverse @fred;# WRONG - doesn't change @fred
  • sort: 讀取列表(或數組)的值,按照內部字符編碼順序(Unicode編碼順序)排序.所以數字的排序結果跟我們想象的並不一樣.
@rocks = qw/ bedrock slate rubble granite /;
@sorted = sort(@rocks);# gets bedrock, granite, rubble, slate
@back = reverse sort @rocks; # these go from slate to bedrock
@rocks = sort @rocks;# puts sorted result back into @rocks
@numbers = sort 97..102;# gets 100, 101, 102, 97, 98, 99


sort @rocks;# WRONG, doesn't modify @rocks
  • each: 這是v5.12之後版本支持的命令. 在數組中每次調用each,會返回下一元素的索引和值.
require v5.12;
@rocks = qw/ bedrock slate rubble granite /;
while( ( $index, $value ) = each @rocks ) {
	print "$index: $value\n";
}

哈希

#訪問哈希裏的元素
$hash{$some_key}

#哈希賦值
$family_name{'fred'} = 'flintstone';
#哈希賦值
foreach my $person (qw< barney fred >) {
print "I've heard of $person $family_name{$person}.\n";
}

#用%前綴表示整個哈希元素
%some_hash = ('foo', 35, 'bar', 12.4, 2.5, 'hello',
'wilma', 1.72e30, 'betty', "bye\n");
#在列表上下文中,哈希的值是簡單的鍵值隊列表
@any_array = %some_hash;

#哈希賦值
my %new_hash = %old_hash;
my %inverse_hash = reverse %any_hash;
#利用胖箭頭進行賦值
my %last_name = ( # a hash may be a lexical variable
'fred'=>'flintstone',
'dino'=>undef,
'barney' =>'rubble',
'betty' =>'rubble',
);

哈希相關函數

#keys函數和values函數
my %hash = ('a' => 1, 'b' => 2, 'c' => 3);
my @k = keys %hash;#返回哈希建列表
my @v = values %hash;#返回哈希值列表

#each函數
while ( ($key, $value) = each %hash ) {
print "$key => $value\n";
}

#exists()函數檢查某個健是否在哈希裏
if (exists $books{"dino"}) {
print "Hey, there's a library card for dino!\n";
}

#delete指定刪除某個鍵和對應的值
my $person = "betty";
delete $books{$person};# Revoke the library card for $person

foreach $person (sort keys %books) {# each patron, in order
if ($books{$person}) {
print "$person has $books{$person} items\n";# fred has 3 items
}
}


上下文

在perl中上下文意義在於:同一個表達式在不同的地方會有不同的含義.此時起絕定性因素是操作符,表達式輸出結果是數字,字符串還是列表看操作符的性質.

@people = qw( fred barney betty );
@sorted = sort @people; # list context: barney, betty, fred
$number = 42 + @people; # scalar context: 42 + 3 gives 45

@list = @people; # a list of three people
$n = @people;# the number 3

在標量上下文中使用產生列表的表達式:

@backwards = reverse qw/ yabba dabba doo /;# gives doo, dabba, yabba
$backwards = reverse qw/ yabba dabba doo /;# gives oodabbadabbay

在列表上下文中使用產生標量的表達式:

@fred = 6 * 7; # gets the one-element list (42)
@barney = "hello" . ' ' . "world";

# OOPS! Gets the one-element list (undef)
# which is not the same as this:
@wilma = undef; 
# A correct way to empty an array
@betty = ( );

編譯命令

  1. use warnings; #啓用警告
  2. use diagnostics; #顯示更加詳細的警告信息
  3. use strict; #告訴編譯器代碼需要更加嚴謹,遵循優良編程風格
  4. 使用binmode以二進制方式讀寫文件句柄 ,例如binmode STDOUT, ':encoding(UTF-8)';標準輸出中不轉換換行符,且編碼格式爲utf-8.
  5. use autodie; 自動檢測致命錯誤

特殊變量

[ 文件句柄 ]

$| 如果非零, 則在對當前選定的文件執行寫或打印操作後強制清除緩衝區
$% 當前選中文件句柄的當前頁碼
$= 當前選中文件句柄的當前頁面長度
$- 當前選中文件句柄的頁面剩餘長度
$~ 當前選中文件句柄的報表格式名稱
$^ 當前選中文件句柄的當前頁眉格式名

[ 全局變量 ]

$_ 默認的輸入和模式搜索空間
$@ 上一個 eval、do 或 require 函數產生的錯誤消息
$/ 輸入記錄的分隔符, 默認爲換行符(類似於 awk 中的 RS)
$\ 打印函數的輸入記錄分隔符。 除非設置了 $="\n" 否則不會打印換行符
$# 使用打印函數打印的數字輸出格式(類似於 awk 中的 OMFT)
$? 上一個關閉的管道、反引號中的命令以及系統函數的返回狀態
$! 根據上下文內容,返回錯誤號或者錯誤串
$$ 運行本腳本的 Perl 程序進程 ID
$* 默認值爲 0 。 如果爲 1 的話, 表示在字符串中進行多行匹配; 0 表示只在單行中匹配
$, 打印函數的輸出字段分隔符。 一般在以逗號隔開的字符串中不打印其定界符, 除非設置了 $,=" "
$" 與 $, 類似, 但它是在雙引號中提供打印數組的, 默認值爲空格
$0 Perl 腳本名
$[ 指向數組或子串的第一個字符的索引, 默認值爲 0
$] 當使用 Perl - v 命令獲得版本信息時打印出字符串的第一部分
$; 多維數組的下標分隔符。 默認爲 \034 (類似於 awk 的 SUBSEP)
$. 讀取上一個文件句柄的當前輸入行號; 必須在關閉前一個文件句柄後才能對下一個文件句柄重置行號
$< 進程的實際 uid
$> 進程的有效 uid
$( 進程的實際 gid
$) 進程的有效 gid
$: 字符集, 將其後的字符串斷開, 並以某種格式填入連續的行(從 ^ 處開始)。 默認是以空白字符、換行符或冒號上隔開的 \n-

_ 下劃線, 負責在聲明文件時測試文件的特殊標識符
ARGV 用於行參數循環的特殊文件句柄數組
$ARGV 從 讀取時, 含有當前文件名的變量
@ARGV 含有命令行參數的數組
DATA 一個特殊文件句柄變量, 負責引用 END 標誌後面的內容
@F 在使用 -a 開關時, 自動拆分輸入行所得到的數組
@INC 一個含有文件名路徑的數組, require 和 do 函數從中搜索將要導入的文件名路徑
%INC 一個含有文件名路徑的關聯數組, require 和 do 函數將從中搜索將要導入的文件名路徑。 其中鍵是文件名, 值是文件路徑位置
%ENV 含有當前環境變量的關聯數組
@EXPORT 導出時的默認符號
@EXPORT_OK 根據用戶請求而導出的符號
%EXPORT_TAGS 用於 Exporter.pm 中, 負責對符號集合統一命名
%SIG 用於設置信號處理例程的關聯數組
STDERR 用於標準出錯內容的特殊文件句柄
STDIN 用於標準輸入的特殊文件句柄
STDOUT 用於標準輸出內容的特殊文件句柄
$-[0] 和 $+[0] 代表當前匹配的正則表達式在被匹配的字符串中的起始和終止的位置

[ 塊內局部變量 ]

$1…$9 含有與對應的一組括號的子記憶模式。(等效於\1…\9)
$& 上一次與模式相匹配的字符串(等效於 sed 編輯器)
$` 上一次與模式相匹配的項的前導字符串
$’ 上一次與模式相匹配的項之後的字符串
$+ 與搜索模式相匹配的最後一個模式
@_ 傳給子程序的參數列表

子程序

  • 典型的子程序定義如下所示:
sub marine {
	$n += 1; # Global variable $n
	print "Hello, sailor number $n!\n";
}
  • 調用子程序:
&marine;#says Hello,sailor number 1!
&marine;#says Hello,sailor number 2!
&marine;#says Hello,sailor number 3!
&marine;#says Hello,sailor number 4!
  • 所有子程序都有返回值,但返回值並不一定有用.子程序最後執行的表達式結果都被自動當作子程序的返回值
  • 子程序參數保存在參數列表保存在特殊數組變量 @_ 中,則第一個參數存儲在 $[0],第二個參數存儲在 $[1],以此類推…
  • 私有變量用my關鍵字,my不會改變變量上下文
my($num) = @_;# list context, same as ($num) = @_;
my $num = @_;# scalar context, same as $num = @_;
  • 變長參數列表,例子如下:
$maximum = &max(3, 5, 10, 4, 6);
sub max {
	my($max_so_far) = shift @_; # the first one is the 	largest yet seen
	foreach (@_) {# look at the remaining arguments
	if ($_ > $max_so_far) { # could this one be bigger yet?
		$max_so_far = $_;
}
}
	$max_so_far;
}
  • 持久性私有變量,用state關鍵字定義

格式化輸入輸出

  • 幾種輸入操作:

    • < STDIN >: 從標準輸入(鍵盤)讀取字符串
    • <>: 從用戶指定地址讀取內容,當碰到-參數時,表示從標準輸入讀取
    • <<>>: (v5.22新增的)實際操作與<>一樣.區別在於<<>>支持的程序參數包含特殊字符,而不會產生歧義, 例如|。
  • say與print區別在於say自動在輸出字符串末尾加換行符

  • printf格式化輸出

printf "%g %g %g\n", 5/2, 51/17, 51 ** 17;# 2.5 3 1.0683e+29

文件操作

perl提供了6種特殊的文件句柄:STDIN , STDOUT , STDERR , DATA , ARGV 和ARGVOUT

打開文件

open CONFIG, 'dino';
open CONFIG, '<dino';
open BEDROCK, '>fred';
open LOG, '>>logfile';

下表列出了不同的訪問模式:

模式 描述
< 或 r 只讀方式打開,將文件指針指向文件頭。
> 或 w 寫入方式打開,將文件指針指向文件頭並將文件大小截爲零。如果文件不存在則嘗試創建之。
>> 或 a 寫入方式打開,將文件指針指向文件末尾。如果文件不存在則嘗試創建之。
+< 或 r+ 讀寫方式打開,將文件指針指向文件頭。
+> 或 w+ 讀寫方式打開,將文件指針指向文件頭並將文件大小截爲零。如果文件不存在則嘗試創建之。
+>> 或 a+ 讀寫方式打開,將文件指針指向文件末尾。如果文件不存在則嘗試創建之。

關閉文件

close filehandler

改變默認的文件輸出句柄

使用select更改默認文件輸出句柄

select LOG;
$| = 1; # don't keep LOG entries sitting in the buffer
select STDOUT;
# ... time passes, babies learn to walk, tectonic plates shift, and then...
print LOG "This gets written to the LOG at once!\n";

文件測試

文件測試參數及其意義如下表

File test Meaning
-r File or directory is readable by this (effective) user or group
-w File or directory is writable by this (effective) user or group
-x File or directory is executable by this (effective) user or group
-o File or directory is owned by this (effective) user
-R File or directory is readable by this real user or group
-W File or directory is writable by this real user or group
-X File or directory is executable by this real user or group
-O File or directory is owned by this real user
-e File or directory name exists
-z File exists and has zero size (always false for directories)
-s File or directory exists and has nonzero size (the value is the size in bytes)
-f Entry is a plain file
-d Entry is a directory
-l Entry is a symbolic link
-S Entry is a socket
-p Entry is a named pipe (a “fifo”)
-b Entry is a block-special file (like a mountable disk)
-c Entry is a character-special file (like an I/O device)
-u File or directory is setuid
-g File or directory is setgid
-k File or directory has the sticky bit set
-t The filehandle is a TTY (as reported by the isatty() system function; filenames can’t be tested by this test)
-T File looks like a “text” file
-B File looks like a “binary” file
-M Modification age (measured in days)
-A Access age (measured in days)
-C Inode-modification age (measured in days)

代碼:

if (-r $filename and -w $filename) {
... }
  • 文件測試操作符沒寫文件名和文件句柄,則默認文件名保存在$_裏
foreach (@lots_of_filenames) {
print "$_ is readable\n" if -r;
}
  • 虛擬文件句柄 _ , 告訴perl用上次查詢過的文件信息作當前測試
if (-r $filename) {
print "The file is readable!\n";
}
lookup( $other_filename );
if (-w _) {
print "The file is writable!\n";
}
sub lookup {
return -w $_[0];
}
  • stat和lstat函數
    普通文件信息用stat函數,符號連接文件用lstat函數
my($dev, $ino, $mode, $nlink, $uid, $gid, $rdev,
$size, $atime, $mtime, $ctime, $blksize, $blocks)
= stat($filename);
  • localtime獲取時間戳
my $date = localtime $timestamp;

my($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst)
= localtime $timestamp;

my $now = gmtime;
# Get the current universal timestamp as a string

目錄操作

獲取當前工作目錄

use v5.10;
use Cwd;
say "The current working directory is ", getcwd();

更改工作目錄

chdir '/etc' or die "cannot chdir to /etc: $!";

刪除文件

unlink qw(slate bedrock lava);
unlink glob '*.o';

文件重命名

rename 'old', 'new';

鏈接與文件

link 'chicken', 'egg'
or warn "can't link chicken to egg: $!";

創建和移動目錄

mkdir 'fred', 0755 or warn "Cannot make fred directory: $!";

改變權限

chmod 0755, 'fred', 'barney';

改變所屬關係

my $user = 1004;
my $group = 100;
chown $user, $group, glob '*.o';

改變時間戳

my $now = time;
my $ago = $now - 24 * 60 * 60;# seconds per day
utime $now, $ago, glob '*';# set access to now, mod to a day ago

字符串操作

  • . 子字符串連接
    'hello'.'world'
    #等同於‘helloworld’

  • x 重複字符串指定次數 "fred" x 3
    # is "fredfredfred"

  • index用index函數查找子字符串

 my $where = index($big, $small);
  • substr:
    截取指定子字符串
my $part = substr($string, $initial_position, $length);
  • sprintf格式化輸出
my $date_tag = sprintf
"%4d/%02d/%02d %2d:%02d:%02d",
$yr, $mo, $da, $h, $m, $s;
#2038/01/19 3:00:08
  • 高級排序
    編寫排序子程序實現排序功能
    sub by_number {
# a sort subroutine, expect $a and $b
if ($a < $b) { -1 } elsif ($a > $b) { 1 } else { 0 }
}
#實現數字從小到大排序
my @result = sort by_number @some_numbers;

簡化代碼有:

sub by_number { $a <=> $b }#比較數字
sub by_code_point { $a cmp $b }#比較字符串

Perl 進程管理

Perl 中你可以以不同的方法來創建進程。

你可以使用特殊變量 $$ 或 $PROCESS_ID 來獲取進程 ID。

%ENV 哈希存放了父進程,也就是shell中的環境變量,在Perl中可以修改這些變量。

exit() 通常用於退出子進程,主進程在子進程全部退出後再退出。

所有打開的句柄會在子程序中被 dup() 函數複製, 所有關閉進程所有句柄不會影響其他進程 。

反引號運算符

使用反引號運算符可以很容易的執行 Unix 命令。你可以在反引號中插入一些簡單的命令。命令執行後將返回結果:

#!/usr/bin/perl

@files = `ls -l`;

foreach $file (@files){
   print $file;
}

1;

執行以上程序,輸出結果如下:

drwxr-xr-x 3 root root 4096 Sep 14 06:46 9-14 drwxr-xr-x 4 root root
4096 Sep 13 07:54 android
-rw-r–r-- 1 root root 574 Sep 17 15:16 index.htm drwxr-xr-x 3 544 401 4096 Jul 6 16:49 MIME-Lite-3.01
-rw-r–r-- 1 root root 71 Sep 17 15:16 test.pl ……

system() 函數

你也可以使用 system() 函數執行 Unix 命令, 執行該命令將直接輸出結果。默認情況下會送到目前Perl的STDOUT指向的地方,一般是屏幕。你也可以使用重定向運算符 > 輸出到指定文件:

執行以上程序,輸出結果如下:

drwxr-xr-x 3 root root 4096 Sep 14 06:46 9-14 drwxr-xr-x 4 root root
4096 Sep 13 07:54 android
-rw-r–r-- 1 root root 574 Sep 17 15:16 index.htm drwxr-xr-x 3 544 401 4096 Jul 6 16:49 MIME-Lite-3.01
-rw-r–r-- 1 root root 71 Sep 17 15:16 test.pl ……

你需要注意命令包含環境變量如 $PATH 或 $HOME 的輸出結果,如下所示:

#!/usr/bin/perl
 
$PATH = "我是 Perl 的變量";
 
system('echo $PATH');  # $PATH 作爲 shell 環境變量
system("echo $PATH");  # $PATH 作爲 Perl 的變量
system("echo \$PATH"); # 轉義 $
 
1;

執行以上程序,輸出結果如下:

/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin
我是 Perl的變量 /usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin

fork() 函數

Perl fork() 函數用於創建一個新進程。

在父進程中返回子進程的PID,在子進程中返回0。如果發生錯誤(比如,內存不足)返回undef,並將$!設爲對應的錯誤信息。

fork 可以和 exec 配合使用。exec 函數執行完引號中的命令後進程即結束。
實例

#!/usr/bin/perl
 
if(!defined($pid = fork())) {
   # fork 發生錯誤返回 undef
   die "無法創建子進程: $!";
}elsif ($pid == 0) {
   print "通過子進程輸出\n";
   exec("date") || die "無法輸出日期: $!";
  
} else {
   # 在父進程中
   print "通過父進程輸出\n";
   $ret = waitpid($pid, 0);
   print "完成的進程ID: $ret\n";
 
}
 
1;

執行以上程序,輸出結果如下:

通過父進程輸出
通過子進程輸出
2016年 6月19日 星期日 22時21分14秒 CST
完成的進程ID: 47117

如果進程退出時,會向父進程發送一個CHLD的信號後,就會變成僵死的進程,需要父進程使用wait和waitpid來終止。當然,也可以設置$SIG{CHLD}爲IGNORG:
實例

#!/usr/bin/perl
 
local $SIG{CHLD} = "IGNORE";
 
if(!defined($pid = fork())) {
   # fork 發生錯誤返回 undef
   die "無法創建子進程: $!";
}elsif ($pid == 0) {
   print "通過子進程輸出\n";
   exec("date") || die "無法輸出日期: $!";
  
} else {
   # 在父進程中
   print "通過父進程輸出\n";
   $ret = waitpid($pid, 0);
   print "完成的進程ID: $ret\n";
 
}
 
1;

執行以上程序,輸出結果如下:

通過父進程輸出
通過子進程輸出
2016年 6月19日 星期日 22時30分56秒 CST
完成的進程ID: -1

Kill 函數

Perl kill(‘signal’, (Process List))給一組進程發送信號。signal是發送的數字信號,9爲殺掉進程。

首先看看linux中的常用信號,見如下列表:

信號名 標註 解釋
HUP 1 A 檢測到掛起
INT 2 A 來自鍵盤的中斷
QUIT 3 A 來自鍵盤的停止
ILL 4 A 非法指令
ABRT 6 C 失敗
FPE 8 C 浮點異常
KILL 9 AF 終端信號
USR1 10 A 用戶定義的信號1
SEGV 11 C 非法內存訪問
USR2 12 A 用戶定義的信號2
PIPE 13 A 寫往沒有讀取者的管道
ALRM 14 A 來自鬧鐘的定時器信號
TERM 15 A 終端信號
CHLD 17 B 子進程終止
CONT 18 E 如果被停止則繼續
STOP 19 DF 停止進程
TSTP 20 D tty鍵入的停止命令
TTIN 21 D 對後臺進程的tty輸入
TTOU 22 D 對後臺進程的tty輸出

以下實例向進程 104 和 102 發送 SIGINT 信號:

#!/usr/bin/perl
 
kill('INT', 104, 102);
 
1;

高級技巧

切片

#列表切片操作
my $mtime = (stat $some_file)[9];
#-1表示列表最後一個元素
my($first, $last) = (sort @names)[0,1];

#列表切片
my @names = qw{ zero one two three four five six seven eight nine };
print "Bedrock @names[ 9, 0, 2, 1, 0 ]\n";

#哈希切片
#下兩行代碼是等價的
my @three_scores = ($score{"barney"}, $score{"fred"}, $score{"dino"});
my @three_scores = @score{ qw/ barney fred dino/ };

eval檢查運行時錯誤

eval作用是當其監察模塊出現錯誤,就會立即停止運行該塊,並繼續運行其餘代碼.
eval返回值是監察的語句塊最後一條表達式執行結果.

#可以檢查除0錯誤
eval { $barney = $fred / $dino };
foreach my $person (qw/ fred wilma betty barney dino pebbles /) {
eval {
open my $fh, '<', $person
or die "Can't open file '$person': $!";
my($total, $count);
while (<$fh>) {
$total += $_;
$count++;
}
my $average = $total/$count;
print "Average for file $person was $average\n";
&do_something($person, $average);
};
if ($@) {
print "An error occurred ($@), continuing\n";
}
}

用die拋出異常,用eval捕獲異常.

用grep篩選列表

#實現把1到1000中奇數保存至odd_numbers中
#工作原理:gerp會把列表裏每個元素帶到代碼塊裏進行計算,結果爲真的值將作爲gerp返回的列表裏其中一個元素
my @odd_numbers = grep { $_ % 2 } 1..1000;

用map把列表變形

#把data數組裏數據格式化爲金額形式輸出
#map工作原理是:把列表裏的元素帶到代碼塊裏執行,並把實際計算結構作爲map返回值的一部分
my @data = (4.75, 1.5, 2, 1234, 6.9456, 12345678.9, 29.95);
my @formatted_data = map { big_money($_) } @data;

總結

perl語言的設計思想有:

  • 用最少的代碼來來實現一個功能。
  • 無內建限制
  • 去除不必要的限制

這就犧牲了可讀性,編程風格就會因人而異,粗看別人寫的代碼,就會陷入迷茫,看不懂的境地。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章