Perlの隠された機能?


143

有用な作業を行うために実際に使用できた、Perlの本当に便利ですが難解な言語機能は何ですか?

ガイドライン:

  • CPANではなく、Perlコアへの回答を制限してください
  • 例と短い説明を入力してください

他の言語の隠し機能にもある隠し機能:

(これらはすべてCorionの回答からです)

  • C
    • ダフのデバイス
    • 移植性と標準性
  • C#
    • 空白で区切られたリストと文字列の引用
    • エイリアス可能な名前空間
  • ジャワ
    • 静的イニシャライザ
  • JavaScript
    • 機能はファーストクラスの市民です
    • ブロックのスコープと閉鎖
    • 変数を介して間接的にメソッドとアクセサーを呼び出す
  • ルビー
    • コードによるメソッドの定義
  • PHP
    • 広範なオンラインドキュメント
    • 魔法の方法
    • シンボリックリファレンス
  • パイソン
    • 1行の値の交換
    • コア機能でも独自の機能に置き換える機能

その他の隠し機能:

演算子:

引用構文:

構文と名前:

モジュール、プラグマ、およびコマンドラインオプション:

変数:

ループとフロー制御:

正規表現:

その他の機能:

その他のトリック、およびメタ答え:


関連項目:


これらの機能のほとんどは日常的に使用されており、一部はほとんどのPerlスクリプトで発生し、「その他」の下にリストされているほとんどは依然として他の言語に由来し、これらの「非表示」を呼び出すと質問の意図が変わります。
reinierpost

回答:


54

フリップフロップ演算子は、フラグ変数を使用せずに、ファイルハンドルから返されたレコード(通常は行)をループするときに最初の反復をスキップする場合に便利です。

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

perldoc perlop詳細と例については、「フリップフロップ」を実行して検索してください。


実際には、これはawkから取られたもので、pattern1、pattern2を書き込むことで2つのパターン間でフリップフロップを実行できます
Bruno De Fraine

15
明確にするために、これの「隠された」側面は、スカラー '..'のいずれかのオペランドが定数の場合、値が暗黙的に入力行番号($。)と比較されることです
Michael Carman

47

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にするなど)。

これらの多くは実際にはどこかで文書化されているか、文書化された機能から論理的にフォローされていますが、それでもあまり知られていないものもあります。

更新:もう1ついいもの。q{...}引用構文の下で言及されましたが、区切り文字として文字を使用できることをご存知ですか?

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

同様に、正規表現を書くことができます:

m xabcx
# same as m/abc/

2
「印章の後にスペースができることを知っていますか?」私は完全にうろたえています。ワオ。
アリストテレス・パガルツィス2008年

1
涼しい!!! $ undef_varは警告を作成しません。
Axeman

4
文字列を区切るために文字を使用する例は、「Jet another perl hacker」ではなく「Just another perl hacker」であると思います= P
Chris Lutz

最悪の部分は、区切り文字として他のものも使用できることです。閉じ括弧も。以下は有効です:s} regex} replacement} xsmg; q]文字列リテラル];
ライアンC.トンプソン

46

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;

(シェルのメタ文字を含むファイル名を処理するために必要な$ _の前後の引用符)

この<>機能は@ARGV、「。gz」または「.Z」で終わるすべてのファイルを解凍します。

while (<>) {
    print;
}

2
|交換でエスケープする必要はないと思います。
Chris Lutz、

私はこれをじっと見つめていますが、どのように機能するのかわかりません。どの時点でzcat |、パイプを通過するコマンドとして解析されますか?
Ether

1
@Ether =>パイプの検出は、2つの引数openの機能であり、ダイヤモンドオペレーターが各ファイルを開くときに使用します@ARGV
Eric Strom

40

Perlの私のお気に入りの機能の1つは、ブール||演算子を使用して一連の選択肢から選択することです。

 $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; #$ xがfalseの場合、値は0になります。

$ x // = 0; #$ xが未定義の場合、値はゼロになります。

チェリオ、

ポール


4
これは非常に一般的なイディオムであり、「隠された」機能と見なすことはほとんどできません。
マイケルカーマン、

3
かなりのプリンターが//はコメントであると考える恥:)
John Ferguson

2
質問、これらの新しい演算子を使用するための「使用機能」はありますか、それともデフォルトで有効になっていますか?私はまだPerl 5.10の機能に傾いています。
JJ

