143

役立つ作業を行うために実際に採用できた、Perl の非常に便利だが難解な言語機能は何ですか?

ガイドライン:

  • CPANではなくPerlコアへの回答を制限するようにしてください
  • 例と簡単な説明を教えてください

他の言語の隠し機能にも見られる隠し機能:

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

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

その他の隠し機能:

オペレーター:

構造の引用:

構文と名前:

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

変数:

ループとフロー制御:

正規表現:

その他の機能:

その他のトリックとメタ回答:


関連項目:

4

78 に答える 78

54

フリップフロップ演算子は、フラグ変数を使用せずに、ファイル ハンドルによって返されたレコード (通常は行) をループするときに最初の反復をスキップするのに役立ちます。

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

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

于 2008-10-02T12:41:44.920 に答える
47

Perl には多くの非自明な機能があります。

たとえば、シジルの後にスペースがあることをご存知ですか?

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

または、シンボリック参照を使用する場合、サブに数値名を付けることができますか?

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

"bool" 疑似演算子もあり、真の式の場合は 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/
于 2008-10-02T12:50:58.907 に答える
46

マジック 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;

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

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

while (<>) {
    print;
}
于 2008-10-02T17:23:05.117 に答える
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$c0

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

これらは省略形でも使用でき、デフォルトを提供するのに非常に役立ちます。

$x ||= 0; # $x が false の場合、値は 0 になりました。

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

チェリオ、

ポール

于 2008-10-02T13:23:29.577 に答える
39

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

my $_ = "a"
print -$_

プリント-a

print ++$_

プリントb

$_ = 'z'
print ++$_

プリントaa

于 2008-10-02T12:26:31.867 に答える
36

Perl には、他のリストの「難解な」部分がほとんどすべて含まれているため、Perl にできないことを 1 つお伝えします。

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

Perl が提供する機能がよくわからなかった場合に備えて、完全にはわかりにくいエントリの選択的なリストを以下に示します。

ダフのデバイス- Perl

移植性と標準性- C コンパイラよりも Perl を使用するコンピュータの方が多い可能性があります。

ファイル/パス操作クラス- File::Find は .Net よりもさらに多くのオペレーティング システムで動作します

空白で区切られたリスト と文字列の引用符- Perl では、リストと文字列の区切り文字にほぼ任意の引用符を選択できます

エイリアス可能な名前空間- Perl は、glob 割り当てを通じてこれらを持っています:

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

静的初期化子BEGIN- Perl は、 (コード解析) から (コード解析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
于 2008-10-02T13:27:11.487 に答える
35

自動活性化。私の知る限り、他の言語にはありません

于 2008-10-02T13:48:56.880 に答える
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//も表示される場合があります。

于 2008-10-02T16:43:04.557 に答える
27

「for」ステートメントは、Pascal で「with」と同じように使用できます。

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

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

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

于 2008-10-02T17:11:11.650 に答える
27

隠されているわけではありませんが、多くの Perl プログラマーは毎日CPANについて知りません。これは特に、フルタイムのプログラマーではない人や、フルタイムで Perl でプログラミングをしていない人に当てはまります。

于 2008-10-02T17:25:18.247 に答える
26

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

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

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

ノイズがはるかに少なく、目に優しい。Perlのもう1つの非常に優れた点は、SQLを作成するときに本当に見逃していることですが、末尾のコンマが有効であるということです。

print 1, 2, 3, ;

これは奇妙に見えますが、コードを別の方法でインデントした場合はそうではありません。

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

関数呼び出しに引数を追加する場合、前の行または末尾の行にコンマをいじる必要はありません。単一の線の変更は、周囲の線に影響を与えません。

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

于 2008-10-02T16:54:51.003 に答える
26

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

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

__DATA__
some good data
some bad data
more good data 
more good data 
于 2008-10-02T17:57:38.670 に答える
24

New Block Operations

I'd say the ability to expand the language, creating pseudo block operations is one.

  1. You declare the prototype for a sub indicating that it takes a code reference first:

    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. You can then call it in the body like so

    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 is another semi-hidden gem.) Notice how you don't need the sub keyword in front of the block, or the comma before the hash. It ends up looking a lot like: map { } @list

