Rubyで入力をエコーバックしない方法は以下記事の通りIO#noecho
を利用すればOK。
いい感じでプロンプトを出力したい
こうしたい。
- プロンプトを表示(ただしこの時点ではまだ改行しない)
- (ユーザー入力)
- 改行
ベタに書くとこんな感じ。
プロンプト出力しつつIO#noecho
require "io/console"
print "Password: "
input = STDIN.noecho &:gets
print "\n"
puts "Entered => #{input}"
ワンライナーで書けないのかコレ?という話。
(それ用のgem使えば実現できそうだけどデフォルト厨なので標準APIだけでやりたい)
Readline.readlineを使ってみる
Readline.readline
はプロンプト出力を引数に渡せる。
これはエコーバックする
require "readline"
input = Readline.readline "Password: "
puts "Entered => #{input}"
エコーバックさせずに書くならばこう?
エコーバックしないけど...
require "io/console"
require "readline"
input = STDIN.noecho { Readline.readline "Password: " }
puts "Entered => #{input}"
だがこれだと入力後に改行が含まれない。
「abc」と入力した出力結果
Password: Entered => abc
こうしてみる。
プロンプトに改行を含める
input = STDIN.noecho { Readline.readline "Password: \n" }
入力受付中がこうなる。うーん。
入力受け付ける時点で改行している
Password:
_ #←ここにカーソルが表示されてる
例えば、IO#noecho を使ってパスワード入力を端末上に表示しないといっ た事ができます。同様の事が curses ライブラリやreadline ライブラリでも実現できますが、
とあるが、Readline
にエコーバックさせないためのいい感じなI/Fが特に見つからない...。
結論
うまく書けなかった(少なくとも私は...)
- ベタに書く(アプリ内で頻繁な記述にならなければこれでいいや)
-
関数を作る
gets_without_echoと命名してみたrequire "io/console" def gets_without_echo io: STDIN, prompt: nil print prompt unless prompt.nil? input = io.noecho &:gets print "\n" input end input = gets_without_echo prompt: "Password: " puts "Entered => #{input}"
番外編:無理矢理ワンライナーで書いてみる
可読性ェ...
require "io/console"
input = STDIN.tap{print "Password: "}.noecho(&:gets).tap{print "\n"}
puts "Entered => #{input}"
オススメしたくない。
コメントで教えてもらったスマートな書き方
良さそう。
require "io/console"
require "readline"
input = STDIN.noecho { Readline.readline("Password: ").tap { puts } }