前言

正常情况下, Perl 定义变量直接赋值即可, 但是这样有时候会导致一些问题, 一般建议使用 use strict, 这样定义变量的时候必须使用 my 关键字, 例如:

use strict;
my $var = "var";

另外, Perl 默认的 print 方法并不自带换行符, 会导致每次需要换行符的时候, 需要写成这样:

use strict;
print "Hello World\n";

# or
my $hello = "Hello World";

print $hello . "\n";

并不优雅也很麻烦. 所以又建议使用 use 5.011 (及以上)替换 use strict, 因为 5.011 强制开启 use strict, 而且新增了 say 方法, 自带换行符, 会比较方便:

use 5.011;
say "Hello World"; # add "\n" automatically

变量

# scalar
my $hello  = 1;
my $_hello = 1;
my $HELLO  = 1;

# array
my @array = (1, 2, 3);

# hash
my %hash = (a => 1, b => 1);

数据类型

my $num0 = 1;
my $num1 = 100_000; # "100_000" equals "100000", you can add "_" in a number

my $float = 3.14;

条件语句

if - elsif - else

if ($_ == "if") {
    say "if";
}
elsif ($_ == "elsif") {
    say "elsif";
}
else {
    say "else";
}

say "this is one line version of if" if 1;

unless (opposite of if)

if (1) {
    say "yes"; # would say yes
}

unless (0) {
    say "yes"; # would say yes
}

my $bool = 0;
say "yes" if !$bool; # would say yes
say "yes" unless $bool; # would say yes

流程控制

for

for (my $i = 0; $i < 10; $i++) {
    say $i;
}

for my $idx (1 .. 10) {
    say $idx;
}

foreach

foreach my $idx (1 .. 10) {
    say $idx;
}

while

my $idx = 0;
while (1) {
    $idx += 1;
    last if $idx == 10;
    next if $idx < 10;
    say "in while loop"; # won't execute
}

say $idx; # would be 10

引用

# new normal variables
my $string = "string";
my @array = (1, 2, 3);
my %hash = (a => 1, b => 1);

# make reference, use "\"
my $string_ref = \$string; # note it's "$" before "string_ref"
my $array_ref = \@array; # note it's "$" before "array_ref"
my $hash_ref = \%hash; # note it's "$" before "hash_ref"

# dereference
say $$string_ref; # equals say $string; # use "$" before $var
say @$array_ref; # equals say @array; # use "@" before $var
say %$hash_ref; # equals say %hash; # use "%" before $var

# new reference variables directly
my $array_direct_ref = [1, 2, 3]; # use "[]" instead of "()"
my $hash_direct_ref = {a => 1, b => 1}; # use "{}" instead of "()"

say @$array_direct_ref;
say %$hash_direct_ref;

函数

无返回值

sub self_introduce {
    # input parameters stored in "@_"
    # "shift" implicit means shift "@_" here
    my $name = shift; # shift @_
    my $age = shift; # shift @_

    say "my name is: $name";
    say "my age is: $age";
}

# you can also call function by using: &self_introduce('lane', 29)
# but it is eaiser to call it without "&"
self_introduce('lane', 29);

有返回值

sub max {
    my $left = shift;
    my $right = shift;

    # in fact, you can omit the keyword "return"
    # the last evaluated value will become the returned value implicitly
    return $left > $right ? $left : $right;
}

say max(1, 3); # 3

闭包

sub outter {
    my $cnt = 0;
    my $inner = sub {
        $cnt += 1;
        say $cnt;
    };
    return $inner;
}

my $foo = outter;

$foo->(); # 1
$foo->(); # 2
$foo->(); # 3
$foo->(); # 4

面向对象

定义类

package ParentClass;

sub new {
    my $class = shift;
    my $self = {};

    bless $self, $class; # notice the "bless" keyword
    return $self;
}

sub say_hello {
    say "Hello from ParentClass";
}

继承

package ChildClass;

# if ParentClass.pm not in current directory, you need this line
use ParentClass;

# any one of below is OK
our @ISA = qw/ParentClass/;
use parent qw/ParentClass/;
use base qw/ParentClass/;

sub say_hello {
    say "Hello from ChildClass";
}

# test
say "papa say:";
my $papa = ParentClass->new();
$papa->say_hello();

say "baby say:";
my $baby = ChildClass->new();
$baby->say_hello();

黑科技

字符串内插时执行运算

任何时候, 当我们使用命名数组的时候, 我们都可以使用在打括号中放置该数组的引用的方式来替换.

my @arr;
my $ref = \@arr;

# it's equals
@arr;
@{$ref};

一个中括号就是一个匿名的数组引用, 所以用来放入大括号中没有问题.

@{["some words"]};

一个匿名的数组引用, 即一个中括号中, 是可以进行任意运算的.

[undef // "some words"];

以上几点联立起来, 再加上数组可以往字符串中进行内插这个特性, 我们可以得到在字符串内插的同时进行任意运算的一般表达式:

# "@{['your expression here']}"
say @{[undef // "some words"]}; # print "some words"

use VS. require

use编译时(compile time)生效, require运行时(run time)生效.

并且以下两种写法等效:

use ModuleName;

# equals

BEGIN {
    require ModuleName;
    ModuleName->import;
}
Comments
Write a Comment