2012-03-20 5 views
17

perldocsは、以下が約last言う:Perl:grepやマップを終了するのに「最後に」使わないのはなぜですか?

lastようeval {}sub {}、又はdo {}として値を返すブロックを終了するために使用することができない、および(grepのを終了するために使用すべきではない)、または地図()操作です。

それは のgrep()または マップに避けなければならないのはなぜ

()?私は特に地図に興味があります。なぜなら、これはforeach構造の代わりです。ドキュメントは、結果を説明せずに何かをしないことを主張するようです。

+3

mapはリストを別のリストに変換するので、各マップ呼び出しは要素を返さなければなりません。 – perreal

+0

perl v5を使って 'last'で' map'を終了しようとすると 'Can not"というエラーが出ます。 WinXPで14.1 – TLP

+0

@TLP:そして、それは、少なくともPerlのv5.10.1以降のケースとなっています。私は、この「すべきではない」言語は、それはいくつかの奇妙な行動を起こしていなければならないのPerlのいくつかの以前のバージョンからのホールドオーバーであることを推測しています。 – ruakh

答えて

8

まず、ifがあるだけのように、grepmapnextlastredoに透明であることを認識しています。

$ perl -e' 
    print "A"; 
    for (8,9) { 
     print "B"; 
     print map { print "C"; next; print "D"; $_ } 1,2,3; 
     print "E"; 
    } 
    print "F\n"; 
' 
ABCBCF 

しかし、ドキュメントはlastmapを終了するために使用することはできません言っていない、それは使用してはならないと言います。それが何を意味するのかははっきりしない。

  • は、彼らがmapgrepに影響を与える考え、それらを使用しないでください?
  • 読者がmapgrepに影響していると思うかもしれないので、そのように使用しないでください。
  • Perlを厄介な状態にする可能性があるので、そのように使用しないでください。
  • 将来的に動作が変わる可能性があるため、そのように使用しないでください。

わかりません。

私はmapまたはgrepコールバックを残すためにnextlastredoを使用して、任意の悪い副作用を知らないので、それは#3だとは思いません。

ループ構成を使用してmapgrepを残しておかしくないことは、同じ方法でサブを残しても警告しません。

$ perl -wE'while (1) { map { last; } 1; }' 

$ perl -wE'while (1) { sub { last; }->(); }' 
Exiting subroutine via last at -e line 1. 
+2

'map'や' grep'の暗黙のループを終了するために 'last'(そして' next')を使用すべきではないという意図は確かです。特にファイルレベルの 'last'は不正ですが、' print "A";プリントマップ{プリント "B";最終; print "C";} 1,2,3; "Z"を出力; '' AB''だけを出力するので、プログラム全体が終了します。一番下の行は、 'map'はあるリストから別のリストへ*マッピング*を提供し、OPは' foreach'の代わりに**が**ではないということです。 – Borodin

+0

@Borodin、Reは "実際に包含ブロックを出るので"、考えられる*解釈の1つです*私が言及しました。実際には、ドキュメントが実際に言う*ことではなく、正しい解釈でなければならないあなたの主張を裏付ける証拠は絶対にありません。 "特に注意してください"と書かれていますが、なぜドキュメンテーションは '最後の'を使って 'if'の「then」ブロックを終了しないのですか?また、「包含ブロック」を終了します。あなたは単にそれが明らかであることを明示して意図が明白ではないという私の主張を反駁しています。私は感銘を受けていません。あなたのコメントのポイントは何でしたか? – ikegami

+4

あなたは攻撃性と過敏性に取り組む必要があります。私が言ったのは、私がドキュメンテーションの意図を確信しているということでした。はい、あなたの選択肢の1つでした。私はドキュメンテーションの意味が明らかかどうかについてはコメントしなかった。私は全くあなたに同意していませんでした。落ち着いてください。 – Borodin

7

mapは他へマッピングつのリストのためのものです。確かにではなく、foreachの代替品です。私はあまりにも多くの場合、その副作用のためmapを使用し、結果のリストを捨てるの罪を犯し

map { print "$_\n" } @data; 

のようなものを見てきました。あなたは使用を考慮しません

my $x = 99; 
sqrt(my $y = $x * $x); 
print $y; 

