在Perl中,布尔值TrueFalse用字符串来表示,因为所有Scalar类型都可以转换为字符串😑。

其中,False可以是空字符串'', 或者字符串'0'. 其余任何字符串都是True, 包括'00', '0E0'等转换为数值类型等于0的字符串。

一般函数要返回False的时候返回''undef (undef转换为空字符串'').

逻辑运算符

Perl的逻辑运算符和其他符号和字符都可以使用。

symbolic | textual
---------+--------
! | not
&& | and
|| | or
// | (defined-or)

因为程序是顺序执行的,和数学中的逻辑运算有点不一样。程序会先执行运算符左边的表达式,计算它的真假,然后根据运算符,有必要时再计算运算符右边的表达式。

# 先执行open函数打开文件,如果打开文件成功,返回`True`,
# 则不会执行后面的die函数;如果打开文件失败,才会执行后
# 面的函数。最终运算结果是die函数的返回值。
open(...) || die(...)
open(...) or die(...)

# 同上,只不过只有在unlink函数返回`True`的情况下才会执行
# 右边的函数。
unlink(...) && print(...)
unlink(...) and print(...)

# 如果$name没有被定义过则执行die函数
$name // die("the name is not defined")

# 判断$name是否被定义,没有则赋值(因为没有定义,会报错)。
$name //= "peter"

if 和 unless

和Python的if...elif...else语句没有不同,除了在Perl中使用elsif关键词,而不是elif.

if (<cond>) { ... }
elsif (<cond>) { ... }
elsif (<cond>) { ... }
elsif (<cond>) { ... }
else { ... }

unless 可以看作 if (not <cond>)的缩写。

语法糖:使用if语句控制前一个表达式的执行。

if ($friendly) { print $greeting }

print $greeting if $friendly; # same as above
练习
  • Use the function time() to get the current time (a simple integer
    number) into a variable

  • Print the content of this variable

  • Print the strings “odd” or “even” depending on the value of this
    variable. (Hint: use the modulo operator)

  • Bonus: print human readable date, whenever the number is dividable by 3, 5, or 7
    Hint: The function localtime() converts the epoch time into a readable
    representation:

print localtime(…) . "\n";   # use concatenation with dot operator

答案:

#!/usr/bin/perl
use strict;
use warnings;

my $now = time();
print $now, "\n";

if ($now % 2 == 0) {
print "even\n";
}
else {
print "odd\n";
}


if ($now % 3 == 0 or $now % 5 == 0 or $now % 7 == 0) {
print localtime($now) . "\n";
}

三元运算符

$result = $value % 2 == 0 ? "even" : "odd"

循环控制:while / until / for / last / next / continue

  • While循环
while (<cond>) {
..
next if ...; # optional, jump to ocntinue
last if ...; # optional, leave the loop
...
} continue {
...
}
  • do while循环
do {
...
} while (<cond>);
  • 使用自定义标签标注循环入口和出口

  • next默认跳出当前循环,进行下一次循环,类似Python中的continuenext接自定义标签则跳出循环到指定标签处继续执行。

  • last跳出循环,类似Python中的break

FOO: while (<cond>) {
...
while (<cond>){
...
next if ...;
next FOO if ...;
}
}
  • for循环
# expr0 example: $i = 0
# expr1 example: $i < n
# expr2 example: $i++
for (<expr0>; <expr1>; <expr2>) {
...
}

练习

Create a script, that lets the user guess a random number, giving feedback if the guess was small or big.

Hints:

  • random integer between 0 and 10: $value = int rand 10
  • a line of user input: $input = readline;

答案:

#!/usr/bin/perl
use strict;
use warnings;
use feature 'say';

my $random_number = int rand 10;
say "Take a guess!";
GUESS: while (my $input = readline) {
if ($input > $random_number) {
say "Wrong guess. Your guess is big to the target number.";
}
elsif ($input < $random_number) {
say "Wrong guess. Your guess is small to the target number.";
}
else {
last GUESS;
}
say "Try it again!";
}

say "Congratulations! You guessed right!"