6
//デフォルトではそこにあり、特別な調整は必要ありません。また、dor-patchを使用して5.8.xにバックポートすることもできます... CPANミラーのauthors / id / H / HM / HMBRAND /ディレクトリを参照してください。FreeBSD 6.x以降では、perlパッケージでこれを行います。
ランド:2008年

2
|| または// do {}と組み合わせて、より複雑な割り当てをカプセル化できます。つまり、$ x = $ a || {私の$ z; 3行または4行の派生。$ z};
RET

39

演算子++と単項-は、数値だけでなく文字列でも機能します。

my $_ = "a"
print -$_

プリント-a

print ++$_

プリントb

$_ = 'z'
print ++$_

プリントAA


3
perlvarを引用するには:「自動減分演算子は魔法ではありません。」したがって--、文字列では機能しません。
moritz 2008年

「aa」は「z」に続く自然の要素ではないようです。次に高いASCII値である「{」を期待します。
エーテル

4
「z」の後に来るものをプログラマーに尋ねないでください。人間に聞いてください。この機能は、長いリストの項目に番号を付けるのに最適です。
バリーブラウン

17
Perlを初めて使用するとき、私はこの機能をz to aaの正確な動作で自分で実装し、それを笑わせた同僚に見せ、私に「何かを見せて」と言いました。私は少し泣きましたが、何かを学びました。
コパス2009年

2
@Ether-必要に応じて、数字を使用して、でASCIIに自動変換しますord()。または、小さなクラスを作成し、演算子をオーバーロードして実行します。
Chris Lutz、

36

Perlは他のリストのほとんどすべての「難解な」部分を持っているので、Perlができないことの1つを説明します。

//演算子は正規表現に使用されるため、Perlができないことの1つは、コードに任意のURLを含めることです。

Perlが提供する機能があなたに明らかでない場合に備えて、完全に明らかではない可能性があるエントリの選択リストを次に示します。

ダフのデバイス - Perlで

移植性とStandardness - CコンパイラよりもPerlで複数のコンピュータは、おそらくあります

ファイル/パスの操作クラス - ネットよりもさらに多くのオペレーティングシステム上のファイル::検索作品

空白区切りのリスト株価 や文字列は - Perlは、あなたのリストと文字列の区切り文字にはほとんど任意の引用符を選択することができます

エイリアス可能な名前空間-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" };

Pervasive online documentation - Perlのドキュメントはオンラインであり、おそらくシステムにもあります

「存在しない」関数を呼び出すたびに呼び出されるマジックメソッド -PerlはAUTOLOAD関数にそれを実装します

シンボリック参照 -これらに近づかないようにしてください。彼らはあなたの子供を食べます。しかし、もちろん、Perlを使用すると、血に飢えた悪魔に子供を提供できます。

1行の値スワッピング -Perlはリストの割り当てを許可します

コア機能でも独自の機能に置き換える機能

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

または

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

unlink($_) for @ARGV

私は他の言語と比較してPerlのドキュメントのファンですが、それでもRegexesとリファレンスについては、かなり合理化できると思います。たとえば、正規表現の最適な入門書はPerlreではなくPerlop
John Ferguson

9
「Perlができないことの1つは、//演算子が正規表現に使用されるため、コードに任意のURLを含めることです。」-これはまったくナンセンスです。

あなたの洞察に感謝します。ソースフィルターを使用せずに、Perlコードでベアhttp:// ... URLを作成するいくつかの方法を調べましたが、方法が見つかりませんでした。// 5.8.xまでのPerlバージョンの正規表現に使用されます。5.10では、定義済みまたは割り当て用に再利用されます。
Corion

8
なぜ/どこであなたのコードに裸のURL が欲しいのですか?例は思いつきません。
漂流者

18
誰もそれを望んでいないでしょう、それは単なるJavaミームです。「foo.com」はラベルhttp:で、コメントの「foo.com」です。一部の人々はこれが面白いと思う...彼らはばかげている。
jrockway

35

Autovivification。私の知る限り、他の言語にはありません


Pythonなどがこれをサポートしていないことを私は知りませんでした。
skiphoppy 2008年

@davidnicol:本当に?リンクを提供してもらえますか?グーグルでの私のクイック検索は何も返しませんでした。ECMAscriptがJavascriptの正しい名前であることを知らない人のために。en.wikipedia.org/wiki/ECMAScript
JJ

1
そして、
自動生存

1
@Gregg Lind-最初に変数を割り当てるたびにPythonが変数を自動的に作成することを考えると、autovivificationは1つのタイプミスから巨大な問題を作成します。
クリス・ルッツ

3
@tchrist-a = [[xrange(1,11)のyのx * y] xrange(1,11)のxの場合]
方位

31

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と同じように機能しますが、システムコマンドとして非対話的に実行します。標準出力から生成されたすべてのテキストを返します。(リダイレクションは、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 //が表示されることもあります。


1
私は時々qw ""を使用して、構文ハイライターが正しく強調表示するようにします。
Brad Gilbert、

SlickEditで動作します。:)
Robert P

1
@fengshaun、私は一般的に使用編集者が行う正しくこれらを強調表示します。StackOverflowの構文ハイライターを部分的に参照しました。
Brad Gilbert

@Bradギルバート:スタックオーバーフローができない(まあ、(ない)、パースのPerl diddlyスクワット価値☹。
tchrist

my $moreout = qx{type "$path" 2>&1};...そんなことができるなんて知らなかった![TM]
ドランド、

27

実際には隠されていませんが、Perlプログラマーの多くはCPANについて知りません。これは特に、フルタイムのプログラマーではないか、Perlでフルタイムでプログラミングしていない人に当てはまります。


27

「for」ステートメントは、「with」がPascalで使用されるのと同じ方法で使用できます。

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

変数名を繰り返すことなく、一連のs ///操作などを同じ変数に適用できます。

注:上の改行しないスペース(&nbsp;)には、Markdownを回避するためにUnicodeが隠されています。コピーして貼り付けないでください:)


「map」も同じトリックを実行します... map {....} $ item; 「マップ」ではなく「for」を使用する利点の1つは、nextを使用して分割できることです。
draegtun 2008年

2
また、操作対象のアイテムがコードの操作前にリストされているため、読みやすくなります。
Robert P

@RobertP:その通りです。トポラライザーは談話に役立ちます。
tchrist '11 / 11/10

26

quoteword演算子は、私のお気に入りの1つです。比較:

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

そして

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

ノイズがはるかに少なく、目に優しい。SQLを書くときに本当に見逃しがちなPerlのもう1つの本当に良い点は、末尾のコンマが正当であることです。

print 1, 2, 3, ;

奇妙に見えますが、コードを別の方法でインデントすると、そうではありません。

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

関数呼び出しに引数を追加しても、前または後の行でカンマをいじる必要はありません。単一行の変更は、周囲の行に影響を与えません。

これにより、可変個の関数を操作することが非常に快適になります。これはおそらくPerlの最も過小評価されている機能の1つです。


2
Perlの構文の興味深いコーナーケースは、次が有効であることです。$ _ qw(もののリスト){...}
ephemient

1
*?などの特殊文字を使用しない限り、単語の引用にglob構文を悪用することもできます。だからあなたは書くことができますfor (<a list of stuff>) { ... }
moritz 08年

1
@ephemient:ほぼ。これはレキシカルでのみ機能します:私の$ x qw(abc){...}の場合:$ _ qw(abc){print}の場合#何も出力されません
dland

Perlのお気に入りのデフォルトを楽しむことができるのに、なぜその余分な語彙を追加するのですか for(qw / abcd /){print; }
fengshaun

2
@ ephemient、@ fengshaun、@ moritz、@ dland:これはbleadで「修正」されてます。このp5pスレッドを参照してください。
tchrist '11 / 11/11

26

DATAブロックに直接貼り付けられたデータを解析する機能。プログラムなどで開くテストファイルに保存する必要はありません。例えば:

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

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

そして、小さなテストで非常に役立ちます!
fengshaun

@peter mortensen複数のブロックをどのように持つでしょうか?そして、どのようにブロックを終了しますか?
ヒキガエル

@Toad:それはアランの答えです(改訂リストを参照)。そのユーザーに対処することをお勧めします。または、そのユーザーがStack Overflowを離れたので、特に誰も対処していない可能性があります(したがって、実際のP​​erl専門家が後でそれを修正できます)。
Peter Mortensen、

3
@ハイ:いいえ、それは醜いというわけではありません—実際、醜いの正反対です。それは、クリーンで洗練された、ミニマルで美しいものです。一言で言えば、それは素晴らしいことであり、それを持たない言語はPITAです。@peter mortensen、@ toad:同じプログラムで複数のデータブロックを使用する方法に対する1つの答えは、CPANのInline :: Filesモジュールを使用することです。
tchrist '11 / 11/11

Inline :: Filesは、ソースフィルターを使用して実装されます。ありますデータ::セクション複数のインラインブロックを提供し、ソース・フィルターを使用していません。
Prakash K

24

新しいブロック操作

言語を拡張する機能、疑似ブロック操作を作成する機能は1つだと思います。

  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もう1つの半隠された宝石です。)subブロックの前のキーワード、またはハッシュの前のコンマが必要ないことに注意してください。最終的には次のようになります。map { } @list

