Perl Basic - Scalar
这是我第一次听到Scalar这个词(nothing beats the first time😏)。Scalar的字面意思是标量,在矩阵中用来表示无方向的向量。Let’s take a wild guess here. Scalar在Perl语言中应该是单一维度的变量的意思,包括字符串(string),数字(numerical),引用(reference),通配符(glob)。
字符串
构建字符串
和Shell一样,Perl的特殊符号在双引号内会被转义,在单引号内不会(除了\')。以下面的表达式为例,\t在双引号内转义为一个tab,在单引号内输出字面的”\t”.
print "perl" # <----------.
print 'perl' # same as ---'
print "hello\tworld" # <------------------.
print 'hello\tworld' # not the same as ---'
另一种单引号的quoting格式:q<char>...<char>。
# 以下全部输出hello 'world'
print 'hello \'world\'';
print q!hello 'world'!;
print q<hello 'world'>;
另一种双引号的quoting格式:qq<char>...<char>。另外,双引号里面的特殊符号会被解析。
# 以下全部输出Hello "world"
print "Hello \"world\""
print qq!Hello "world"!
print qq<Hello "world">
特殊符号种类
sequence | output
-------------------+------------------
\t | tab character
\n | newline
\x<xdigit><xdigit> | character code "\x41" => "A"
\x{<xdigits>} | unicode character code "\x{263A}" => "☺"
\N{<name>} | unicode character name "\x{BICYCLIST}" => "🚴"
多行字符串
Perl的<<有类似于Shell的作用。
# "<<FOO"会被下一行到第二个"FOO"的多行字符串替代后输出
print <<FOO;
abc
def
ghi
FOO
字符串运算
-
拼接
# 输出Hello World print 'Hello' . ' ' . 'World'; -
复制
# 连续输出3次Hello print 'Hello' x 3; # 遵从数学运算符优先原则,先复制后拼接 print '-' x 10 . "\n" . '*' x 10; -
比较
- 字符串的比较是根据字符在ASCII码表中对应的数值来的。比如’!’小于’0’, ‘a’小于’b’, ‘a’大于’A’。可以通过’ord’函数来换算字符的ascII码,通过’chr’函数计算ascII码代表的字符。
- 如果第一位字符相同则比较后一位字符,比如,‘aa’小于’ab’, ‘a’小于’aa’,依此类推。
- Boolean comparison:
eq,ne,gt,lt,ge,le返回 true 或 false - 3-state comparison:
cmp返回 -1, 0 or 1
数字
数字42的几种表示方法
42 # decimal
4_2 # _ for grouping
4200E-2 # scientific notation
4.2E1 # floating point
0x2a # hex (base 16)
052 # octal (base 8)
0b101010 # binary (base 2)
'42' # string
运算符
运行符和其他编程语言没差:
computation: +, -, *, /, %(modulo), **(power)
boolean: ==, !=, >, <, >=, <=
3-state: <=>
Bitwise operations: <<, >>, |, &, ~(negation), ^(xor)
Perl中的Context
上下文(context)由运算符来决定。
# Operator "-" forces numerical context for the operands.
print '72' - 30; # 等价于 72 - 30
# Operator "." forces string context for the operands.
print 4 . '2'; # 等价于 '4' . '2'
任何数字类型都可以转换为字符串,任何字符串可以转换为数字,但有可能会导致一个警告信息”non-numerical value in numeric context”.
'42' => 42
'fortytwo' => 0 and a warning
'' => 0 and a warning
'result 42' => 0 and a warning
'42 mice' => 42 and a warning
使用print和printf进行输出
-
print函数接受一串表达式,用,,., 或其他数学运算符分隔,然后输出到STDOUT.print 'This', 'is', 'another', "World\n"; -
printf函数用第一个参数作为模板字符串,其后的参数代入模板中的占位符,然后输出到STDOUT.# "The Result", 42, 42 分别代入占位符%s, %x, %b printf "%s: %x (%b)\n", 'The Result', 42, 42; -
其他点位符: 字符串
%s,整型%d,十六进制数%x,八进制数%o,二进制数%b,浮点数%f,等等。 -
占位符可以格式化代入参数的长度和浮点数精度:
%20s,%5.2f. -
关于
print和printf函数更详细的解释参考文档:perldoc -f print.
练习
Write a script that computes and outputs in order:
- the decimal sum of the binary value 100110 and the octal value 36
- a new line
- the binary sum of the binary value 100110 and the octal value 36
- a new line
- a line of 72 dashes, terminated with a new line
答案:
#!/usr/bin/perl
use strict;
use warnings;
use feature 'say';
printf "%s: %d", "Decimal sum", 0b100110 + 036;
print "\n";
printf "%s: %b", "Binary sum", 0b100110 + 036;
print "\n";
say "-" x 72 . "\n";
变量
-
Scalar类型的变量不会区分字符串和数字类型。
-
变量的命名要在简练和准确达意之间做好平衡。
-
变量未赋值之前是
undef, 类似于Javascript中的undefined.my $greeting; # declare and set to <undef> my $greeting = undef; # same -
Scalar变量在双引号中会被解析(context是字符串)。
my $result = "42"; print "result: $result\n"; print "result: ${result}\n"; -
操作符
-
赋值
my $name = 'Tom'; # declare and assign $name = 'Tom'; # assign (needs to be declared already) -
所有Scalar变量可以使用
<op>=格式的操作(inplace modification)# $variable <operator>= <operand>; my $result = 0; $result = $result + 12; $result += 12; # same as above -
加减g 操作还有
++和--my $y = 0; print $y++; # post increment print ++$y; # pre increment print $y--; # post decrement print --$y; # pre decrement # 注意避免`++$x$x++`这样的表达式,有可以会产生意想不到的Bug
-
练习
-
Write a script that computes the the time (in seconds), an electrical signal would need to travel around the globe (assume the signal travels at the speed of light)
speed of light: 300'000 km/s distance: 40'000 kmMake use of variables, put the computation result into a variable and print it with a nice explanative text around.
-
Bonus: Create a script, that
-
sets a variable x to 41
-
output the variable
-
Now the following lines:
print ++$x, "\n"; # say ++$x; print $x++, "\n"; # say $++; print $x, "\n"; # say $x;- What output do you expect?
- What output do you get?
-
答案:
#!/usr/bin/perl
use strict;
use warnings;
my $speed_of_light = 300000;
my $distance = 40000;
printf "The time an electrical travel global one circle: %f seconds.\n", $distance / $speed_of_light;
my $x = 41;
print ++$x, "\n";
print $x++, "\n";
print $x, "\n";