从《Learning Perl》第七版中学到的5件事

《Learning Perl》第七版预计在本月晚些时候发布。我是这本书的技术审稿人之一——自从这本书作为我在大学时的课程教材(当时Perl被描述为“文本处理语言”)以来,我就没有读过它了!在审阅这本书的过程中,我对其所包含的细节之多印象深刻。如果你正在寻找对Perl的全面介绍,这是一个很好的起点。在阅读过程中,我学到了(或重新学习了)一些技巧,我认为这些技巧值得分享。

1. 堆叠文件测试运算符

你可能知道Perl支持许多文件测试运算符,这些运算符可以执行一些有用的功能,比如检查文件是否存在、是否可读等。

  if (-e $filepath && -r $filepath) {
    ... 
  }

但是,你知道从5.10版本开始,你可以堆叠文件测试运算符吗?

  if (-e -r $filepath) {
    ...
  }

这种方式更简洁、更短。而且,额外的奖励!文件测试运算符也可以用于文件句柄。堆叠文件运算符不是特性祈使句的一部分,因此不需要显式使用use 5.10.0;,尽管如果你的代码将要被共享,你可能需要包含它。

2. glob函数的复杂历史

《Learning Perl》中包含了许多关于Perl历史的趣事。你可能之前使用过glob函数。

my @json_files = glob '*.json';

这个函数会返回当前工作目录中以.json结尾的所有文件名。Glob函数接受由空白字符分隔的字符串模式,因此你可以提供多个模式。

  my @config_files = glob '*.json *.toml *.ini';

你不需要使用单词glob,而是可以使用尖括号。

  my @json_files = <*.json>;

这些尖括号将它们之间的文本视为双引号字符串。我学到的一件事是,Perl的古老版本(5.6之前)每次遇到glob时都会调用/bin/csh!这使得globbing变得缓慢,目录句柄比glob更受欢迎。

3. Perl支持内联二进制表示法

在许多基于C的语言中,你可以用十六进制和八进制表示法书写数字,你可以在Perl中这样做。

  my $byte_max = 0xff;
  my $permissions = 0755;

然而,在Perl中,你还可以使用前缀0b来内联书写二进制数字。

  my $bits = 0b10111000;

这可以让你更容易地处理二进制数据;你不需要使用十六进制表示法并进行心算来计算值,你可以直接书写二进制数据。例如,假设你正在审查一些代码:

  if ($bit_array & 0x40) {
    ...
  }

要理解这个示例的十六进制表示,你必须计算出4 * 16 = 64,然后要么知道,要么将该数字转换为二进制以找出第7位是否翻转,并理解这是在测试$bit_array是否有该位翻转。以下是用内联二进制表示的相同代码:

  if ($bit_array & 0b1000000) {
    ...
  }

在这个示例中,你只需看到第7位被翻转,if语句的意图也就一目了然了。如果你对位数组和位运算符感兴趣,我最近写了一个介绍

4. 检查安装的模块是否是最新的

如今,我们有许多高级Perl包安装器,如cpanmcpm,因此很容易忘记基本的CPAN客户端也能做很多事情。例如,-D选项检查模块的安装版本,并将其与CPAN上的最新版本进行比较。因此,要检查Test::More模块是否是最新的,我可以在终端中输入:

$ cpan -D Test::More

CPAN: Storable loaded ok (v2.53)
Reading '/home/dfarrell/.local/share/.cpan/Metadata'
  Database was generated on Thu, 22 Sep 2016 21:53:30 GMT
Test::More
-------------------------------------------------------------------------
      (no description)
      E/EX/EXODIST/Test-Simple-1.302056.tar.gz
      /home/dfarrell/.plenv/versions/5.22.0/lib/perl5/5.22.0/Test/More.pm
      Installed: 1.001014
      CPAN:      1.302056  Not up to date
      Chad Granum (EXODIST)
      exodist7@gmail.com

哇,我的版本相当过时了。我应该升级……

5. 避免使用shell进行系统命令

Perl 的内置函数 execsystem 在执行系统命令时可能会调用 shell。通常,您希望避免这种情况,因为调用 shell 比直接执行命令要慢。Perl 会查看传递给 execsystem 的第一个参数,如果它包含 shell 元字符,则会调用 shell。

my $command = join " ", $program, $arg1, $arg2;
system $command; # may invoke shell

假设您需要调用一个系统命令,而且您不确定命令参数是否包含元字符。如果包含,shell 将会被调用,并且任何元字符都会被替换。避免 shell 替换元字符的一种方法是对其进行转义。但是,shell 的转义序列很少简单(例如,转义单引号)。学习 Perl 展示了一种更好的方法:传递一个列表。

system $program, $arg1, $arg2; # never invokes the shell

这永远不会调用 shell,并避免元字符替换。

现在预购《Learning Perl》

《Learning Perl》第 7 版有近 400 页,描述了 Perl 的语法以及如何完成重要的任务,如文件输入输出、进程管理和模块安装。现在可以在 Amazon 预购(这是 brian d foy 的联盟链接,他是本版的作者)。您也可以从出版社 O’Reilly 购买。查看 Brian 关于新版的博客 网站


本文最初发布在 PerlTricks.com 上。

标签

David Farrell

David 是一名专业程序员,他经常 推文博客 关于代码和编程的艺术。

浏览他们的文章

反馈

这篇文章有什么问题吗?通过在 GitHub 上打开一个问题或拉取请求来帮助我们。