ソースフィルター

また、ソースフィルターもあります。あなたがそれを操作できるようにPerlがあなたにコードを渡す場所。これとブロック操作の両方は、ほとんどの場合、自宅でこれを試してはいけません。

たとえば、時間をチェックするための非常に単純な言語を作成して、いくつかの意思決定のために短いPerlの1行を許可するなど、ソースフィルターでいくつかのきちんとしたことを行いました。

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

Lib::TL 「変数」と定数の両方をスキャンし、それらを作成して、必要に応じて置き換えるだけです。

繰り返しになりますが、ソースフィルターは乱雑になる可能性がありますが、強力です。しかし、それらはデバッガをひどいものに混乱させる可能性があります-さらに、警告が間違った行番号で出力される可能性があります。Damian's 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

モジュールを含むパッケージ内の特定のタイプのリテラルを検査できます。たとえば、これをimportサブで使用する場合:

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

これは、呼び出しパッケージの20億を超える整数がすべてMath::BigIntオブジェクトに変更されることを意味します。(overload :: constantを参照してください)。

グループ化された整数リテラル

その間、Perlを使用すると、大きな数値を3桁のグループに分割しても、解析可能な整数を取得できます。2_000_000_000上記の20億に注意してください。


5
$ SIG { DIE }ハンドラーを使用する場合は、$ ^ Sを調べて、プログラムが実際に停止しているかどうか、またはキャッチされる例外をスローしているかどうかを確認することを強くお勧めします。通常、あなたは後者に干渉したくないでしょう。
pjf 2008年

