Search code examples
rubytimeoutgets

Changing behavior of gets, when reading from command line, in Ruby


The intended operation of the Ruby code below is as follows:

  1. write ARGV[0], a file named on the command line, to old
  2. create a new, temporary copy of that file
  3. loop until user gives input
  4. remove the temporary file

When I hard code old equal to hello.c, Timeout inside the do loop works as I would expect: it waits for 3 seconds for input from the keyboard, if none is given enter the rescue block and repeat.

When I set old equal to ARGV[0] (which is also hello.c), fp is assigned the first line of hello.c and the code breaks out of the loop.

How I run it:

user@cpu live$ ruby test.rb hello.c 
hello.c
#include <stdio.h>
user@cpu live$

The code:

#!/usr/bin/env ruby

require 'timeout'

old = ARGV[0].chomp
puts old  # sanity check
# old = 'hello.c'
new = 'tmp_' + old
`cp #{old} #{new}`

fp = nil
loop do
  begin
    Timeout::timeout(3) { fp = gets }
    puts fp  # sanity check
    break if (fp)
  rescue Timeout::Error
    # ...
  end
end

`rm #{new}`

I don't understand why reading from the command line would be any different than hard coding the file name.

I appreciate any help you can give. Thanks.


Solution

  • Check the docs:

    If Kernel.gets sees that ARGV is set, it uses them as filenames to feed instead of reading from stdin. So use an expicit: $stdin.gets