1

Rubyのファイバーを使用してREPLを作成しようとしています.1つのファイバーがフロントエンドとして機能し、入力を取得して出力を表示し、バックエンドとして1つのファイバーを使用して、フロントエンドからの入力を処理し、表示用の出力を返します。

(私がこれを行っているのは、漠然と REPL が必要なためでもあり、ファイバーを理解したかったからでもあり、これによりテストが可能になると考えたからでもあります。テスト フレームワークのフロントエンドを置き換えてバックエンドをテストするだけです。逆もまた同様です)。 .

問題は、Fibers ライブラリ全体を実際に使用する方法に関する適切なドキュメントが見つからず、最初の推測がうまくいかないことです。そこで、次の 4 つの質問があります。

  1. これは中途半端な考えですか?ファイバーから REPL を作成しようとすると、大きな問題が発生しますか?
  2. 両方の方法で値を渡す必要があるため、Fibers ライブラリなしでこれを行うことはできないと思います。そうですか?
  3. Ruby Fibres に関するまともな最初からのチュートリアルまたはドキュメントを教えてくれる人はいますか (単方向ジェネレーターのものではなく、ライブラリのように)
  4. 以下が機能しないのはなぜですか?を正しく表示しEnter a string:、入力を繰り返し受け入れます。しかし、入力行を提供するたびに、入力の最初の行が反転して表示されます (明確でない場合に備えて、サンプル出力が含まれています)。

コード:

require 'fiber'


# Simple REPL. Echo back the user's input, reversed, until they
# enter "pots" (resulting in "stop")
frontend = Fiber.new do |backend, output|
  while output != 'stop' do
    puts output
    print ": "
    input = gets
    output = backend.transfer(frontend, input)
  end
end

backend = Fiber.new do |frontend, input|
  loop do
    frontend.transfer(input.reverse)
  end
end

frontend.transfer(backend, "Enter a string:")

出力:

Enter a string:
: Hello

olleH
: World

olleH
:
4

1 に答える 1

1

答えは次のとおりです。

  1. これには繊維が間違っています。ファイバーは、協調的な同時実行を目的とした非常に高レベルの機能です。関数とブロックでカバーされる単純なユースケースにそれらを使用することは意味がありません。
  2. いいえ。メソッドのみを使用して記述された REPL を見てください。

    def repl(output, &backend)
      input = nil
      while output != "stop"
        puts output
        print ': '
        input = gets.chomp
        output = backend.call(input)
      end
    end
    repl("Enter a string: ") {|input| input.reverse}
    

    どの出力:

    Enter a string:                                                                                                                      
    : Hi                                                                                                                                 
    iH                                                                                                                                   
    : Hello                                                                                                                              
    olleH
    : Bork
    kroB
    

    完璧に動作します。

  3. Ruby 独自のドキュメント: http://ruby-doc.org/core-2.0.0/Fiber.html

  4. transferorを複数回呼び出すとresume、引数は初回のみファイバーのブロックに渡されます。transferしたがって、バッキングされたファイバーを呼び出すたびに、渡された最初の文字列が逆になっています。これが、ファイバーがこれを実装するのに適していない理由です。

于 2013-10-03T14:50:26.530 に答える