Perl中的隐藏功能?(Hidden features of Perl?)

2019-09-01 00:34发布

什么是Perl中一些非常有用的,但深奥的语言功能,你实际上已经可以聘请做无用功?

指南:

  • 尝试限制答案Perl的核心,而不是CPAN
  • 请举一个例子,一个简短的描述

隐藏功能在其他语言中隐藏的功能还发现:

(这些都是从Corion的答案 )

  • C
    • 达夫设备
    • 便携性和Standardness
  • C#
    • 行情空格分隔列表和字符串
    • Aliasable命名空间
  • Java的
    • 静态Initalizers
  • JavaScript的
    • 函数是一等公民
    • 区块范围和关闭
    • 调用方法和访问器间接地通过可变
  • 红宝石
    • 通过代码定义方法
  • PHP
    • 普适在线文档
    • 魔术方法
    • 符号引用
  • 蟒蛇
    • 一号线值交换
    • 能力用自己的功能,即使更换核心功能

其他隐藏的特点:

运营商:

  • 该布尔准运营商
  • 触发器操作
    • 也用于列表建设
  • ++和一元-对字符串操作员工作
  • 重复操作
  • 飞船操作
  • 该|| 运营商(和//运营商)从一组选项中进行选择
  • 钻石操作
  • 在特殊情况m//运营商
  • 波浪线的波浪线“经营者”

引述结构:

  • 在QW操作
  • 信件可以作为在Q {}引号分隔符-样结构
  • 引用机制

语法和名称:

  • 可以有一个印记后空间
  • 你可以给潜艇用符号引用的数字名称
  • 法律尾随逗号
  • 分组整数常量
  • 散片
  • 从阵列填充的散列的密钥

模块,语法和命令行选项:

  • 使用严格和使用警告
  • 错误检查
  • 密宗使用-n和-p的
  • CPAN
  • overload::constant
  • IO ::处理模块
  • 安全舱
  • 属性

变量:

  • 自动激活
  • $[变量
  • 领带
  • 动态作用域
  • 可变交换用一个语句

循环和流量控制:

  • 魔术转到
  • for在单个可变
  • 继续条款
  • 绝望模式

常用表达:

  • \G
  • (?{})和“(?? {})`中的正则表达式

其他特性:

  • 调试器
  • 特殊的代码块,如BEGIN,CHECK和END
  • DATA
  • 新的块操作
  • 源过滤器
  • 信号鱼钩
  • 地图 ( 两次 )
  • 包装内置功能
  • eof函数
  • dbmopen功能
  • 谈到警告变为错误

其他的技巧,以及元的答案:

  • 猫文件,解压缩的gzip如果需要的话
  • Perl的提示

也可以看看:

  • 的C隐藏功能
  • C#的隐藏功能
  • 的C隐藏功能++
  • Java的隐藏功能
  • 的JavaScript的隐藏功能
  • 红宝石的隐藏功能
  • PHP的隐藏功能
  • Python中的隐藏功能
  • Clojure中的隐藏功能

Answer 1:

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

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

运行perldoc perlop和搜索“触发器”的详细信息和示例。



Answer 2:

有在Perl许多非显而易见的特征。

例如,你可知道,可以有印记后的空间?

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

或者说,如果你使用的符号引用你可以给潜艇数字名称?

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

另外还有“布尔”准运营商,真正表达和假空字符串,返回1:

$ 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/


Answer 3:

添加通过神奇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与“广州”或“.Z”结尾的文件:

while (<>) {
    print;
}


Answer 4:

一个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,

保罗



Answer 5:

运营商++和一元 - 不仅在数字工作,但也对字符串。

my $_ = "a"
print -$_

打印-a

print ++$_

打印b

$_ = 'z'
print ++$_

打印AA



Answer 6:

像Perl从其他列表中几乎所有的“深奥”的部分,我会告诉你一件事是Perl不能:

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

万一这一点不明确你什么功能Perl提供了,这里的也许不是完全明显条目的选择列表:

达夫设备 - 在Perl

便携性和Standardness - 有Perl的可能更多的计算机比用C语言编译器

一个文件/路径操作类 - 文件::上更加操作系统查找作品比不净

对于空格分隔列表行情 和字符串 - Perl的允许您选择适合您的列表和字符串分隔符几乎任意引号

Aliasable命名空间 - Perl有这些通过水珠分配:

*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的实现,在自动加载功能

符号引用 -你是很好的建议远离这些东西拿走。 他们会吃你的孩子。 但当然,Perl的允许你提供你的孩子嗜血的恶魔。

一号线价值交换 - Perl的允许列表赋值

能力用自己的功能,即使更换核心功能

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

要么

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

unlink($_) for @ARGV


Answer 7:

自动激活 。 AFAIK 没有其他语言都有它



Answer 8:

这很简单引述几乎任何一种在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.);

引用机制:

问:文字报价; 只需要转义字符为结束字符。 QQ:一种解释报价; 处理变量和转义字符。 伟大的,你需要引用字符串:

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

QX:工程就像QQ,但然后执行它作为一个系统命令,非交互方式。 返回从标准输出生成的所有文本。 (重定向,如果支持的OS,也出来),还与反引号完成(在'字符)。

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 //。



Answer 9:

没有真正隐藏的,但许多每天Perl程序员不知道CPAN 。 这尤其适用于人谁不是全职程序员还是不要用Perl全日制课程。



Answer 10:

该“为”语句可以使用相同的方式“与” Pascal的使用:

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

您可以申请小号///操作等相同的变量的序列,而无需重复变量名。

注意:上面的非间断空间(NBSP)已隐藏的Unicode在它规避降价。 不要复制粘贴:)



Answer 11:

该quoteword运营商是我最喜欢的事情之一。 相比:

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的最低估的特点之一。



Answer 12:

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

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

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


Answer 13:

新的块操作

我想说,扩大语言的能力,建立伪块业务就是其中之一。

  1. 您声明原型指示,它需要一个代码参考第一子:

     sub do_stuff_with_a_hash (&\%) { my ( $block_of_code, $hash_ref ) = @_; while ( my ( $k, $v ) = each %$hash_ref ) { $block_of_code->( $k, $v ); } } 
  2. 然后,您可以调用它的身体像这样

     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只想扫描两个“变量”和常数,创建它们并根据需要替换它们。

同样,源过滤器可能是肮脏的,但强大的。 但是,他们可以搞起来的调试可怕的东西 - 甚至警告可以用错误的行号打印出来。 我停止使用达米安的开关 ,因为调试程序将失去所有的能力告诉我,我真的是。 但我发现,你可以最大限度地减少通过修改的一小段代码,让他们在同一行的损坏。

信号鱼钩

这往往做得不够,但不是所有的明显。 下面是小猪的老后卫的芯片处理器。

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

您可以检查某种类型的文字中包含你的模块封装。 例如,如果你在使用这个import子:

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

这将意味着每一个大于2十亿在调用封装整数将得到改变,以一个Math::BigInt对象。 (参见过载::恒定 )。

分组整数常量

虽然我们在这。 Perl的允许你大量分解成三个数字组,仍然把它弄出来一个可分析的整数。 注意2_000_000_000上述2十亿。



Answer 14:

二进制“X”是重复操作符 :

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

它还可以与列表:

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


Answer 15:

错误检查。 随着检查已启用污点,Perl会死(或警告,以-t ),如果你尝试通过被污染数据(粗略地讲,在程序外部数据),以不安全的功能(打开文件,运行一个外部命令等) 。 写setuid的脚本或CGI程序或任何在脚本比喂养它的数据的人更大的权限时,这是非常有帮助的。

魔术跳转。 goto &sub确实优化的尾部呼叫。

调试器。

use strictuse warnings 。 这些可以从一堆错别字救你。



Answer 16:

基于在路上"-n""-p"开关在Perl 5中实现,你可以写一个看似不正确的程序,包括}{

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

其内部转换为以下代码:

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


Answer 17:

让我们先从容易的飞船操作 。

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


Answer 18:

这是一元的答案,但Perl的提示档案包含各种可以用Perl做有趣的把戏。 前尖端的存档的在线浏览,并且可以经由邮件列表或原子饲料进行订阅。

一些我喜欢的技巧包括与PAR生成可执行文件 , 使用autodie自动抛出异常 ,以及使用的开关和智能匹配的Perl 5.10的结构。

披露:我是作家和Perl提示的维护者之一,所以我显然认为非常高他们。 ;)



Answer 19:

地图 -不仅因为它使一个人的代码更有表现力,而是因为它给了我一个冲动,读多一点关于这个“函数式编程”。



Answer 20:

上环的继续子句。 它会在每个循环的底部被执行,甚至那些被next'ed。

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

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

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


Answer 21:

我的投票会去的(?{})和(?? {})在Perl的正则表达式组。 第一执行Perl代码,忽略返回值时,第二执行代码,用返回值作为正则表达式。



Answer 22:

while(/\G(\b\w*\b)/g) {
     print "$1\n";
}

所述\ G变锚。 它太热



Answer 23:

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

  • 如果您使用的? 作为分隔符,它只匹配一次,除非你叫reset
  • 如果使用'作为分隔符的模式没有插值。
  • 如果模式是空的,它使用上一次成功匹配的模式。


Answer 24:

空文件句柄钻石操作 <>有它的建设命令行工具的地方。 它的作用类似于<FH>到从手柄读,除了它神奇地选择取其首次发现:命令行的文件名或STDIN。 从perlop得到措施:

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


Answer 25:

特殊的代码块 ,如BEGINCHECKEND 。 他们来自awk中,但在Perl的工作方式不同,因为它不记录为主。

BEGIN块可以被用于指定解析阶段一些代码; 当你这样做的语法和变量检查它也是执行perl -c 。 例如,要在配置变量加载:

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


Answer 26:

rename("$_.part", $_) for "data.txt";

重命名data.txt.part到data.txt中,而不必重复自己。



Answer 27:

有点晦涩是波浪,波浪线“经营者”,迫使标量上下文。

print ~~ localtime;

是相同的

print scalar localtime;

并从不同

print localtime;


Answer 28:

领带,可变捆扎接口。



Answer 29:

Perl的闭环控制结构的“绝望模式”,这使他们查找堆栈找到匹配的标签,允许一些奇怪的行为,其测试::更多需要的优势,是好还是坏。

SKIP: {
    skip() if $something;

    print "Never printed";
}

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

还有的鲜为人知.pmc文件。 “使用富”将寻找Foo.pmc在@INC Foo.pm.前 这是为了允许编译的字节代码首先被加载,但是模块::编译利用这一点来缓存源过滤模块更快的加载时间和更容易调试。

把警告变为错误的能力。

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

这就是我能想到的关闭还没有被提到我的头顶。



Answer 30:

该goatse操作*

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

要么

sub foo {
    return @_;
}

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

它的工作原理,因为在标量上下文列表分配产生被分配在列表中元素的个数。

*请注意,不是一个真正的运营商



文章来源: Hidden features of Perl?