20

私はRubyジェネレーターとPythonジェネレーター(Rubyで知られているEnumerators)の類似点/相違点を調査してきましたが、私が知る限り、それらはほぼ同等です。

ただし、私が気付いた違いの1つは、Pythonジェネレーターはclose()メソッドをサポートしているのに対し、Rubyジェネレーターはサポートしていないことです。Pythonのドキュメントから、このclose()メソッドは次のことを行うと言われています。

ジェネレーター関数が一時停止されたポイントでGeneratorExitを発生させます。その後、ジェネレーター関数がStopIteration(正常に終了するか、すでに閉じられているため)またはGeneratorExit(例外をキャッチしないことにより)を発生させた場合、closeは呼び出し元に戻ります。」

RubyがこのメソッドEnumeratorsをサポートしない正当な理由はありますか?close()それとも偶然の脱落ですか?

また、RubyはメソッドをEnumeratorsサポートしているが、 rewind()Pythonジェネレーターはサポートしていないことも発見しました...これにも理由がありますか?

ありがとう

4

3 に答える 3

7

巻き戻し方法に関するこのドキュメントは、詳細が少し不足しています。ただし、「最初からやり直す」には、ジェネレーターは次の2つのいずれかを実行する必要があります。

  • 完全な出力を覚えて、巻き戻されたらその出力を繰り返してから、前に行っていたことを再開します
  • 他の望ましくない副作用なしに同じ出力が繰り返されるように、内部状態をリセットします

これらの2番目は常に可能であるとは限りません。たとえば、ジェネレータがネットワークからバイトバッファを出力する場合、出力は完全に内部状態の関数ではありません。ただし、最初の手法を使用するジェネレーターは、使用時にメモリ内にますます大きなバッファーを構築する必要があります。このようなジェネレーターは、リストよりもパフォーマンス上の利点がほとんどありません。

したがって、Rubyrewindメソッドはオプションである必要があり、具象列挙子クラスによって常にサポートされるとは限らないと結論付けます。したがって、Python設計者がリスコフの置換原則を重視する場合、すべてのジェネレーターでそのようなメソッドを必要としないようになります。

于 2012-06-28T18:02:02.360 に答える
2

ジェネレーターはスタック ベースであり、Ruby の列挙子は多くの場合、(インタープリター レベルで) 特殊化されており、スタック ベースではありません。

于 2010-09-26T01:25:24.167 に答える
1

Ruby の Enumerator は内部で StopIteration クラスを使用します。Ruby 1.9.1 で Enumerators はどのように機能しますか?を参照してください。

( for each 呼び出しで使用すると、ラップされるだけです)。だから私は彼らがかなり近いと思います。そうは言っても、列挙子の close メソッドが何をすべきか、正確にはわかりません...おそらくクリーンアップですか?(Python のジェネレーターはおそらく巻き戻しの恩恵を受けるでしょう。Ruby では巻き戻しに応答しない列挙子があるため、そのメソッドを呼び出すと例外が発生することに注意してください)。

于 2010-09-29T19:49:55.353 に答える