2013-07-03 5 views
5

givenブロックの外側にあるwhenの文については、ドキュメントが疎であるようです。 whenは 'トピック'が設定されているときに使用できますが、正確にトピックが設定されていると判断されたときは使用できますか?これらのケースを考えてみます。Perl 5で 'when'文を使用できる条件は何ですか?

for (@arr) { 
    when { } 
} 

が、これはデフォルト、基本ケース、ですが、私は5.14.2私のperlの上でも、この作業を取得できなかったようだ - $ perl -Mfeature=switch -e 'foreach (qw(a b c)) { when (/a/) {print 'boom'} }'は何も出力しません。私は間違って何をしていますか?これは単なるバッシュ引用問題であることが判明しました。

for my $elem (@arr) { 
    when { } 
} 

これは機能しますか? whenが自動的に$ elemを使用してトピックになりますか?

for (@arr) { 
    $_ = some_expression($_); 
    when { } 
} 

これは機能しますか?ループ内でトピックを設定できますか?

また、上記の各コードセグメントでforの代わりにforeachを使用すると、違いはありますか?

基本的にはトピックのトピックが非常に不明なので、教えてください。

答えて

7

これはシェルコマンドの構築エラーです。

perl -Mfeature=switch -e 'foreach (qw(a b c)) { when (/a/) {print 'boom'} }' 

でなければなりません

perl -Mfeature=switch -e 'foreach (qw(a b c)) { when (/a/) {print '\''boom'\''} }' 

我々は

perl -Mfeature=switch -le'foreach (qw(a b c)) { when (/a/) {print "boom"} }' 

を簡素化するために二重引用符に切り替えることができ、我々はさらに

perl -E'for (qw(a b c)) { when (/a/) { say "boom" } }' 

キーワードforとを簡素化することができますはPerlと同じものです。

5.18がgivenwhenを実験として示していることに注意してください。それは消えませんが、変わります。私は何が起こっているのかをhereについて説明します。


いいえ、when$elemを使用していません。常に$_を使用します。


あなたがそう望む場合は、[はい、あなたはforまたはgivenの内側$_を変更することができます。 foreachループは訪問している要素にトピックのエイリアスを付けるので、一方を変更すると他方が変更されます。

+0

私は常に引用符で間違っている、ありがとう。 あなたの他の回答へのリンクをありがとう、そこからのリンクがステータスをより良く理解するのに役立ちました。 私は、これと一緒に奇妙なケースがあります: 'perl -E '@arr = qw(a b c); foreach $ x(@arr){$ _ = $ x; $ _ ++; (/ b /){print $ x}} '' ' これは、期待どおりに印刷されますが、「-e line 1でトピカルライザーの外では使用できません」というエラーで死んでしまうようです。 $ _で2行を削除すると、同じコードがエラーなく実行されますが(何も印刷されません)。ここで何が起こっているのか説明できますか? – sundar

+0

@sundar、問題は引用符の選択ではありません。問題は、あなたが正しくエスケープしなかったことです。更新を参照してください。 – ikegami

+0

このエスケープ構文は新しくて便利です。ありがとう。 トピック化に関して、その理由は、 "$ _で2つの行を削除すると、同じコードがエラーなく実行される"ということです。 for/foreachループは、たとえSOMETHING(...)のものであっても、トピカルライザーとして扱われるようですが、ループの中で$ _に代入すると何とかそれを取り除きます。 – sundar

2

池上はあなたの実際の問題を発見しました。

2つの局所化剤は、for/foreachおよびgivenである。 $_(トピック変数)を設定する他の構文は、トピック化ツールとはみなされません(例:mapまたはgrep)。

ループ変数を明示的に指定してforeach-loopを実行すると、そのループはトピック化ツールとはみなされません。したがって、

for my $x (1..3) { 
    local $_ = $x; 
    say when 2; 
} 

は、最初の反復のために働くだろうが、その後死ぬ(できない「とき」のtopicalizer外)whenいったん終了します。

givenは、$_をローカライズしていない点が異なりますが、字句は$_です。つまり、given (@a) { foo; }{ my $_ = \@a; foo; }と似ています(これは修正されている可能性があります)。

関連する問題