[Ruby] Recognize ASCII control characters such as ^ H as intended when accepting standard input

Conclusion

** Use Readline.readline instead of STDIN.gets **

STDIN.gets If you look at how to receive standard input in Ruby, you'll often find the following implementations:

stdin.rb


print '> '
text = STDIN.gets.strip
puts "You said #{text}!"
$ ruby stdin.rb
> hello
You said hello!

It seems that there are read, readline, and readlines in addition to gets. I want to read multiple lines from Ruby standard input

Disadvantage

However, with the above method, ASCII control characters cannot be recognized with the intended behavior.

$ ruby stdin.rb
> hello^H^H^H
You said he!lo

In the above example, after typing hello, the ASCII control character backspace (which can be entered with ctrl + H) is entered three times.

Actually, after entering hello, I have entered the backspace control character three times, so I want it to be he, but it becomes hello ^ H ^ H ^ H and accepts standard input. The backspace is applied after you finish.

Solution

To do this as intended, implement it as follows:

readline.rb


require 'readline'

print '> '
text = Readline.readline
puts "You said #{text}!"
$ ruby readline.rb
> he # "hello"After typing ctrl+Pressed H 3 times
You said he!

Other

Readline.readline is useful because you can also use history. You can display the previously entered character string by pressing the up key of the cursor or pressing ctrl + P. See the module Readline Reference Manual for more information.

See Wikipedia for ASCII control characters.

Recommended Posts

[Ruby] Recognize ASCII control characters such as ^ H as intended when accepting standard input
Ruby standard input