新しいブロックは非常に有益です!私はそれが言語の意味論だと思っていました!どうもありがとう。
ZeroCool

ソースフィルターの有益な使用法は、pdlのNiceSlice(pdl.perl.org/?docs=NiceSlice&title=PDL::NiceSlice)であるため->slice、スライスが必要になるたびにメソッドとしてを使用する必要はありません。
Joel Berger、

24

バイナリ "x"は繰り返し演算子です:

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

リストでも機能します:

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

これが、Perlがハッカーに非常に人気がある理由の1つです。perl -e 'print 0x000 x 25';
JJ

4
これの私のお気に入りの使用法は、SQL INSERTステートメントの最後の部分のプレースホルダーを生成することです:@p =( '?')x $ n; $ p = join( "、"、@p); $ sql = "INSERT ... VALUES($ p)";
skiphoppy 2008年

24

汚染チェック。汚染チェックを有効に-tすると、汚染されたデータ(大まかに言えば、プログラムの外部からのデータ)を安全でない関数(ファイルを開く、外部コマンドを実行するなど)に渡そうとすると、perlは停止します(またはで警告します)。これは、setuidスクリプトやCGI、またはスクリプトがデータをフィードする人よりも大きな権限を持つスクリプトを作成するときに非常に役立ちます。

魔法の後藤。 goto &sub最適化された末尾呼び出しを行います。

デバッガ。

use strictuse warnings。これらは、タイプミスの束からあなたを救うことができます。


1
他の言語にこの機能がないのはなぜですか?この機能を使用することで、perl Webスクリプトが1桁安全になります。
マシューロック

22

