这个Perl语法构造是什么?

jac*_*ter 5 sorting syntax perl

我有一个跟进问题,我的早期帖子按数值排序文件名.

解决方案是这段代码:

opendir(XMLDIR,$xmldirname);
my @files = sort {substr($a, 0, index($a, '.')) <=> substr($b, 0, index($b, '.'))} readdir(XMLDIR);
Run Code Online (Sandbox Code Playgroud)

我真的不明白readdir前面的整个{...}是做什么的,或者更确切地说,它是如何做它正在做的事情.当然,我可以看到两个值相互比较.但是整个事情是什么样的语法结构?$ a和$ b来自哪里?我可以在Perl书中看到哪些标题?这是一个特殊的东西,只适用于sort {}还是有其他方法可以使用这个构造?

ike*_*ami 7

采用的语法sort

sort BLOCK LIST
Run Code Online (Sandbox Code Playgroud)

表示的表达式LIST是返回要排序的值列表.这是readdir(XMLDIR)你的情况.它返回目录中文件名的列表.

BLOCK是有趣的部分.它表示curlies中的代码,由排序算法调用以与要排序的元素进行比较.要比较的元素是$a$b,并且代码应该评估为以下之一:

  • 如果$a应该放在之前的负值$b,
  • 如果$a相对于哪个位置无关紧要,则为零$b,或者
  • 如果$a应放在后面,则为正值$b.

substr($a, 0, index($a, '.'))在第一个之前提取文件名的一部分..在这种情况下,它会提取文件名中的数字.

然后,从两个文件名中提取的数字数值通过比较<=>,重新调谐-1,0+1如上文所述.


请注意,您的代码会发出警告,因为它不会考虑readdir将返回....我通过添加原始问题的答案来解决这个问题.


Rob*_*arl 5

这是sort使用参数调用的.块用于其他几个Perl内置的包括mapgrep.

块参数是一种为要执行的函数定义自己的代码的方法.sort使用块来比较要排序的列表中的两个值,用$a和表示$b.

使用原型,您可以定义自己的子例程以类似的方式工作:

sub block_exec(&@) {
    my $block = shift;

    for (@_) {
        &$block;
    }
}

block_exec { print "block! $_\n"; } (1..10);
Run Code Online (Sandbox Code Playgroud)