Ruby readline fails if process started with arguments
Asked Answered
A

2

6

I'm having the strangest issue. This code below works fine:

require 'json'
require 'net/http'
h = Net::HTTP.new("localhost", 4567) 
while(l = gets.chomp!)
   res = h.post("/api/v1/service/general",l)
   puts res.body
end

However, with the small modification of getting host/port from parameters:

require 'json'
require 'net/http'
h = Net::HTTP.new(ARGV[0], ARGV[1]) 
while(l = gets.chomp!)
   res = h.post("/api/v1/service/general",l)
   puts res.body
end

..and starting with ruby service.rb localhost 4567 ...

I get this error:

service.rb:4:in `gets': No such file or directory - localhost (Errno::ENOENT)

Using ruby 1.9.2p0 on Ubuntu 11.04

Annikaanniken answered 6/8, 2011 at 9:20 Comment(0)
Z
12

Have you tried while (l = $stdin.gets.chomp!)? Otherwise Kernel#gets reads from ARGV.

Zenobia answered 6/8, 2011 at 9:29 Comment(3)
Really? That's interesting to learn. I love Ruby to pieces, but this is the principle of most surprise, IMHO. I would have to investigate this in-depth tomorrow! Sometimes I feel Ruby is making me un-learn too much!Federation
Ah, that worked. Is this normal behaviour? I can't remember having this problem before, and I've written quite some scripting in Ruby before - although on earlier versions. Why would you ever want gets or readline to work with the first argument?Annikaanniken
Yes, this is standard behavior. From the Kernel#gets docs: "Returns (and assigns to $_) the next line from the list of files in ARGV (or $*), or from standard input if no files are present on the command line." With the explicit receiver, you call IO.gets which "Reads the next ``line’’ from the I/O stream".Zenobia
V
1

Try it like this:

h = Net::HTTP.new(ARGV.shift, ARGV.shift) 
while(l = gets.chomp!)

It will still fail if you pass in more than two arguments. You should call ARGV.clear after constructing h if you want to deal with that.

Villar answered 6/8, 2011 at 9:27 Comment(2)
You also can give gets an explicit receiver ($stdin), then it works without clearing ARGV. See my answer.Zenobia
Yup this worked as well. I tried setting ARGV[0] to nil, but that didn't work. I guess there's a special case if ARGV.length>0 or somethingAnnikaanniken

© 2022 - 2024 — McMap. All rights reserved.