LoginSignup
1
1

More than 5 years have passed since last update.

[Ruby] Windows で 標準入力から EOF を受け取ったときの挙動に困っている話

Last updated at Posted at 2017-06-22

記述に誤りや見当違いな点がありましたら、ご指摘いただけますと幸いです。

はじめに

Windows で、複数行にわたる標準入力を受取りたいと思って書いた Ruby のコードが、予想外の動きをして困惑した話です。

次の環境で動かしました。

  • Windows XP Professional + Ruby 2.0.0-p648(USB Rumix 2)
  • Windows 8.1 Pro + Ruby 2.0.0-p648(USB Rumix 2)
  • Windows 10 + Ruby 2.3.3-p222(RubyInstaller)
  • Windows 10 + Ruby 2.4.1-p111(RubyInstaller2)

コンソール(とシェル?)の組合せは CKW-Mod + NYAOS です。

困ったこと

やろうとしたことは、コマンドラインから複数行の入力を受付け、直後にもう一度別の入力を受取るというもので、例えば次のようなコードです。

pry> p $stdin.readlines; p $stdin.gets

まず IO#readlines で改行をまたぐ入力を取得し、続けざまに IO#gets で一行入力を得ています。

実際に動かしている様子が次のアニメーションになります。
"fisrt line of #readlines"、 "second line of #readlines" の2行を入力後、 IO#readlines への入力を確定するために EOF(Ctrl + Z) を送っています。 すると Pry によって IO#readlines の戻り値がエコー出力され、引き続き IO#gets の入力待ちになります。ここで続けて "first line of #gets" という文字列を入力しようとしたところ、一文字目の "f" を押下した時点で IO#getsnil を返し、このコードの実行が終了してしまいます。

つまり、 EOF 後の入力は取りこぼしてしまうようなのです。

animation.gif

この入力の取りこぼしは、冒頭で示した Windows 環境のいずれにおいても同じようにみられた一方で、 Ubuntu ではみられませんでした。

次のアニメーションは Ubuntu 16.04(Ruby 2.4.1-p111)で実行した様子です。 
Ubuntu では IO#gets は nil を返すことなく、改行を入れるまで入力を受付け思惑どおりに動いてくれます。 EOF を送った後の入力をこぼすことなく、受取ってくれます。

animation_ubuntu.gif

解決方法がわからん

いろいろもがいてはみたものの、いずれも奏功せず悪あがきに終わりました。何か有効な対処法はないんでしょうかね…。自分でやってみたことは次のとおりです。

1. IO#raw

端末画面での入力処理モードには、次のようなものがあります。

  • cooked
    入力はいったんバッファに溜められ、改行するまでプログラムに渡らない。また、Ctrl + C や Ctrl + D といったコントロールコードをシェル側で解釈する。

  • cbreak
     標準入力をバッファに溜めず、入力後即時でプログラムに渡す。コントロールコードは解釈される。

  • raw
     標準入力をバッファに溜めず、かつコントロールコードも解釈せず通常の文字としてプログラムに渡す。

io/consolerequire すると IO#raw が使えるようになります。

p $stdin.raw(&:readlines); p $stdin.gets

これを利用すれば EOF も無効化できるのではと思いましたが、特に挙動に変化は見られませんでした。

2. IO#ungetc("\b")

EOF が悪さをしているんだろうから、送ったらバックスペースで消せばいいという考え。

p $stdin.readlines; $stdin.ungetc("\b"); p $stdin.gets

バックスペースを送ったところで EOF が消えるわけでないんだから、そりゃだめだわ…。

おわりに

これって Windows に依存する問題なんでしょうか。 Windows ではこのほかにも、 Pry や irb (正確には rb-readline か) で日本語入力を正しくあつかえないという制限もあり、こと標準入力に関しては不自由があるな~と感じています。

私の環境では Windows は全部みられた現象なので、過去に困った方がいないのかと思ったのですが、ググった限りでは見つからず…。

1
1
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1