Edited at

Rubyで標準入力にexitとタイプしたら終了させる

More than 3 years have passed since last update.

標準入力にexitかquitが入力されたときにプログラムを終了させたいときがあると思います。

でもいちいち入力時にチェックするコードを記述するのはしんどいですよね。

というわけで、こんな感じでIOクラスのgetsメソッドを上書きしちゃいます。

class IO

def gets
i = super
exit 0 if i.chomp =~ /^(quit|exit)$/ && self.tty?
return i
end
end

# 標準入力のテスト
puts STDIN.gets # exitとタイプすると終了する
puts $stdin.gets # この書き方でもいける
puts gets # この書き方だとexitとタイプしても終了しない

こうすると既存の記述は崩さずに、exitをタイプすればプログラムを終了させることができます。

ただ、上記の例にある通り、STDINを省略してgetsと書いた場合、exitとタイプしても終了しません(標準入力のデータは取得できます)。

どういうことかというと、STDINを省略するとIOクラスのgetsが呼ばれずに、Kernelモジュールのgetsが呼ばれてしまうからです。

なので、下記のようにObjectクラスのgetsを上書きすればいいのですが、そうすると今度はSTDIN.getsが動きません。

class Object

def gets
i = super
exit 0 if i.chomp =~ /^(quit|exit)$/
return i
end
end

# 標準入力のテスト
puts gets # exitとタイプすると終了する
puts STDIN.gets # この書き方だとexitとタイプしても終了しない

どっちの記述も対応したい場合は両方書くしかないっぽいですね。

なんでこんな風になってるんだろう…。


参考

instance method IO#gets (Ruby 2.2.0)

gets - module Kernel (Ruby 2.2.0)