あなたは警告が表示されます。同じ理由で、forを意味するときにはmapを使用しないでください。実用的な理由のために

は、

AB 

print "A"; 
print map { print "B"; last; print "C";} 1,2,3; 
print "Z"; 

OUTPUTはので、この場合にはlastは全体のプログラムを終了を検討してください。一般に、mapまたはgrepブロック内にlastまたはnextを使用すると、ブロックがある場合はブロックを含むが終了します。これは回避する必要があるため、"last ... grep()またはmap()操作を終了するために使用しないでください"

+0

私は別のforeachリストジェネレータを意味しました。* [docs](http://perldoc.perl.org/functions/map.html)*は '%hash = map {foo($ _)=> $ _ } @array; 'は%hash =()の代わりです。 foreach(@array){$ hash {foo($ _)} = $ _; } ' – vol7ron

+0

void文脈で' map'を使うと捨てる "文字列"はありませんので、最初の引数には致命的な欠陥があります。 – ikegami

+2

2番目の引数にも同じような欠陥があります。人はいつも 'func(my $ y = EXPR)'を行います: 'chomp(my $ x = <>);' 'utf8 :: decode(my $ decoded = $ encoded);'これはvoid文脈で 'map'のために言うことができる以上です! – ikegami

2

Perlでは、for/foreach,grepおよびmapの間にかなりの量の機能が重複しています。しかし、ちょうどあなた潜在的に同じ問題を解決するためにそれらをすべて使用することができますので、彼らはその特定のジョブ(:ネイルを荒れ狂ったためにドライバを使用して参照)のためのすべての最良のツールだという意味ではありません。

  • grep:その目的は、リストをフィルタリングし、得られたサブセットを返すことです。
  • map:その目的はリストを変更し、結果として得られる修正リストを返すことです。
  • for/foreach:その目的はリストを反復して何かを行うことです。

さて、あなたはfor/foreachgrepmapのすべての使用を達成することができます。 grepmapは、基本的には特に一般的で有用なリスト処理(for/foreach)の特定の使用のために糖衣構文です。設計上、慣習やベストプラクティスによって、利便性と明快さを高めるために特定のものを交換します。それらのものの

一つは、grepmapが値を返すように意図されていることです。 void文脈でそれらを使用することは推奨されず、慣用的なPerlに違反すると考えられます。値を返さない場合は、for/foreachを使用します。値を返すと、lastはそのプロセスに割り込む。

Perlのベストプラクティスに従っている場合、grepmapの使用は常に値を返します。つまり、lastを使用することは避けてください。

+0

+1。私はPerlが公式ベストプラクティス*を持っているかどうかはわかりませんが、Damian Conwayはそうしていると信じています:)ほとんどのプログラミング言語で彼の意見のほとんどは一般に受け入れられています。しかし、注意してください。彼は個人的な好みであることを伝えずに、いくつかの個人的な好みの点を挿入している。 – vol7ron

+0

Perlに**公式**ベストプラクティスがないかもしれませんが、これはDamian Conwayの本のベストプラクティスではありません。 "Perlのプログラミング"(http://shop.oreilly.com/product/9780596004927.do)の第4版と "[Perl]"の中のperldocs(オリジナルのポスターで引用されています)有効なPerlプログラミング](http://www.effectiveperlprogramming.com/)、第2版 "を参照してください。すべてのことを考えれば、Perlが公式のベストプラクティスに近づくほど近いと言えるでしょう。 ;-) –

+0

私は決して答えませんでしたが、皆さんはPerl COREへの貢献者であるか、お互いのプロジェクトで一緒に仕事をしていることがわかります。彼らはPerlコミュニティーのすべての尊敬されたメンバーであり、*ベストプラクティスと同じ非公式リストに影響を与えています。彼らがすべてO'Reillyによって出版されていることを理解してください。ちょうど1つまたは2つが同意し、必ずしもそれらをベスト*にするわけではありません。他の場所を見ると、いわゆる習慣のいくつかがバグを引き起こすことがわかります。それでも、TMTOWTDIから離れて、人気のあるスタイルとコンベンションを使用するのが最善です。 ---また、私はOPだったことに気付きました。 – vol7ron

関連する問題