質問

I was following the advice from this question when trying to read in multi-line input from the command line:

# change line separator
$/ = 'END'
answer = gets
pp answer

However, I get weird behavior from STDIN#gets when I try to change $/ back:

# put it back to normal
$/ = "\n"
answer = gets
pp answer
pp 'magic'

This produces output like this when executed with Ruby:

$ ruby multiline_input_test.rb
this is
        a multiline
  awesome input string
                        FTW!!
END
"this is\n\ta multiline\n  awesome input string\n            \t\tFTW!!\t\nEND"
"\n"
"magic"

(I input up to the END and the rest is output by the program, then the program exits.)

It does not pause to get input from the user after I change $/ back to "\n". So my question is simple: why?

As part of a larger (but still small) application, I'm trying to devise a way of recording notes; as it is, this weird behavior is potentially devastating, as the rest of my program won't be able to function properly if I can't reset the line separator. I've tried all manner of using double- and single-quotes, but that doesn't seem to be the issue. Any ideas?

役に立ちましたか?

解決

The problem you're having is that your input ends with END\n. Ruby sees the END, and there's still a \n left in the buffer. You do successfully set the input record separator back to \n, so that character is immediately consumed by the second gets.

You therefore have two easy options:

  1. Set the input record separator to END\n (use double quotes in order to have the newline character work):

    $/ = "END\n"
    
  2. Clear the buffer with an extra call to gets:

    $/ = 'END'
    answer = gets
    gets # Consume extra `\n`
    

I consider option 1 clearer.

This shows it working on my system using option 1:

$ ruby multiline_input_test.rb 
this is
        a multiline
  awesome input string
                        FTW!!
END
"this is\n        a multiline\n  awesome input string\n                        FTW!!\nEND\n"
test
"test\n"
"magic"
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top