Perl 学习笔记

Introduction

# 代表注释
Perl 不需要进行变量声明
大部分 Perl 语句用 ; 结尾,但只是用来分隔不同的语句,而不是断行
Perl 解释器能够一次性完成编译和运行两个动作:首先载入整个源程序,将其转换成内部使用的 bytecodes,这是一种 Perl 在内部用来表示程序语法树的数据结构,然后交给 Perl bytecode 引擎运行
Perl 中,任何需要变量的地方,都可以用赋值运算符代替,先做赋值运算,然后返回赋值后的变量
Perl 中,除非去掉括号会改变表达式的含义,否则括号也是可以省略的

Scalar Data

标量是 Perl 中最简单的数据类型,包括数字(number)和字符串(string of characters)(Perl 中字符串就是一个独立的标量,但有必要时我们还是能够访问其中的每个字符),两者在大多数情况下可以相互转换

不管是整数还是浮点数,在 Perl 内部都是用双精度浮点数保存的,所以像除法运算也是按浮点数操作的
literal(直接量)是指某个数字在 Perl 源代码中的写法,并非运算结果,也不是 I/O 操作的结果,就是直接键入程序源代码的写法
Perl 允许在整数直接量中插入下划线进行分隔,便于阅读,如 11_222_333_444
Perl 字符串能够包含任何字符,因此可以直接操作二进制数据
Perl 完全支持 Unicode,但由于历史原因不会自动原因将程序源代码当做 Unicode 编码的文本文件读入,所以如果想在源代码中使用 Unicode 书写直接量,需要加上 use utf8;(建议每次均加上该语句)

字符串直接量有两种形式:单引号内和双引号内。单引号内除了单引号和反斜线外,所有字符都代表自己,包括换行符(就是直接敲了换行),\n 并不是换行符,而是反斜线和字符n,如果要表示单引号和反斜线本身,需在前面加上反斜线表示转义;双引号内的的反斜线就更加强大,可以进行转义。此外,双引号内可以使用变量内插 e.g. "It is $test";内插时,Perl 会采用最长的合法变量名称,为避免歧义,可以像 shell 一样,用花括号将变量名括起来(不包括美元符号)
字符串连接用 .,重复用 x (就是字符x)(左边必然为字符串类型,数字也会被转换,右边是数字,先取整;不能互换,不满足交换律)
数字和字符串之间的自动转换完全取决于操作符
use warnings; 开启警告功能,use diagnostics; 能够给出更详尽的问题描述(不过会减慢启动速度)

标量变量,就是只存单个标量的变量。标量变量的名称以 $ 符号开头,区分大小写
多了一个针对字符串变量的双目赋值操作符 .=,追加字符串

print 可以输出一系列用逗号隔开的值

if 语句结构 if (condition) {statement},其中花括号作为界限是必须的
while 语句结构类似 while (condition) {statement}
Perl 中没有专门的布尔数据类型
undef 是一个特殊的标量值,既不是数字也不是字符串,出现在比如标量变量还未被赋值就直接使用或者读取文件至末尾时,但它能够根据具体的情况表现得像是数字0或者空字符串
为了区分某个字符串是 undef 还是空字符串,可以使用 defined 函数,如果是 undef,返回假,否则为真

行输入操作符 <STDIN> 能够使 Perl 从标准输入中读取一行文本(到换行符为止)。一般由 <STDIN> 返回的字符串都会在末尾带有换行符,可以用函数 chomp() 除去字符串变量末尾的换行符。该函数返回值为实际移除的字符数,因此只能作用于变量,这样可以直接改变字符串变量

Lists and Arrays

列表(list)是标量的有序集合,而数组(array)则是存储列表的变量;前者是数据,后者是变量
索引从0开始,可以为负数,$#<array_name> 是数组最后一个元素的索引值
数组或列表中的每个元素都是单独的标量变量,拥有独立的标量值,因此各元素可以是不同类型的标量
数组的名字空间和标量的名字空间是完全分开的,因此可以有相同的变量名,但实际中不要这么操作
任何求值能够得到数字的表达式均可作为下标,如果不是整数,则会自动舍去小数部分
下标超出数组范围时,对应的值为 undef
对索引值超过数组尾端的元素赋值时,数组会自动扩大,其他的值默认取 undef

列表直接量是圆括号内用逗号隔开的一串数据,e.g. (1, 2, "fred")
要产生一串数字,还可以用 .. 操作符,从左边的数字计数到右边,每次加1,产生一串数字,e.g. (1..5)
数组中的元素可以是表达式,每次用到这些直接量时会重新计算

qw(quoted word)简写,用于构建列表,当中的元素将会被当成单引号内的字符串来处理(所以没法使用 \n 或者 $fred 等),其中的空白符(空格,制表符,换行符等)都会被抛弃,身下的就是列表元素 e.g. qw( fred barney betty wilma dino ) 等价于 ("fred", "barney", "betty", "wilma", "dino")
qw 的定界符可以是任意标点符号
列表值能够赋值给变量 e.g. ($fred, $barney, $dino) = ("flintstone", "rubble", undef);,如果两边个数不等,当列表元素多时,会舍弃;当变量多时,赋为 undef
Perl 中互换两个变量的值 e.g. ($fred, $barney) = ($barney, $fred);

引用整个数组时,使用 @ 字符 e.g. @rocks = qw/ bedrock slate lava /;
也可以用该语句构建 rocks 数组 ($rocks[0], $rocks[1], $rocks[2], $rocks[3]) = qw/talc mica feldspar quartz/;
数组只能包含标量,不能包含数组,因此赋值时是将一个数组中的元素赋值给了另一个数组

数组常被当成堆栈(stack)使用(后进先出):

  • pop() 取出数组的最后一个元素并将其作为返回值返回,e.g. pop(@array)
  • push() 将若干个元素添加至数组的尾端,e.g. push(@array, 0);
  • shift()unshift() 则是分别针对数组的左边进行移除和添加
  • splice() 能对数组中间的元素进行操作,第一个参数是要操作的数组,第二个是要操作元素的起始索引,第三个参数是要操作的元素长度,即个数,第四个参数是用来替换的列表长度并不需要一致。后两个参数可选,没有的时候就是进行删除操作;如果想直接添加不进行删除,那么第三个参数设为0即可

数组的内容也可以内插到双引号字符串中,数组各元素之间会自动添加分隔符(首尾不会),有特殊变量 $" 指定,默认为空格
对于一些可能产生歧义的地方:

$email = "fred@bedrock.edu";
$email = "fred\@bedrock.edu"; # Correct
$email = 'fred@bedrock.edu'; # Another way to do that

索引表达式会被当成字符串表达式进行处理,该表达式中,变量不会被内插:

@fred = qw(hello dolly);
$y = 2;
$x = "This is $fred[1]'s place";     # "This is dolly's place"
$x = "This is $fred[$y-1]'s place";  # same thing
$y = 2*4;
$x = "This is $fred[$y-1]'s place";  # $y相当于2,所以索引结果仍为1,而不是7