"-n"および"-p"スイッチがPerl 5に実装されている方法に基づいて、以下を含む一見間違っているプログラムを作成できます}{

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

これは内部的にこのコードに変換されます:

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

@マーティンクレイトン:それはなぜそれと呼ばれているのですか?
tchrist '11 / 11/10

@tchrist-それはおそらく、2人が鼻をこするように見えるからです。プロフィールで、あなたが私が何を意味するかを見れば。
マーティンクレイトン、

18

宇宙船オペレーターから簡単に始めましょう。

$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
@レオン:C / C ++は、数値に対して3値を返しません。メモリが機能する場合、文字列comapre関数は、STL言語全体で知っている唯一の3つの値の戻り値です。AFAIK Pythonには、3戻りの数値比較はありません。Javaには、番号固有の3リターン比較もありません。
JJ

7
誰もが知っているわけではないので、-1 / 0/1比較演算子の便利な点に言及する価値があります。それらをor演算子と一緒にチェーンして、primary / secondary / etcを実行できます。並べ替え。だから、($a->lname cmp $b->lname) || ($a->fname cmp $b->fname)彼らの最後の名前で人をソートしますが、2人が同じ姓を持っているならば、彼らは彼らの最初の名前で注文することになります。
ホブ、

@JJ Pythonには3つの値の比較があります:cmp()>>> print(cmp(5,7)、cmp(6,6)、cmp(7,5))(
1、0、1

18

これはメタアンサーですが、Perlヒントアーカイブには、Perlで実行できるあらゆる種類の興味深いトリックが含まれています。以前のヒントのアーカイブは閲覧用にオンラインであり、メーリングリストまたはAtomフィードを介して購読できます。

私のお気に入りのヒントには、PAR使用して実行可能ファイルを構築することオートダイを使用して自動的例外をスローすること、Perl 5.10でスイッチスマートマッチコンストラクトを使用することが含まれます。

開示:私はPerl Tipsの作成者およびメンテナーの1人なので、明らかに非常に高く評価しています。;)


2
これはおそらく、最も優れたドキュメント言語の1つであり、ドキュメントを検索するためのツールのパターンを設定します。この質問のリストはおそらく他の言語ほど必要ではありません。
Axeman

1
オートダイはとても素敵に見えます。
j_random_hacker 2010

18

マップ -コードをより表現力豊かにするだけでなく、この「関数型プログラミング」についてもう少し読む衝動を与えたからです。


15

ループの継続句。次のループであっても、すべてのループの最後で実行されます。

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

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

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

15

私の投票は、Perlの正規表現の(?{})グループと(?? {})グループに行きます。1つ目は戻り値を無視してPerlコードを実行し、2つ目は戻り値を正規表現として使用してコードを実行します。


perlは、他のプログラムが元の正規表現言語の代わりにpcre(perl互換正規表現)を頻繁に使用するほど多くの正規表現拡張機能を発明しました。

ここで少し宣伝文読むperldoc.perl.org/... :-D
JJ

Perlは、(私が知る限り)正規表現に関しては、パックをリードしています。
Brad Gilbert、

これは、私が知る限り、まだ実験段階であり、将来のPerlでは同じように機能しない可能性があります。これが役に立たないことは言うまでもありませんが、s ///コマンドの/ eフラグで少し安全で使用可能なバージョンを見つけることができます:s/(pattern)/reverse($1);/ge;#はすべてを逆にしますpatterns
Chris Lutz、

@Chris Lutz、@ Leon Timmerman:これらの2つの構成要素は現在再入可能であることに注意してください。また、2番目のものは、再帰的なパターンを実行するために使用する必要がなくなったことにも注意してください。キャプチャグループを再帰的に処理できるようになりました。@Brad Gilbert:PCREは私たちを追跡するのにまともな仕事をしていますが、そうです。Perlが完全に挑戦されていない正規表現の卓越性の1つの領域は、Unicodeプロパティへのアクセスです。私のunitrio分布を参照してくださいuninamesunicharsと、特にuniprops私が何を意味するかのほんの一部を見ること。
tchrist '11 / 11/10

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

\ Gアンカー。それはだ熱いです


3
...そしてそれは前の試合の終わりの位置を示します。
Dave Sherohman、2008年

1
ただし、スカラーコンテキストで正規表現を呼び出す必要があります。
davidnicol 2008年

@davidnicol:上記のコードは機能します。どういう意味かわかりますか?
JJ

13

m//オペレータは、いくつかのあいまいな特殊なケースがあります。

  • ?区切り文字として使用する場合、を呼び出さない限り、1回だけ一致しますreset
  • '区切り文字として使用する場合、パターンは補間されません。
  • パターンが空の場合、最後に一致したパターンが使用されます。

2
これらは、隠された機能というよりは隠された落とし穴のようなものです!私はそれらを好きな人を知りません。しばらく前にp5pのスレッドで、推定m / $ foo / rフラグの有用性について説明しました。/rは、一重引用符のことを誰も覚えていないため、補間がないことを意味します(文字は重要ではありません)。
ランド:2008年

2
@dland:同意。私はこれらの隠されたミス機能を呼び出し、製品コードで使用することはありません。
マイケルカーマン、

7
Perlプログラマーが、単一引用符が補間を意味しないことを覚えている(または推測する)ことができないとは想像できません。このセマンティクスでの使用法は、言語ではほぼ普遍的であり、これがそうであると期待しています...
sundar-モニカを復活させる'10

そして、パターンが空で、最後に成功した一致が/ o修飾子を使用してコンパイルされた場合、それ以降はそのパターンでスタックします。
davidnicol 2008年

1
空のパターンの動作は廃止されたと思います。主に、m / $ foo /のようなパターンは、$ fooが空の場合に厄介なバグになるためです。
マシューS

12

nullファイルハンドルのひし形演算子 <>は、コマンドラインツールの構築に使用されます。<FH>ハンドルから読み取るように動作しますが、最初に見つかったコマンドラインファイル名またはSTDINのいずれかを魔法のように選択します。perlopから取得:

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

4
また、使用してのUNIXセマンティクスを、次の「 - 」あなたが行うことができるように標準入力から読み込む」を意味する。perl myscript.pl file1.txt - file2.txtと、perlは最初のファイルを処理し、その後、標準入力、2番目のファイル。
ライアンC.トンプソン

次のことができ、独自のオブジェクト上のオペレータ()イテレータのように動作するように。ただし、リストのコンテキストでは期待どおりに機能しません。overload<><$var>
ドルメン

11

特別なコードブロックのようなBEGINCHECKEND。それらはAwkからのものですが、Perlではレコードベースではないため、動作が異なります。

このBEGINブロックを使用して、解析フェーズのコードを指定できます。syntax-and-variable-checkを実行したときにも実行されますperl -c。たとえば、構成変数を読み込むには:

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

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

自分で繰り返すことなく、data.txt.partをdata.txtに名前変更します。


10

少しあいまいなのは、スカラーコンテキストを強制するチルダ-チルダ「演算子」です。

print ~~ localtime;

と同じです

print scalar localtime;

とは異なります

print localtime;

5
perl5.10.0は "スマートマッチオペレーター"も導入しているため、これは特にあいまいです。これは~~、正規表現のマッチングを実行したり、配列にアイテムが含まれているかどうかを調べたりすることができるためです。
moritz 2008年

それは不明瞭ではなく、難読化されています(そしてゴルフとJAPHに役立ちます)。
マイケルカーマン、

これは正しくありません!~~は参照に対して安全ではありません!それらを文字列化します。
Leon Timmermans、

はい、そうです。文字列化は、スカラーコンテキストに強制されると参照に何が起こるかです。それはどのようにして「~~はスカラーコンテキストを強制する」のを間違っているのでしょうか?
Dave Sherohman、2008年

3
@Nomad Dervish:スカラーコンテキスト/ =文字列化。たとえば、「$ n = @a」はスカラーコンテキストです。"$ s = qq '@ a'"は文字列化です。参照に関して、「$ ref1 = $ ref2」はスカラーコンテキストですが、文字列化しません。
マイケルカーマン、


9

一致するラベルを見つけるためにスタックを調べさせるPerlのループ制御構造の「必死モード」は、Test :: Moreが好むまたは好まない、いくつかの奇妙な動作を可能にします。

SKIP: {
    skip() if $something;

    print "Never printed";
}

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

ほとんど知られていない.pmcファイルがあります。「use Foo」は、Foo.pmの前に@INCでFoo.pmcを探します。これは、コンパイルされたバイトコードを最初にロードできるようにすることを目的としていましたが、Module :: Compileはこれを利用して、ソースのフィルタリングされたモジュールをキャッシュし、ロード時間を短縮してデバッグを容易にします。

警告をエラーに変換する機能。

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

これについては、言及されていない頭上から考えることができます。


9

山羊演算子*

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

または

sub foo {
    return @_;
}

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

これは、スカラーコンテキストでのリスト割り当てにより、割り当てられているリスト内の要素の数が得られるため機能します。

* 注、実際には演算子ではありません


それは、これまでで最も(よく、少なくとも)美しい「オペレーター」です。
Chris Lutz、
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.