美文网首页
Effective Perl-chapter1

Effective Perl-chapter1

作者: chensole | 来源:发表于2019-05-19 16:59 被阅读0次

    最近事情有点多,没有什么时间来记录学习历程。月初的时候在网上买了本英文版的《Effective Perl》,被誉为"圣经"的perl系列教程必须拜读一下。接下来的每一周我会整理出两个章节的内容。

    第一章节主要介绍perl基础部分需要注意的细节。

    1. Understand what sigils are telling you
      sigils(魔符)指的是perl变量名前和去引用前的标识
    $  意味着你正在操作的是一个单一的值,这个值可能是一个标量变量也或者是哈希或者数组的单一元素
    $scalar
    $array[3]
    $hash{'key'}
    
    @ 意味着你正在操作的是多个值的集合,你能在数组和哈希中使用它
    @array
    @array[1,2,3]
    @hash{qw(key1 key2)}
    
    % 意味着你把一些东西当作哈希处理
    % hash
    
    不能通过魔符来识别变量的类型,我们能通过三个考量因素来进行判断: 魔符、标识符、索引
    魔符          标识符               索引
       $              name                 [3]    
       $               hash               {'key'}
    通过索引[ ]或{ },我们可以确定变量为数组和哈希
    如果没有索引符号,通过魔符标识即可确定变量类型 
    
    1. know the difference between string and numeric comparisons
      用来比较字符串的操作符也是由字母组成,字符比较是一个字符一个字符按照字符的值进行比较,并且区分大小写和空格
    'a' lt  'b'  #TRUE
    'a' eq 'A'  #false
    'john' eq 'john '  #false
    

    数值比较操作符使用和代数里面的符号差不多

    0 < 5  #TRUE
    10 == 10.0  #TRUE
    

    不要使用数值比较操作符比较字符串,反之亦然。
    为了避免弄混eq和==,我们可以使用只能匹配操作符~~来搞定各种比较操作,它会检查两边的类型找出合适的方法来比较
    当智能匹配操作符发现右边是数字,或者左边是数字而右边像数字的字符串时候,它会按 == 的方式作比较

    if (123 ~~ '456') {...}  # FALSE
    if ('123.0' ~~ 123){...}  #TRUE
    if ('mimi' ~~ 123)  #FALSE
    否则智能匹配操作符会按 eq 的方式来比较
    if ('123' ~~ '123.0') #FALSE  等价于eq
    
    1. know which values are false and test them accordingly
      因为数值和字符串类型的数据在perl中都属于标量,而布尔操作符能针对任何标量进行操作,所以perl 的逻辑真假测试,可以根据数字和字符串的取值判别。
      0 ,'0',undef, ' '(空字符串)都是假值,其他皆为真
      在哈希中,我们用defined来判断某个key的value是否被定义,而exists则是判断是否存在该键名
    $hash{'key'} = undef;
    if ($hash{'key'}) #FALSE
    if (exists $hash{'key'})  #TRUE
    if (defined $hash{'key'}) #FALSE
    如果某个键的赋值明确,哪怕是个代表假的值,这个键对应的值也是已定义的
    $hash{'key'} = ' ';
    if ($hash{'key'}) #FALSE
    if (exists $hash{'key'})  #TRUE
    if (defined $hash{'key'}) #TRUE
    # 当用while读入文件时,行输入操作符<>对于$_变量会自动check $_是否被定义,如果没有定义,则会退出while 循环,结束读入文件. 若不使用$_变量,则需要check变量是否被定义
    while (defined(my $line) = <IN>) {...}
    
    1. know the differene between lists and arrays
      列表是一组标量的有序结合,然而数组是一个含有列表的变量,数组并非列表本身,而是列表的容器
    (localtime)[5]  #列表
    $array[5] #数组
    

    对于数组,在标量上下文则返回数组中元素的个数,然而对于列表没有这样的操作,列表没有标量解释。

    逗号操作符分隔的一串标量
    my $scalar = ('a','b','c');
    print $scalar;  # 有人猜结果为3,其实不是,为c. 逗号操作符在标量上下文中会返回右边的元素
    标量上下文中的列表赋值操作,会返回赋值操作符右边的元素个数
    my $scalar = my @array = localtime
    此时会返回localtime产生的元素个数,赋值操作符是右结合的,先进行最右边的列表赋值,即: 标量上下文环境中列表赋值操作,会返回赋值操作符右边的元素个数
    为了方便可以省略中间数组的命名,可以替换上面的@array为一个空列表
    my $scalar = () = localtime   # 称为山羊操作符
    my $number = () = split /:/,$line
    my $number = () = m/(...)/g; #统计全局匹配的个数
    
    1. Avoid a slice when you want an element
    @a[1]实际上是一个数组切片,获取数组中的某个元素应该使用$array[$n]
    切片是一种同时访问多个元素的快捷方式
    my @select = ($array[1],$array[2]) # 重复输入array,很啰嗦
    my @select = @array[1,2] #使用切片更加简洁
    
    # 左值切片
    在赋值操作中,如果左边是一个切片,那就相当于对切片中的变量元素依次赋值
    @array[1,2] = ('a','b');
    
    # 切片可以交换数组内的元素
    @array[1,2] = @array[2,1]  #swap 1st and 2nd 
    
    # 合并两个哈希
    @hash{keys %hash1} = value %hash1;
    %hash = (%hash,%hash1)  # 于上面结果相同,但很晦涩难懂
    
    # 将一个哈希从另一个哈希中去除
    delete @name{keys %remove}
    通常我们会这么做
    foreach my $k (keys %remove) {
                  delete $name{$k};
    }
    切片很方便,但是切记对于单个元素不要用切片
    
    1. Understand context and how it affects operations
      当操作的需要的是单个对象时,perl会使用标量上下文,当操作多个对象时,perl 使用的就是列表上下文。
      列表操作符希望操作的是多个元素,如print 操作符
      6.1 由赋值操作决定的上下文
      如果是赋值给某个列表,那么赋值操作符会给它右边提供列表上下文环境
    my ($n) = ('a','b','c')  #$n ='a'
    my @lines = <IN> #读入所有行
    给裸标量赋值(赋值操作符左边没有用括号)指定的就是标量上下文
    my $n = ('a','b','c');  # $n = 'c'
    

    以上是我觉得比较重要的东西,这本书内有很多的有意思的东西,值的我去仔细研读。

    关于平常练习使用的perl脚本,我会及时上传到Github上:
    https://github.com/chensole/perl_practice

    相关文章

      网友评论

          本文标题:Effective Perl-chapter1

          本文链接:https://www.haomeiwen.com/subject/pydaaqtx.html