標準入力をcountすると末尾にDが付与される

fjordbootcampのプラクティスを進めていく上で、標準入力($stdin.read)の値に対し、String#countを使用した際にDが末尾に出力された。

# wc.rbのコード
p $stdin.read.count('a')
# 実行結果
$ ruby wc.rb
aa
a
3D
#=> 3 と表示させたい!
  1. Dの正体🤔
  2. Dを出力させなくするには🤔

に関して、調べたみたので結果を備忘録として。

Dの正体

標準入力をcontrol - Dで終了した際、端末(ターミナル)が制御文字(^D)をcharとしてエコーしているため表示される。
たしかに標準入力を終了する際にcontrol - Dで終了したな〜 更に調べると、制御文字(^D)が出力される設定になっている模様。
stty -aコマンドから端末の設定を確認することができる。 f:id:choco0809:20220409090254p:plain echoctlが設定されているため、制御文字(^D)をcharとしてエコーしているため表示されてしまう。
eof = ^Dが入力の終了であることを表している
以上のことからDの正体は制御文字(^D)であることがわかった。

制御文字(^D)を出力させなくするには

echoctlが設定されているため制御文字が出力されるので、この機能を無効化すればよい。

# sttyの機能を無効化する際は、機能の前に - を付与する
$ stty -echoctl

f:id:choco0809:20220409091214p:plain echoctlが無効化されていることがわかる。
無効後再度wc.rbを実行すると

$ ruby wc.rb 
aa
a
3

期待通り、制御文字(^D)が表示されなくなった! ただ、上記の方法など毎回実行する端末の設定を変える必要がある...😓

ちなみにrubyプログラムから端末設定を制御することができる(別途gemが必要)を教えてもらったので、
次回はそのgemを用いて、プログラム側から端末の設定を制御してみようと思う。

ちなみに

プログラム内の値にはDは付与されていないため、あまりプログラム内では意識しなくていいかも?