0

I need a method with which I can proof if the last entered letter is a space while I'm typing something so the program jumps to the next line code.
Normally it works with Enter but I want to continue it with Space.
I tried to use gets.chomp[-1] but you always have to press Enter.

Eric
  • 11
  • 1
  • Welcome to SO. Saying you "need a method" isn't the right approach. We need to see your attempt at solving this. See "[Stack Overflow question checklist](https://meta.stackoverflow.com/questions/260648)" and "[How do I ask a good question?](https://stackoverflow.com/help/how-to-ask)". Your question is close but show us some code that demonstrates the problem you're having, the required input and the desired results. – the Tin Man Jan 14 '20 at 05:21

3 Answers3

1

You might have to use getch. See "Get single char from console immediately" and compose your own line input. gets doesn't act on pressing a space but groups the whole line input until Enter is pressed.

The gets documentation says it:

returns (and assigns to $_) the next line ... from standard input.

so if you press the space bar, and you could press backspace and do other things before you press Enter, and Ruby won't act on the space being pressed.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
nonopolarity
  • 146,324
  • 131
  • 460
  • 740
1

When you call gets, Ruby delegates the line editing to your terminal. With default settings, your terminal buffers the input and provides some basic line-editing: it prints the entered character to the screen and allows you to delete the last caracter via del or an entire word via ^W (depending on your terminal). Once you press enter, the terminal sends the finished buffer back to Ruby.

Ruby isn't aware of any of this. It doesn't see your editing, nor does it see a del control character in the resulting string. The only thing it gets is the composed line as a whole. Likewise, Ruby isn't aware of the separate key presses and can't intercept space on its own.

But fortunately, terminals are very flexible. Almost any setting can be configured, including the end-of-line character. So in order to make space work like enter, we have to adjust the terminal settings!

This can be done using the stty command line tool. In addition, you have to change Ruby's input record separator $/ (which defaults to newline) to space, so gets and chomp behave accordingly.

Here's a quick and dirty example:

begin
  settings = `stty -g`          # get current terminal settings
  system('stty', 'eol', ' ')    # make terminal recognize space as end-of-line
  $/ = ' '                      # set Ruby's input record separator to space

  puts 'hit ^D to exit'
  while input = gets(chomp: true)
    p input: input
  end
ensure
  system('stty', settings)      # revert terminal settings
end

Running the above code in a terminal and entering foo bar baz (with trailing space) gives:

hit ^D to exit
foo {:input=>"foo"}
bar {:input=>"bar"}
baz {:input=>"baz"}

Another option is to put your terminal into raw mode, either by calling stty or via require 'io/console' (see the docs). This disables all line editing features (including printing the entered characters) and passes the input directly to Ruby. It gives you even more control over the input but obviously needs much more work to get the line editing features we're accustomed to.


The documentation for termios provides more information.

Stefan
  • 109,145
  • 14
  • 143
  • 218
0

This will only allow a space to continue, while still honoring Control-C

require 'io/console'

def wait_for_space_key
  puts "Press space to continue"
  input = nil
  while input != ' '
    input = STDIN.getch
    raise Interrupt if input.ord == 3 # Control-C has an ASCII value of 3
  end
end

begin
  # Your script goes here
  puts "Welcome to my script!"
  
  wait_for_space_key
  
  puts "Thank you for pressing space!"
rescue Interrupt
  puts "\nInterrupted by Control-C"
end
Michael
  • 3,568
  • 3
  • 37
  • 50