当前位置:  开发笔记 > 编程语言 > 正文

Perl的隐藏功能?

如何解决《Perl的隐藏功能?》经验,为你挑选了39个好方法。

Perl中有哪些非常有用但却深奥的语言功能,你实际上可以用来做有用的工作?

指南:

尝试限制Perl核心的答案,而不是CPAN

请举例和简短说明


其他语言的隐藏功能隐藏功能:

(这些都来自Corion的回答)

C

达夫的装置

便携性和标准性

C#

用于以空格分隔的列表和字符串的引号

可替换的命名空间

Java的

静态初始化剂

JavaScript的

职能是一等公民

阻止范围和关闭

通过变量间接调用方法和访问器

红宝石

通过代码定义方法

PHP

普遍的在线文档

魔术方法

符号引用

蟒蛇

一行值交换

能够使用您自己的功能替换核心功能

其他隐藏的功能:

运营商:

布尔准算子

触发器操作员

也用于列表构建

++和一元-运营商处理字符串

重复运算符

宇宙飞船运营商

|| operator(和//运算符)从一组选项中进行选择

钻石运营商

m//运营商的特殊情况

代字号"操作员"

引用结构:

qw运算符

字母可以用作q {}中的引号分隔符 - 类似构造

报价机制

语法和名称:

在sigil之后可以有一个空间

您可以使用符号引用指定子数字名称

法律尾随逗号

分组整数文字

哈希切片

从数组填充哈希的键

模块,Pragma和命令行选项:

使用严格并使用警告

污点检查

深奥使用-n和-p

CPAN

overload::constant

IO :: Handle模块

安全隔间

属性

变量:

自动激活

$[变量

领带

动态范围

使用单个语句进行变量交换

循环和流量控制:

魔术转到

for 在一个变量上

继续条款

绝望模式

常用表达:

\G

(?{}) 和'(?? {})`在正则表达式中

其他特性:

调试器

特殊代码块,如BEGIN,CHECK和END

DATA

新的块操作

源过滤器

信号挂钩

地图(两次)

包装内置函数

eof功能

dbmopen功能

将警告变为错误

其他技巧和元答案:

cat文件,如果需要,解压缩gzips

Perl技巧


也可以看看:

C的隐藏功能

C#的隐藏功能

C++的隐藏功能

Java的隐藏功能

JavaScript的隐藏功能

Ruby的隐藏功能

PHP的隐藏功能

Python的隐藏功能

Clojure的隐藏功能

John Siracus.. 54

触发器操作符用于在循环文件句柄返回的记录(通常是行)时跳过第一次迭代,而不使用标志变量:

while(<$fh>)
{
  next if 1..1; # skip first record
  ...
}

运行perldoc perlop并搜索"触发器"以获取更多信息和示例.



1> John Siracus..:

触发器操作符用于在循环文件句柄返回的记录(通常是行)时跳过第一次迭代,而不使用标志变量:

while(<$fh>)
{
  next if 1..1; # skip first record
  ...
}

运行perldoc perlop并搜索"触发器"以获取更多信息和示例.


为了澄清,这个"隐藏"的方面是,如果标量'..'的任一操作数是常量,则该值与输入行号($.)隐式比较.

2> moritz..:

Perl中有许多非显而易见的功能.

例如,你知道sigil之后可以有一个空格吗?

 $ perl -wle 'my $x = 3; print $ x'
 3

或者,如果使用符号引用,您可以给出子数字名称?

$ perl -lwe '*4 = sub { print "yes" }; 4->()' 
yes

还有"bool"准运算符,它返回1表示真实表达式,空字符串表示false:

$ perl -wle 'print !!4'
1
$ perl -wle 'print !!"0 but true"'
1
$ perl -wle 'print !!0'
(empty line)

其他有趣的东西:use overload你可以重载字符串文字和数字(例如使它们成为BigInts或其他).

这些东西中的许多实际上是在某处记录的,或者从逻辑上遵循记录的特征,但是有些并不是很清楚.

更新:另一个不错的.在q{...}引用结构下面提到了,但你知道你可以用字母作为分隔符吗?

$ perl -Mstrict  -wle 'print q bJet another perl hacker.b'
Jet another perl hacker.

同样,您可以编写正则表达式:

m xabcx
# same as m/abc/


我认为你使用字母分隔字符串的例子应该是"_Just_另一个perl hacker"而不是"Jet另一个perl hacker"= P
"你知道在印第安之后会有一个空间吗?"我完全被惊呆了.哇.

3> timkay..:

通过magic ARGV添加对压缩文件的支持:

s{ 
    ^            # make sure to get whole filename
    ( 
      [^'] +     # at least one non-quote
      \.         # extension dot
      (?:        # now either suffix
          gz
        | Z 
       )
    )
    \z           # through the end
}{gzcat '$1' |}xs for @ARGV;

(引用带有shell元字符的文件名所需的$ _左右的引号)

现在,该<>功能将解压缩@ARGV以".gz"或".Z"结尾的所有文件:

while (<>) {
    print;
}


我不认为你需要在替换中逃避`|`.

4> pjf..:

Perl中我最喜欢的一个功能是使用布尔||运算符在一组选项之间进行选择.

 $x = $a || $b;

 # $x = $a, if $a is true.
 # $x = $b, otherwise

这意味着可以写:

 $x = $a || $b || $c || 0;

取从所述第一真值$a,$b$c,或者一个默认0否则.

在Perl 5.10中,还有//操作符,如果已定义则返回左侧,否则返回右侧.以下选择第一限定从值$a,$b,$c,或0以其他方式:

$x = $a // $b // $c // 0;

这些也可以与他们的简写形式一起使用,这对于提供默认值非常有用:

$x ||= 0;   # If $x was false, it now has a value of 0.

$x //= 0;   # If $x was undefined, it now has a value of zero.

Cheerio,

保罗


//默认情况下在那里,不需要特殊调整.您还可以使用dor-patch将其后端移植到5.8.x中...查看任何CPAN镜像上的authors/id/H/HM/HMBRAND /目录.FreeBSD 6.x及更高版本在你的perl包中为你做这件事.
这是一种常见的习惯用语,几乎不具备"隐藏"功能的条件.
羞耻漂亮的打印机认为//是评论:)
问题,是否有使用这些新操作符的"使用功能",或者是否默认启用?我仍然倾向于Perl 5.10的功能.
当|| 或//与do {}结合使用,可以封装更复杂的赋值,即$ x = $ a || 做{my $ z; 3或4行推导; $ z};

5> Leon Timmerm..:

运算符++和一元 - 不仅可以处理数字,还可以处理字符串.

my $_ = "a"
print -$_

打印-a

print ++$_

打印b

$_ = 'z'
print ++$_

打印aa


当Perl的新手我自己实现了这个功能时,确切的z到aa行为,然后向一个同事笑着说我,并说"让我告诉你一些事情".我哭了一下,但学到了一些东西.
不要问程序员在"z"之后出现什么; 问一个人.此功能非常适合对长列表中的项目进行编号.
引用perlvar:"自动递减运算符并不神奇." 所以` - `不适用于字符串.
@Ether - 如果你想要,使用数字并用`ord()`将它们自动转换为ASCII.或者,编写一个小类并重载操作符来为您完成.

6> Corion..:

由于Perl几乎所有的"深奥"部分来自其他列表,我会告诉你Perl不能做的一件事:

Perl不能做的一件事就是在代码中有任意URL,因为//运算符用于正则表达式.

为了防止Perl提供的功能不明显,这里有一些可能不是很明显的选项列表:

Duff的设备 - 在Perl中

可移植性和标准性 - 使用Perl的计算机可能多于使用C编译器的计算机

文件/路径操作类 - File :: Find可以在比.Net更多的操作系统上运行

用于以空格分隔的列表 和字符串的引号 - Perl允许您为列表和字符串分隔符选择几乎任意的引号

可替换的命名空间 - Perl通过glob赋值:

*My::Namespace:: = \%Your::Namespace

静态初始化程序 - Perl几乎可以在编译和对象实例化的每个阶段运行代码,从BEGIN(代码解析)到CHECK(在代码解析之后)到import(在模块导入时)到new(对象实例化)到DESTROY(对象破坏)到END(程序退出)

功能是一等公民 - 就像在Perl中一样

阻止范围和关闭 - Perl都有

通过变量间接调用方法和访问器 - Perl也这样做:

my $method = 'foo';
my $obj = My::Class->new();
$obj->$method( 'baz' ); # calls $obj->foo( 'baz' )

通过代码定义方法 - Perl也允许:

*foo = sub { print "Hello world" };

普遍的在线文档 - Perl文档在线,也可能在您的系统上

每当你调用"不存在"函数时调用的魔术方法 - Perl在AUTOLOAD函数中实现它

符号引用 - 建议您远离这些.他们会吃你的孩子.但是,当然,Perl允许您为您的孩子提供嗜血的恶魔.

一行值交换 - Perl允许列表分配

能够使用您自己的功能替换核心功能

use subs 'unlink'; 
sub unlink { print 'No.' }

要么

BEGIN{
    *CORE::GLOBAL::unlink = sub {print 'no'}
};

unlink($_) for @ARGV


没有人会想要它,它只是一个Java meme."http://foo.com"是标签http:然后是评论中的"foo.com".有些人觉得这很有趣,因为......他们很蠢.
"Perl不能做的一件事就是在代码中有任意URL,因为//运算符用于正则表达式." - 这完全是胡说八道.
您为什么/在哪里*需要*代码中的*裸URL?我想不出一个例子.

7> J.J...:

自动化.AFAIK 没有其他语言.


@tchrist - 对于xrange(1,11)中的x,a = [[x*y表示y格式(1,11)]]

8> Robert P..:

在Perl中引用几乎任何类型的奇怪字符串都很简单.

my $url = q{http://my.url.com/any/arbitrary/path/in/the/url.html};

事实上,Perl中的各种引用机制非常有趣.Perl正则表达式引用机制允许您引用任何内容,指定分隔符.您几乎可以使用任何特殊字符,如#,/,或打开/关闭字符,如(),[]或{}.例子:

my $var  = q#some string where the pound is the final escape.#;
my $var2 = q{A more pleasant way of escaping.};
my $var3 = q(Others prefer parens as the quote mechanism.);

报价机制:

q:字面引用; 只有需要转义的字符才是结束字符.qq:解释性引用; 处理变量和转义字符.非常适合您需要引用的字符串:

my $var4 = qq{This "$mechanism" is broken.  Please inform "$user" at "$email" about it.};

qx:像qq一样工作,但后来作为系统命令执行,非交互式.返回从标准输出生成的所有文本.(重定向,如果在操作系统中受支持,也会出现)也使用后引号(`字符).

my $output  = qx{type "$path"};      # get just the output
my $moreout = qx{type "$path" 2>&1}; # get stuff on stderr too

qr:解释像qq,但然后将其编译为正则表达式.适用于正则表达式的各种选项.您现在可以将正则表达式作为变量传递:

sub MyRegexCheck {
    my ($string, $regex) = @_;
    if ($string)
    {
       return ($string =~ $regex);
    }
    return; # returns 'null' or 'empty' in every context
}

my $regex = qr{http://[\w]\.com/([\w]+/)+};
@results = MyRegexCheck(q{http://myurl.com/subpath1/subpath2/}, $regex);

qw:一个非常非常有用的报价运算符.将一组引用的空格分隔的单词转换为列表.非常适合在单元测试中填写数据.

   my @allowed = qw(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z { });
   my @badwords = qw(WORD1 word2 word3 word4);
   my @numbers = qw(one two three four 5 six seven); # works with numbers too
   my @list = ('string with space', qw(eight nine), "a $var"); # works in other lists
   my $arrayref = [ qw(and it works in arrays too) ]; 

只要它能让事情变得更清晰,它们就能很好地使用它们.对于qx,qq和q,我很可能使用{}运算符.使用qw的人最常见的习惯通常是()运算符,但有时你也会看到qw //.



9> timkay..:

"for"语句的使用方法与Pascal中使用的"with"相同:

for ($item)
{
    s/&?nbsp;/ /g;
    s/<.*?>/ /g;
    $_ = join(" ", split(" ", $_));
}

您可以将一系列s ///操作等应用于​​同一变量,而无需重复变量名称.

注意:上面的非中断空格( )中隐藏了Unicode以规避Markdown.不要复制贴吧:)


此外,因为在执行操作的代码之前列出了被操作的项目,从而提高了可读性.

10> mpeters..:

并非真正隐藏,但Perl程序员每天都不了解CPAN.这尤其适用于不是全职程序员或不在Perl全职编程的人.



11> dland..:

引号运算符是我最喜欢的东西之一.相比:

my @list = ('abc', 'def', 'ghi', 'jkl');

my @list = qw(abc def ghi jkl);

噪音更少,眼睛更容易.关于Perl的另一个非常好的事情,一个在编写SQL时真的错过了,是一个尾随逗号是合法的:

print 1, 2, 3, ;

这看起来很奇怪,但如果你以另一种方式缩进代码则不行:

print
    results_of_foo(),
    results_of_xyzzy(),
    results_of_quux(),
    ;

在函数调用中添加一个额外的参数不需要在前一行或尾随行上使用逗号.单线更改对其周围线没有影响.

这使得使用可变参数函数非常愉快.这可能是Perl评价最低的功能之一.


Perl语法的一个有趣的角落案例是以下内容是有效的:对于$ _ qw(一个东西列表){...}
@ephemient,@ fengshaun,@ moritz,@ dland:*在*blead*中"固定"; 见[this p5p thread](http://www.nntp.perl.org/group/perl.perl5.porters/2010/08/msg163360.html).

12> 小智..:

解析直接粘贴到DATA块的数据的能力.无需保存到要在程序中打开的测试文件或类似文件.例如:

my @lines = ;
for (@lines) {
    print if /bad/;
}

__DATA__
some good data
some bad data
more good data 
more good data 


@Hai:不,它不是**不丑 - 事实上,它正好与丑陋相反:它干净,苗条,极简,美丽; 总之,它很精彩,没有它的语言就是PITA.@peter mortensen,@ toad:如何在同一个程序中使用多个数据块的一个答案是使用[Inline :: Files](http://search.cpan.org/search?query=inline%3A%3Afiles&mode =模块)模块关闭CPAN.

13> Bruno De Fra..:

二进制"x"是重复运算符:

print '-' x 80;     # print row of dashes

它也适用于列表:

print for (1, 4, 9) x 3; # print 149149149


我最喜欢使用的是为SQL INSERT语句的最后一部分生成占位符:@p =('?')x $ n; $ p = join(",",@ p); $ sql ="INSERT ... VALUES($ p)";

14> Axeman..:

新的块操作

我想说扩展语言的能力,创建伪块操作就是其中之一.

    您声明了一个sub的原型,表明它首先需要一个代码引用:

    sub do_stuff_with_a_hash (&\%) {
        my ( $block_of_code, $hash_ref ) = @_;
        while ( my ( $k, $v ) = each %$hash_ref ) { 
            $block_of_code->( $k, $v );
        }
    }
    

    然后你可以像这样在身体中调用它

    use Data::Dumper;
    
    do_stuff_with_a_hash {
        local $Data::Dumper::Terse = 1;
        my ( $k, $v ) = @_;
        say qq(Hey, the key   is "$k"!);
        say sprintf qq(Hey, the value is "%v"!), Dumper( $v );
    
    } %stuff_for
    ;
    

(Data::Dumper::Dumper是另一个半隐藏的宝石.)注意你不需要sub在块前面的关键字,或哈希前的逗号.最终看起来很像:map { } @list

源过滤器

此外,还有源过滤器.Perl会将代码传递给您,以便您可以操作它.这个以及块操作都是非常不尝试这种在家的类型.

我已经使用源过滤器做了一些巧妙的事情,例如创建一个非常简单的语言来检查时间,允许简短的Perl单行进行一些决策:

perl -MLib::DB -MLib::TL -e 'run_expensive_database_delete() if $hour_of_day < AM_7';

Lib::TL 只会扫描"变量"和常量,创建它们并根据需要替换它们.

同样,源过滤器可能很混乱,但功能强大.但它们可能会使调试程序变得糟糕 - 甚至可能会使用错误的行号打印警告.我停止使用Damian的Switch,因为调试器将无法告诉我我到底在哪里.但我发现你可以通过修改一小段代码来最小化损坏,使它们保持在同一条线上.

信号挂钩

这通常已经足够了,但并不是那么明显.这是一个捎带旧的模具处理程序.

my $old_die_handler = $SIG{__DIE__};
$SIG{__DIE__}       
    = sub { say q(Hey! I'm DYIN' over here!); goto &$old_die_handler; }
    ;

这意味着每当代码中的某个其他模块想要死时,它们就会来找你(除非其他人进行破坏性覆盖$SIG{__DIE__}).并且可以通知您有些事情是错误的.

当然,对于足够多的东西,你可以只使用一个END { }块,如果你想做的只是清理.

overload::constant

您可以在包含模块的包中检查特定类型的文字.例如,如果你在importsub中使用它:

overload::constant 
    integer => sub { 
        my $lit = shift;
        return $lit > 2_000_000_000 ? Math::BigInt->new( $lit ) : $lit 
    };

这意味着调用包中每个大于20亿的整数都将被更改为一个Math::BigInt对象.(参见overload :: constant).

分组整数文字

虽然我们正在努力.Perl允许您将大数字分成三个数字的组,并且仍然可以获得一个可解析的整数.注意2_000_000_000上面有20亿.


当使用$ SIG {__ DIE__}处理程序时,强烈建议您检查$ ^ S以查看您的程序是否实际死亡,或者只是抛出将被捕获的异常.通常你不想干涉后者.

15> Andru Luvisi..:

污点检查.启用污点检查后,-t如果您尝试将污染数据(粗略地说,来自程序外部的数据)传递给不安全的功能(打开文件,运行外部命令等),perl将会死亡(或发出警告).在编写setuid脚本或CGI或脚本具有比提供数据的人更多特权的任何内容时,它非常有用.

魔术转到. goto &sub做一个优化的尾调用.

调试器.

use strictuse warnings.这些可以帮助您摆脱一堆拼写错误.



16> Sec..:

基于Perl 5中的"-n""-p"交换机的实现方式,您可以编写一个看似不正确的程序,包括}{:

ls |perl -lne 'print $_; }{ print "$. Files"'

在内部转换为此代码:

LINE: while (defined($_ = )) {
    print $_; }{ print "$. Files";
}



17> Sec..:

让我们从宇宙飞船运营商那里开始.

$a = 5 <=> 7;  # $a is set to -1
$a = 7 <=> 5;  # $a is set to 1
$a = 6 <=> 6;  # $a is set to 0


值得一提的是关于-1/0/1比较运算符的有用之处,因为并非所有人都知道:您可以将它们与or-operator链接在一起以进行主要/次要/等.排序.所以`($ a-> lname cmp $ b-> lname)|| ($ a-> fname cmp $ b-> fname)`用姓氏对人进行排序,但如果两个人的姓氏相同,那么他们将按照他们的名字排序.

18> pjf..:

这是一个元答案,但Perl Tips档案包含可以使用Perl完成的各种有趣的技巧.以前的提示存档是在线浏览,可以通过邮件列表或原子订阅订阅.

我最喜欢的一些技巧包括使用PAR构建可执行文件,使用autodie自动抛出异常,以及在Perl 5.10中使用switch和smart-match构造.

披露:我是Perl Tips的作者和维护者之一,所以我显然非常重视它们.;)


它可能是最好的文档语言之一,并为搜索文档设置工具模式.这个问题中的列表可能不像其他语言那样需要.

19> 小智..:

map - 不仅因为它使得一个人的代码更具表现力,而且因为它让我有一种冲动来阅读更多关于这种"函数式编程"的信息.



20> Leon Timmerm..:

我的投票将用于Perl正则表达式中的(?{})和(?? {})组.第一个执行Perl代码,忽略返回值,第二个执行代码,使用返回值作为正则表达式.



21> 小智..:

循环上的continue子句.它将在每个循环的底部执行,即使是下一个循环.

while( <> ){
  print "top of loop\n";
  chomp;

  next if /next/i;
  last if /last/i;

  print "bottom of loop\n";
}continue{
  print "continue\n";
}



22> Michael Carm..:

m//运营商有一些模糊的特殊情况:

如果您使用?分隔符,除非您致电,否则它只匹配一次reset.

如果'用作分隔符,则不插入模式.

如果模式为空,则使用上次成功匹配的模式.


我无法想象一个Perl程序员无法记住(甚至猜测)单引号代表无插值.它使用这种语义几乎是普遍的语言,我宁愿_expect_这是如此...
这些更像隐藏的陷阱而不是隐藏的功能!我不认识任何喜欢他们的人.一段时间后,p5p上的一个帖子讨论了推定的m/$ foo/r标志的用处,其中/ r表示没有插值(字母不重要),因为没有人能记住单引号的东西.
@dland:同意; 我称这些隐藏的*mis*功能,并且永远不会在生产代码中使用它们.

23> J.J...:
while(/\G(\b\w*\b)/g) {
     print "$1\n";
}

\ G锚.它是热的.


...它表示上一场比赛结束的位置.

24> spoulson..:

null filehandle 菱形运算符 <>在构建命令行工具中占有一席之地.它的作用就像是从句柄中读取,除了它神奇地选择最先找到的那个:命令行文件名或STDIN.摘自perlop:

while (<>) {
...         # code for each line
}


它也遵循UNIX语义使用" - "来表示"从stdin读取.所以你可以做`perl myscript.pl file1.txt - file2.txt`,perl将处理第一个文件,然后是stdin,然后是第二个文件文件.

25> Bruno De Fra..:

特殊的代码块,如BEGIN,CHECKEND.它们来自Awk,但在Perl中的工作方式不同,因为它不是基于记录的.

BEGIN块可用于为解析阶段指定一些代码; 执行语法和变量检查时也会执行它perl -c.例如,要加载配置变量:

BEGIN {
    eval {
        require 'config.local.pl';
    };
    if ($@) {
        require 'config.default.pl';
    }
}



26> timkay..:
rename("$_.part", $_) for "data.txt";

将data.txt.part重命名为data.txt而不必重复自己.



27> Sec..:

有点模糊的是波形符号"操作符",它强制标量上下文.

print ~~ localtime;

是相同的

print scalar localtime;

与...不同

print localtime;


这是特别模糊的,因为perl5.10.0还引入了"智能匹配运算符"`~~`,它可以进行正则表达式匹配,可以查看项目是否包含在数组中,依此类推.
@Nomad Dervish:标量上下文/ =字符串化.例如"$ n = @a"是标量上下文."$ s = qq'@ a'"是字符串化.关于引用,"$ ref1 = $ ref2"是标量上下文,但不进行字符串化.

28> 小智..:

tie,变量绑定接口.



29> Schwern..:

Perl的循环控制构造的"绝望模式"导致它们查找堆栈以找到匹配的标签,这允许一些好奇的行为,Test :: More利用了这些行为,无论好坏.

SKIP: {
    skip() if $something;

    print "Never printed";
}

sub skip {
    no warnings "exiting";
    last SKIP;
}

有一个鲜为人知的.pmc文件."使用Foo"将在Foo.pm之前在@INC中查找Foo.pmc. 这是为了允许首先加载已编译的字节码,但Module :: Compile利用此功能来缓存源过滤的模块,以加快加载速度并简化调试.

将警告变为错误的能力.

local $SIG{__WARN__} = sub { die @_ };
$num = "two";
$sum = 1 + $num;
print "Never reached";

这就是我能想到的没有被提及的头脑.



30> Chas. Owens..:

山羊运营商*:

$_ = "foo bar";
my $count =()= /[aeiou]/g; #3

要么

sub foo {
    return @_;
}

$count =()= foo(qw/a b c d/); #4

它的工作原理是因为标量上下文中的列表赋值会产生所分配列表中的元素数.

* 注意,不是真正的操作员



31> 小智..:

输入记录分隔符可以设置为对数字的引用以读取固定长度记录:

$/ = \3; print $_,"\n" while <>; # output three chars on each line



32> 小智..:

我不知道它有多深奥,但我最喜欢的是哈希切片.我把它用于各种各样的事情.例如,合并两个哈希:

my %number_for = (one => 1, two => 2, three => 3);
my %your_numbers = (two => 2, four => 4, six => 6);
@number_for{keys %your_numbers} = values %your_numbers;
print sort values %number_for; # 12346



33> Schwern..:

这个并不是特别有用,但它非常深奥.我在Perl解析器中挖掘时偶然发现了这一点.

在有POD之前,perl4有一个技巧允许你将手册页(如nroff)直接嵌入你的程序中,这样它就不会丢失.perl4使用了一个名为wrapman的程序(请参阅Pink Camel第319页了解一些细节),巧妙地将nroff手册页嵌入到脚本中.

它的工作原理是告诉nroff忽略所有代码,然后在END标记之后放置man页面的内容,告诉Perl停止处理代码.看起来像这样:

#!/usr/bin/perl
'di';
'ig00';

...Perl code goes here, ignored by nroff...

.00;        # finish .ig

'di         \" finish the diversion
.nr nl 0-1  \" fake up transition to first page
.nr % 0     \" start at page 1
'; __END__

...man page goes here, ignored by Perl...

roff魔法的细节让我感到惊讶,但你会发现roff命令是void上下文中的字符串或数字.通常,void上下文中的常量会产生警告.op.c允许使用以某些roff命令开头的void上下文字符串有一些特殊的例外.

              /* perl4's way of mixing documentation and code
                 (before the invention of POD) was based on a
                 trick to mix nroff and perl code. The trick was
                 built upon these three nroff macros being used in
                 void context. The pink camel has the details in
                 the script wrapman near page 319. */
                const char * const maybe_macro = SvPVX_const(sv);
                if (strnEQ(maybe_macro, "di", 2) ||
                    strnEQ(maybe_macro, "ds", 2) ||
                    strnEQ(maybe_macro, "ig", 2))
                        useless = NULL;

这意味着,'di';不产生警告,但同样没有'die'; 'did you get that thing I sentcha?';'ignore this line';.

此外,还有用于数字常量例外01允许裸露.00;.该代码声称这是出于更一般的目的.

            /* the constants 0 and 1 are permitted as they are
               conventionally used as dummies in constructs like
                    1 while some_condition_with_side_effects;  */
            else if (SvNIOK(sv) && (SvNV(sv) == 0.0 || SvNV(sv) == 1.0))
                useless = NULL;

你知道什么,2 while condition警告!



34> user105090..:

您可以使用@ {[...]}来获得复杂perl表达式的插值结果

$a = 3;
$b = 4;

print "$a * $b = @{[$a * $b]}";

打印: 3 * 4 = 12



35> timkay..:
sub load_file
{
    local(@ARGV, $/) = shift;
    <>;
}

以及适当返回数组的版本:

sub load_file
{
    local @ARGV = shift;
    local $/ = wantarray? $/: undef;
    <>;
}



36> Robert P..:
use diagnostics;

如果您开始使用Perl并且之前从未这样做过,那么这个模块将为您节省大量时间和麻烦.对于您可以获得的几乎所有基本错误消息,此模块将为您提供有关代码中断的原因的冗长解释,包括有关如何修复它的一些有用提示.例如:

use strict;
use diagnostics;

$var = "foo";

给你这个有用的信息:

Global symbol "$var" requires explicit package name at - line 4.
Execution of - aborted due to compilation errors (#1)
    (F) You've said "use strict vars", which indicates that all variables
    must either be lexically scoped (using "my"), declared beforehand using
    "our", or explicitly qualified to say which package the global variable
    is in (using "::").

Uncaught exception from user code:
        Global symbol "$var" requires explicit package name at - line 4.
Execution of - aborted due to compilation errors.
 at - line 5
use diagnostics;
use strict;

sub myname {
    print { " Some Error " };
};

你得到这个大而有用的文本块:

syntax error at - line 5, near "};"
Execution of - aborted due to compilation errors (#1)
(F) Probably means you had a syntax error.  Common reasons include:

    A keyword is misspelled.
    A semicolon is missing.
    A comma is missing.
    An opening or closing parenthesis is missing.
    An opening or closing brace is missing.
    A closing quote is missing.

Often there will be another error message associated with the syntax
error giving more information.  (Sometimes it helps to turn on -w.)
The error message itself often tells you where it was in the line when
it decided to give up.  Sometimes the actual error is several tokens
before this, because Perl is good at understanding random input.
Occasionally the line number may be misleading, and once in a blue moon
the only way to figure out what's triggering the error is to call
perl -c repeatedly, chopping away half the program each time to see
if the error went away.  Sort of the cybernetic version of S.

Uncaught exception from user code:
    syntax error at - line 5, near "};"
Execution of - aborted due to compilation errors.
at - line 7

从那里你可以去推断你的程序可能出现什么问题(在这种情况下,打印格式完全错误).诊断中存在大量已知错误.现在,虽然这在生产中使用不是一件好事,但对于那些刚接触Perl的人来说,它可以作为一个很好的学习辅助工具.



37> Sec..:

还有$ [变量决定数组的起始索引.默认值为0,因此数组从0开始.通过设置

$[=1;

如果你真的想要,你可以让Perl表现得更像AWK(或Fortran).


虽然引用了perlvar的文件说明:"它的使用非常气馁." 没有多少人期望数组的起始下标发生变化.
我只会在单行中使用此功能,如果有的话.

38> 小智..:

($ x,$ y)=($ y,$ x)是我想要学习Perl的原因.

列表构造函数1..99或'a'..'zz'也非常好.



39> 小智..:

@Schwern提到通过本地化将警告转化为错误$SIG{__WARN__}.你也可以这样做(词法)use warnings FATAL => "all";.见perldoc lexwarn.

在那个音符上,自从Perl 5.12以来,你已经能够说perldoc foo而不是完整了perldoc perlfoo.最后!:)

推荐阅读
小白也坚强_177
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有