Source Filters

Also, there are source filters. Where Perl will pass you the code so you can manipulate it. Both this, and the block operations, are pretty much don't-try-this-at-home type of things.

I have done some neat things with source filters, for example like creating a very simple language to check the time, allowing short Perl one-liners for some decision making:

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

Lib::TL would just scan for both the "variables" and the constants, create them and substitute them as needed.

Again, source filters can be messy, but are powerful. But they can mess debuggers up something terrible--and even warnings can be printed with the wrong line numbers. I stopped using Damian's Switch because the debugger would lose all ability to tell me where I really was. But I've found that you can minimize the damage by modifying small sections of code, keeping them on the same line.

Signal Hooks

It's often enough done, but it's not all that obvious. Here's a die handler that piggy backs on the old one.

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

That means whenever some other module in the code wants to die, they gotta come to you (unless someone else does a destructive overwrite on $SIG{__DIE__}). And you can be notified that somebody things something is an error.

Of course, for enough things you can just use an END { } block, if all you want to do is clean up.

overload::constant

You can inspect literals of a certain type in packages that include your module. For example, if you use this in your import sub:

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

it will mean that every integer greater than 2 billion in the calling packages will get changed to a Math::BigInt object. (See overload::constant).

Grouped Integer Literals

While we're at it. Perl allows you to break up large numbers into groups of three digits and still get a parsable integer out of it. Note 2_000_000_000 above for 2 billion.

于 2008-10-02T14:31:18.243 に答える
24

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

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

デバッガー。

use strictおよびuse warnings。これらは、多くのタイプミスからあなたを救うことができます。

于 2008-10-02T17:00:49.243 に答える
24

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

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

リストでも機能します。

print for (1, 4, 9) x 3; # print 149149149
于 2008-10-02T12:45:51.430 に答える
22

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

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

内部的に次のコードに変換されます。

LINE: while (defined($_ = <ARGV>)) {
    print $_; }{ print "$. Files";
}
于 2008-10-02T12:48:32.377 に答える
18

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

于 2008-10-03T15:04:33.620 に答える
18

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

私のお気に入りのヒントには、PAR使用した実行可能ファイルのビルド、autodie を使用した例外の自動スロー、Perl 5.10でのswitchおよびsmart-match構造の使用が含まれます。

開示:私は Perl のヒントの作成者でありメンテナーの 1 人であるため、明らかにそれらを非常に高く評価しています。;)

于 2008-10-02T13:30:52.413 に答える
18

Spaceship Operatorから簡単に始めましょう。

$a = 5 <=> 7;  # $a is set to -1
$a = 7 <=> 5;  # $a is set to 1
$a = 6 <=> 6;  # $a is set to 0
于 2008-10-02T12:09:33.030 に答える
15

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

于 2008-10-02T12:19:21.633 に答える
15

ループの 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";
}
于 2008-10-04T02:29:35.123 に答える
13
while(/\G(\b\w*\b)/g) {
     print "$1\n";
}

\Gアンカー。暑いです。

于 2008-10-02T14:25:00.380 に答える
13

m//演算子には、あいまいな特殊なケースがいくつかあります。

  • 区切り文字として使用する?と、 を呼び出さない限り、一度だけ一致しますreset
  • '区切り文字として使用すると、パターンは補間されません。
  • パターンが空の場合、最後に成功した一致のパターンが使用されます。
于 2008-10-02T13:25:59.167 に答える
12

null ファイルハンドルのひし形演算子 <>は、コマンド ライン ツールの作成に適しています。<FH>最初に見つかった方 (コマンド ライン ファイル名または STDIN) を魔法のように選択することを除いて、ハンドルから読み取るように動作します。perlop から取得:

while (<>) {
...         # code for each line
}
于 2008-10-02T13:06:18.650 に答える
11
rename("$_.part", $_) for "data.txt";

自分自身を繰り返さなくても、data.txt.part を data.txt に名前変更します。

