学习Perl,One-Liner表现不同

时间:2016-04-01 23:22:57

标签: perl

更新

正如答案中所指出的,这个问题与Perl中的Scalar与List Context有关。

## ## ##

我正在通过自学速成课程(主要是使用Llama书籍和网络)学习perl。在尝试一些字节交换代码时,我发现了一个我完全不理解的衬里。剧本中的评论解释了我认为在单行中发生的事情。

String url = getArguments().getString("key_url");

输出:

  

998是十六进制0x03E6这些数字(交换的字节数)应该匹配......   E603   6E30   E603   E603

     

999是十六进制0x03E7这些数字(交换的字节数)应该匹配......   E703   7E30   E703   E703

     

1000是十六进制0x03E8这些数字(交换的字节数)应该匹配......   E803   8E30   E803   E803

为什么一个班轮工作,为什么 webView.loadUrl(url); 没有同样的方式?我很确定我理解为什么#!/usr/bin/perl -- # # Script to print byte-swapped hex values # use 5.010; use warnings; use strict; # NOTE: I realize I could use a single variable 'data', but the x- y- z- prefixes may help in # identification (for clarity) in the code for this SO question. my $xData; my $yData; my $zData; for ( my $ijk = 998; $ijk < 1001; $ijk++ ) { printf ( "\n%4d is hex " . (sprintf "0x%04X", $ijk) . "\n", $ijk ); # with byte swap say "These numbers (bytes swapped) should match..."; # do sprintf, match pattern and store to ($1)($2), now reverse them into ($2)($1). # BindOp leaves $_ alone, match stuffs $_ & is then used as input for reverse, prints. say reverse ((sprintf "%04X", $ijk) =~ /(..)(..)/) ; # from perlmonks' webpage $yData = (reverse ((sprintf "%04X", $ijk) =~ /(..)(..)/) ); say $yData; # does NOT match $xData = sprintf "%04X", $ijk; $xData =~ s/(..)(..)/$2$1/ ; say $xData; # does match $_ = sprintf "%04X", $ijk; /(..)(..)/; $zData = $2 . $1 ; say $zData; # does match } exit 0; $yData有效,但我希望$xData是最接近的等效非单行。什么是最接近的等效非单线,为什么?差异在哪里?

1 个答案:

答案 0 :(得分:1)

打印(reverse)语句中的say出现在列表上下文中,而当分配给$yData时,上下文是标量。根据上下文,此函数(可能)的行为有很大不同。

来自perldoc -f reverse

  

反向列表
                 在列表上下文中,返回一个列表值,该列表值由相反顺序的LIST元素组成。在标量上下文中,连接LIST的元素并返回一个字符串值,其中所有字符的顺序相反。

在这种情况下,这会产生不同的结果。

在列表上下文中调用时,它会交换(两个)输入字节,保持每个字节完整(由组中匹配的两个十六进制数字表示)。在标量上下文中调用时,它会连接输入并返回一个以相反顺序运行的字符串。为了表示十六进制数,这将改变每个字节。