于 2008-10-02T17:12:40.680 に答える
11

BEGINCHECKおよびなどの特殊なコード ブロックEND。これらは Awk に由来しますが、Perl ではレコードベースではないため、動作が異なります。

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

BEGIN {
    eval {
        require 'config.local.pl';
    };
    if ($@) {
        require 'config.default.pl';
    }
}
于 2008-10-02T13:16:24.493 に答える
10

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

print ~~ localtime;

と同じです

print scalar localtime;

とは異なる

print localtime;
于 2008-10-02T12:42:14.277 に答える
9

入力レコード区切り文字は、固定長レコードを読み取るための数値への参照に設定できます。

$/ = \3; print $_,"\n" while <>; # output three chars on each line
于 2009-06-22T12:39:06.350 に答える
9

一致するラベルを見つけるためにスタックをルックアップする Perl のループ制御構造の「自暴自棄モード」は、Test::More が良くも悪くも利用するいくつかの奇妙な動作を可能にします。

SKIP: {
    skip() if $something;

    print "Never printed";
}

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

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

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

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

それは、言及されていない頭のてっぺんから考えることができるものです。

于 2008-10-15T15:13:09.137 に答える
9

ヤギのオペレーター*

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

また

sub foo {
    return @_;
}

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

スカラーコンテキストでのリスト代入は、代入されるリスト内の要素の数を生成するため、機能します。

*実際にはオペレーターではないことに注意してください

于 2009-05-31T03:13:52.790 に答える
9

変数を結ぶインターフェースであるtie。

于 2008-10-03T21:15:27.940 に答える
7

@{[...]} を使用して、複雑な perl 式の補間結果を取得できます

$a = 3;
$b = 4;

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

プリント:3 * 4 = 12

于 2009-05-31T02:39:22.660 に答える
7

それがどれほど難解かはわかりませんが、私のお気に入りの 1 つはハッシュ スライスです。ありとあらゆるものに使っています。たとえば、2 つのハッシュをマージするには:

私の %number_for = (1 => 1、2 => 2、3 => 3);
my %your_numbers = (2 => 2, 4 => 4, 6 => 6);
@number_for{keys %your_numbers} = 値 %your_numbers;
ソート値を出力 %number_for; #12346
于 2008-10-03T21:09:09.013 に答える
7

これは特に有用ではありませんが、非常に難解です。Perlパーサーを掘り下げているときに、これに出くわしました。

POD が登場する前は、perl4 には man ページを nroff として直接プログラムに埋め込んで、失われないようにするトリックがありました。perl4 は、 wrapmanというプログラムを使用して(詳細については、Pink Camel の 319 ページを参照してください)、巧妙に nroff の man ページをスクリプトに埋め込みました。

nroff にすべてのコードを無視するように指示し、Perl にコードの処理を停止するように指示するENDタグの後に man ページの肉を配置することで機能しました。次のように見えました。

#!/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 コンテキストの定数は警告を生成します。op.c特定の roff コマンドで始まる無効なコンテキスト文字列を許可する特別な例外があります。

              /* 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';

0さらに、数値定数とには例外があり1、裸の.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警告します!

于 2009-02-09T23:00:07.557 に答える
6
sub load_file
{
    local(@ARGV, $/) = shift;
    <>;
}

必要に応じて配列を返すバージョン:

sub load_file
{
    local @ARGV = shift;
    local $/ = wantarray? $/: undef;
    <>;
}
于 2008-10-02T17:15:17.523 に答える
5

$[ 配列が開始するインデックスを決定する変数もあります。デフォルトは 0 なので、配列は 0 から始まります。

$[=1;

本当に望むなら、 Perl をAWK (または Fortran)のように振る舞わせることができます。

于 2008-10-02T12:21:46.230 に答える
5

($x, $y) = ($y, $x) が Perl を学びたいと思ったきっかけです。

リスト コンストラクター 1..99 または 'a'..'zz' も非常に便利です。

于 2008-10-15T17:22:31.870 に答える
5

@Schwern は、ローカライズすることで警告をエラーに変えると述べました$SIG{__WARN__}。これを (レキシカルに) で行うこともできますuse warnings FATAL => "all";。を参照してくださいperldoc lexwarn

その点については、Perl 5.12 以降perldoc foo、完全なperldoc perlfoo. ついに!:)

于 2010-08-19T23:05:10.487 に答える
4

文字列またはリストを他のリストに条件付きで追加するための便利な複合演算子の1つは、次のx!!演算子です。

 print 'the meaning of ', join ' ' =>  
     'life,'                x!! $self->alive,
     'the universe,'        x!! ($location ~~ Universe),
     ('and', 'everything.') x!! 42; # this is added as a list

この演算子を使用すると、次のような逆構文が可能になります。

 do_something() if test();
于 2009-10-31T08:49:34.737 に答える
4

左辺値を使用して、コードを本当に混乱させます。

my $foo = undef ;
sub bar:lvalue{ return $foo ;}

# Then later

bar = 5 ;
print bar ;
于 2008-11-19T15:58:50.260 に答える
4

コアIO::Handleモジュール。私にとって最も重要なことは、ファイルハンドルの自動フラッシュを許可することです。例:

use IO::Handle;    
$log->autoflush(1);
于 2008-10-02T19:53:54.227 に答える
4

このワンライナーは、glob を使用して、指定された長さ (4) の単語のアルファベット (A、T、C、および G -> DNA) のすべての単語の組み合わせを生成する方法を示しています。

perl -MData::Dumper -e '@CONV = glob( "{A,T,C,G}" x 4 ); print Dumper( \@CONV )'
于 2011-06-05T16:43:19.027 に答える
4

使用能力はどうですか

my @symbols = map { +{ 'key' => $_ } } @things;

配列から hashref の配列を生成するには -- hashref の前の + はブロックを明確にするので、インタプリタはそれがコードブロックではなく hashref であることを認識します。素晴らしい。

(前回のトロント パールモンガーズ ミーティングでこれを説明してくれた Dave Doyle に感謝します。)

于 2008-10-03T16:43:33.107 に答える
4

わかった。ここに別のものがあります。動的スコープ。別の投稿で少し話題になっていましたが、隠れた機能についてはここでは見当たりませんでした。

Autovivification のような動的スコーピングは、それを使用する言語の数が非常に限られています。Perl と Common Lisp は、Dynamic Sc​​oping を使用していることを私が知っている唯一の 2 つです。

于 2008-10-05T15:12:40.870 に答える
4

安全なコンパートメント。

Safe モジュールを使用すると、perl だけを使用して独自のサンドボックス スタイルの環境を構築できます。その後、Perl スクリプトをサンドボックスにロードできます。

よろしくお願いします、

于 2008-10-02T18:03:06.753 に答える
3

Quantum::Superpositions

use Quantum::Superpositions;

if ($x == any($a, $b, $c)) { ...  }
于 2009-07-09T18:29:22.713 に答える
3

プログラムの構文エラーをチェックするためのより強力な方法があります。

perl -w -MO=Lint,no-context myscript.pl

それが実行できる最も重要なことは、「存在しないサブルーチン」エラーを報告することです。

于 2010-04-13T10:33:13.140 に答える
3

パーティーには非常に遅れていますが、属性です。

基本的に、属性を使用すると、変数またはサブルーチンの宣言に関連付ける任意のコードを定義できます。これらを使用する最良の方法は、Attribute::Handlersを使用することです。これにより、属性を簡単に定義できます (他の属性に関しては!)。

これらを使用してプラグ可能なクラスとそのプラグインを宣言的にアセンブルする方法について、YAPC::2006 でオンラインのこちらでプレゼンテーションを行いました。これはかなりユニークな機能です。

于 2008-11-21T20:27:52.090 に答える
3

私が気に入っている Perl の隠れた機能はeof関数です。これは、コマンドラインでロードされた複数のファイル間で perldoc -f eofファイル名と(現在の行番号)を簡単にリセットするためにそれを使用する方法を示しています。$.

while (<>) {
  print "$ARGV:$.\t$_";
} 
continue {
  close ARGV if eof
}
于 2008-10-10T02:11:14.207 に答える
3

use re debug
再デバッグの使用に関するドキュメント

perl -MO=Concise[,OPTIONS]
簡潔なドキュメント

非常に柔軟で表現力があり、C、Pascal、Python、およびその他の言語のスタイルでのプログラミングに適していることに加えて、Perl をアルゴリズム、正規表現、または迅速な問題の最初のカヌーリング用の「goto」言語にするいくつかのプラグマ コマンド スイッチがあります。解決する必要があります。これら 2 つは Perl に固有のものであり、私のお気に入りの 1 つです。

use re debug: 正規表現の最近のフレーバーのほとんどは、現在の形式と機能を Perl に負っています。他の言語で表現できない Perl 形式の正規表現は多数ありますが、Perl で表現できない他の言語の正規表現の形式はほとんどありません。さらに、Perl には素晴らしい正規表現デバッガーが組み込まれており、正規表現エンジンがどのように正規表現を解釈し、ターゲット文字列と照合しているかを表示します。

例: 最近、単純な CSV ルーチンを作成しようとしていました。(はい、はい、私は知っています、私はText::CSV...を使用していたはずです) しかし、CSV 値は引用符で囲まれておらず、単純ではありませんでした。

私の最初の試みは/^(^(?:(.*?),){$i}/、n 個の CSV レコードから i レコードを抽出することでした。それはうまくいきます - 最後のレコードまたは n の n を除いて。デバッガなしでそれを見ることができました。

次に試してみ/^(?:(.*?),|$){$i}/ました これはうまくいきませんでした。理由はすぐにはわかりませんでした。(.*?)コンマまたはEOLが続くと言っていると思いました。use re debug次に、小さなテスト スクリプトの先頭に追加しました。ああ、そうです、間の変更は,|$そのように解釈されていませんでした。((.*?),) | ($)それは私が望んでいたものではないと解釈されていました。

新しいグループ化が必要でした。ということで作業にたどり着きました/^(?:(.*?)(?:,|$)){$i}/。正規表現デバッガーを使用しているときに、文字列の末尾に向かって一致するのに何回のループが必要であるかに驚きました。これは.*?非常にあいまいな用語であり、満足するには過度のバックトラックが必要です。だから私は試しました/^(?:(?:^|,)([^,]*)){$i}/これは2つのことをします:1)コンマ以外のすべての貪欲な一致のためにバックトラッキングを減らします2)正規表現オプティマイザーが最初のフィールドで一度だけ変更を使用できるようにしました。ベンチマークを使用すると、これは最初の正規表現よりも 35% 高速です。正規表現デバッガーは素晴らしく、ほとんど使用していません。

perl -MO=Concise[,OPTIONS]: B および Concise フレームワークは、Perl が傑作をどのように解釈しているかを確認するための優れたツールです。を使用する-MO=Conciseと、Perl インタープリターによるソース コードの翻訳結果が出力されます。Concise には多くのオプションがあり、B では、OP コードの独自のプレゼンテーションを作成できます。

この投稿のように、Concise を使用してさまざまなコード構造を比較できます。ソース行は、それらの行が生成する OP コードとインターリーブできます。見てみな。

于 2010-04-16T20:08:08.943 に答える
3

正規表現と文字列の区切り記号は、他のものに置き換えることができます。これは、以下に例示する「つまようじ傾き症候群」に特に役立ちます。

$url =~ /http:\/\/www\.stackoverflow\.com\//;

区切り文字を変更することで、ほとんどのバックワッキングを排除できます。 /bar/m/bar/と同じm!bar!です。

$url =~ m!http://www\.stackoverflow\.com/!;

{} や [] などのバランス区切り文字を使用することもできます。私は個人的にこれらが大好きです。 q{foo}と同じ'foo'です。

$code = q{
    if( this is awesome ) {
        print "Look ma, no escaping!";
    }
};

友達 (およびシンタックス ハイライター) を混乱させるには、次のようにします。

$string = qq'You owe me $1,000 dollars!';
于 2008-10-28T12:48:30.290 に答える
3

HEREDOCS で異なる引用符を使用して、異なる動作を得ることができます。

my $interpolation = "We will interpolated variables";
print <<"END";
With double quotes, $interpolation, just like normal HEREDOCS.
END

print <<'END';
With single quotes, the variable $foo will *not* be interpolated.
(You have probably seen this in other languages.)
END

## this is the fun and "hidden" one
my $shell_output = <<`END`;
echo With backticks, these commands will be executed in shell.
echo The output is returned.
ls | wc -l
END

print "shell output: $shell_output\n";
于 2010-05-26T14:10:53.300 に答える
2

ループ内で見られるフィルターとしてハッシュを使用する機能。私はまだ別の言語でこれほど素晴らしいものを見たことがありません。たとえば、Pythonでこれを複製することはできませんでした。

たとえば、これまでに見たことがない行を印刷したいと思います。

my %seen;

for (<LINE>) {
  print $_ unless $seen{$_}++;
}
于 2010-05-26T10:35:01.773 に答える
2

私が一番気に入っている機能はステートメント修飾子です。

何回やりたかったかわかりません:

say 'This will output' if 1;
say 'This will not output' unless 1;
say 'Will say this 3 times. The first Time: '.$_ for 1..3;

他の言語で。等...

「etc」は、別の 5.12 機能である Yada Yada オペレーターを思い出させました。

これは、プレースホルダーが必要な場合に最適です。

sub something_really_important_to_implement_later {
    ...
} 

確認してください: Yada Yada Operator の Perl Docs

于 2011-04-12T03:33:03.423 に答える
2

Axeman は、いくつかの組み込み関数を簡単にラップできることを思い出させてくれました。

Perl 5.10 より前の Perl には、Python のようなきれいな印刷 (たとえば) がありませんでした。

したがって、ローカル プログラムでは、次のようなことができます。

sub print {
     print @_, "\n";
}

またはデバッグを追加します。

sub print {
    exists $ENV{DEVELOPER} ?
    print Dumper(@_) :
    print @_;
}
于 2008-10-02T15:04:15.637 に答える
2

うまく連携する 2 つのこと: コア内文字列の IO ハンドルと、関数プロトタイプを使用して、grep/map のような構文で独自の関数を記述できるようにすること。

sub with_output_to_string(&) {           # allows compiler to accept "yoursub {}" syntax.
  my $function = shift;
  my $string   = '';
  my $handle   = IO::Handle->new();
  open($handle, '>', \$string) || die $!; # IO handle on a plain scalar string ref
  my $old_handle = select $handle;
  eval { $function->() };
  select $old_handle;
  die $@ if $@;
  return $string;
}

my $greeting = with_output_to_string {
  print "Hello, world!";
};

print $greeting, "\n";
于 2010-05-26T08:44:19.653 に答える
2

以下は「~~」と同じくらい短いですが、何が返されるかを示しており、スマートマッチ演算子と混同しないため、より意味があります:

print "".localtime;   # Request a string

print 0+@array;       # Request a number
于 2009-06-29T17:15:51.400 に答える
2

コマンドラインの新しい -E オプション:

> perl -e "say 'hello"" # does not work 

String found where operator expected at -e line 1, near "say 'hello'"
        (Do you need to predeclare say?)
syntax error at -e line 1, near "say 'hello'"
Execution of -e aborted due to compilation errors.

> perl -E "say 'hello'" 
hello
于 2010-05-26T11:28:35.297 に答える
2

たとえば、文字列内の関数呼び出しを展開できます。

print my $foo = "foo @{[scalar(localtime)]} bar";

foo 水曜日 5 月 26 日 15:50:30 2010 バー

于 2010-05-26T13:50:09.310 に答える
1

私はパーティーに少し遅れていますが、組み込みのタイドハッシュ関数に投票するdbmopen()ことは私を大いに助けてくれました。これは正確にはデータベースではありませんが、データをディスクに保存する必要がある場合は、多くの問題とJustWorksを取り除きます。データベースがなく、Storable.pmを理解していなかったときに、それは私が始めるのに役立ちましたが、テキストファイルの読み取りと書き込みを超えて進歩したいと思っていました。

于 2008-10-11T23:07:37.183 に答える
1

メモリを節約するためにこれを行うことができると思うかもしれません:

@is_month{qw(jan feb mar apr may jun jul aug sep oct nov dec)} = undef;

print "It's a month" if exists $is_month{lc $mon};

しかし、それはしません。Perl は依然として各キーに異なるスカラー値を割り当てます。 Devel::Peekはこれを示しています。 PVHVハッシュです。 Eltはキーで、SVそれに続く はその値です。各 SV には、共有されていないことを示す異なるメモリ アドレスがあることに注意してください。

Dump \%is_month, 12;

SV = RV(0x81c1bc) at 0x81c1b0
  REFCNT = 1
  FLAGS = (TEMP,ROK)
  RV = 0x812480
  SV = PVHV(0x80917c) at 0x812480
    REFCNT = 2
    FLAGS = (SHAREKEYS)
    ARRAY = 0x206f20  (0:8, 1:4, 2:4)
    hash quality = 101.2%
    KEYS = 12
    FILL = 8
    MAX = 15
    RITER = -1
    EITER = 0x0
    Elt "feb" HASH = 0xeb0d8580
    SV = NULL(0x0) at 0x804b40
      REFCNT = 1
      FLAGS = ()
    Elt "may" HASH = 0xf2290c53
    SV = NULL(0x0) at 0x812420
      REFCNT = 1
      FLAGS = ()

undef スカラーは整数スカラーと同じくらい多くのメモリを必要とするため、それらをすべて 1 に割り当てて、 でチェックするのを忘れるという罠を避けるように頼むかもしれませんexists

my %is_month = map { $_ => 1 } qw(jan feb mar apr may jun jul aug sep oct nov dec);

print "It's a month" if $is_month{lc $mon});
于 2009-02-13T18:57:47.223 に答える
1

defined &DB::DBプログラムがデバッガー内から実行されている場合、式は true を返します。

于 2009-10-10T18:37:15.843 に答える
1

次にオタクのパーティーに参加するときは、bash シェルでこのワンライナーを引き出してください。そうすれば、女性があなたに群がり、友達があなたを崇拝するでしょう。

探す 。-name "*.txt"|xargs perl -pi -e 's/1:(\S+)/uc($1)/ge'

すべての *.txt ファイルを処理し、perl の正規表現を使用してインプレース検索と置換を行います。これは、'1:' の後のテキストを大文字に変換し、'1:' を削除します。Perl の 'e' 修飾子を使用して、検索/置換正規表現の 2 番目の部分を実行可能コードとして扱います。インスタント 1 行テンプレート システム。xargs を使用すると、bash のコマンド ラインの長さ制限に達することなく、膨大な数のファイルを処理できます。

于 2010-05-26T10:01:12.637 に答える
1

ハッシュ (キーは一意) を使用して、リストの一意の要素を取得します。

my %unique = map { $_ => 1 } @list;
my @unique = keys %unique;
于 2009-11-19T12:21:56.950 に答える
1

一致する正規表現の補間。これの便利なアプリケーションは、ブラックリストで照合する場合です。補間を使用しない場合、次のように記述されます。

#detecting blacklist words in the current line
/foo|bar|baz/;

代わりに書くことができます

@blacklistWords = ("foo", "bar", "baz");
$anyOfBlacklist = join "|", (@blacklistWords);
/$anyOfBlacklist/;

これはより冗長ですが、データファイルからの移入が可能です。また、何らかの理由でリストがソースで維持されている場合、RegExp よりも配列を維持する方が簡単です。

于 2009-11-05T16:21:50.237 に答える
1

unpack() および pack() 関数用に 1 つ追加します。これは、他のプログラムで使用される形式でデータをインポートおよび/またはエクスポートする必要がある場合に最適です。

もちろん、最近ではほとんどのプログラムでデータを XML でエクスポートできます。また、一般的に使用される独自のドキュメント形式の多くには、その形式用に作成された Perl モジュールが関連付けられています。しかし、これは必要なときに信じられないほど便利な機能の 1 つであり、pack()/unpack() はおそらく、人々が非常に多くの独自データ形式用の CPAN モジュールを作成できる理由です。

于 2010-01-25T22:51:46.463 に答える
0

"今"

sub _now { 
        my ($now) = localtime() =~ /([:\d]{8})/;
        return $now;
}

print _now(), "\n"; #  15:10:33
于 2010-09-06T17:25:31.913 に答える
0

@Corion - Perl のベア URL? もちろん、補間された文字列でも可能です。それが問題になるのは、実際に正規表現として使用していた文字列内だけです。

于 2008-10-02T19:48:08.403 に答える
0

同じ行に印刷してスクリプトの進行状況を表示します。

$| = 1; # flush the buffer on the next output 

for $i(1..100) {
    print "Progress $i %\r"
}
于 2008-10-03T10:25:16.017 に答える
0

B::Deparse - Perl コードを生成するための Perl コンパイラ バックエンド. 毎日の Perl コーディングで使用するものではありませんが、特別な状況では役立つ可能性があります。

難読化されたコードや複雑な式に遭遇した場合は、 に渡しますDeparse。ゴルフされているJAPHまたはPerlコードを把握するのに役立ちます。

$ perl -e '$"=$,;*{;qq{@{[(A..Z)[qq[0020191411140003]=~m[..]g]]}}}=*_=sub{print/::(.*)/};$\=$/;q<Just another Perl Hacker>->();'
Just another Perl Hacker

$ perl -MO=Deparse -e '$"=$,;*{;qq{@{[(A..Z)[qq[0020191411140003]=~m[..]g]]}}}=*_=sub{print/::(.*)/};$\=$/;q<Just another Perl Hacker>->();'
$" = $,;
*{"@{[('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')['0020191411140003' =~ /../g]];}";} = *_ = sub {
    print /::(.*)/;
}
;
$\ = $/;
'Just another Perl Hacker'->();
-e syntax OK

より便利な例は、 deparse を使用して、別のモジュールから受け取った可能性のある coderef の背後にあるコードを見つけることです。

use B::Deparse;
my $deparse = B::Deparse->new;
$code = $deparse->coderef2text($coderef);
print $code;
于 2012-01-12T21:06:48.403 に答える
0

Perl は柔軟な awk/sed として優れています。

たとえば、次のls | xargs statように素朴に行われる の単純な置換を使用できます。

$ ls | perl -pe 'print "stat "' | sh 

入力 (ファイル名) にスペースやシェルの特殊文字 ( |$\. そのため、Perl の出力では一重引用符が必要になることがよくあります。

コマンド ライン経由で perl を呼び出す場合の複雑な問題の 1 つ-neは、シェルが最初にワンライナーでニブルを取得することです。これはしばしば、それを満足させるために苦痛な脱出につながります。

私がいつも使用している「隠れた」機能の 1 つ\x27は、シェル エスケープを使用する代わりに単一引用符を含めることです。'\''

そう:

$ ls | perl -nle 'chomp; print "stat '\''$_'\''"' | sh

より安全に書くことができます:

$ ls | perl -pe 's/(.*)/stat \x27$1\x27/' | sh

そのように引用されていても、ファイル名に変な文字が含まれているとうまくいきません。しかし、これは:

$ ls | perl -pe 's/\n/\0/' | xargs -0 stat
于 2010-05-26T09:54:13.967 に答える
0

もう1つ...

Perl キャッシュ:

my $processed_input = $records || process_inputs($records_file);

Elpeleg オープン ソース、Perl CMS http://www.web-app.net/

于 2009-01-26T07:36:20.793 に答える
0

redoまたは他の制御語を含むベア ブロックを使用して、カスタム ループ構造を作成します。

->can('print')最初のメソッドを返すオブジェクトのリンクされたリストをトラバースします。

sub get_printer {
    my $self = shift;
    {$self->can('print') or $self = $self->next and redo}
}
于 2010-01-14T06:50:33.017 に答える