shinyMao shinyMao - 1 month ago 14
Ruby Question

Difference between $stdin and others gets.chomp

Hello everyone I am a novice to learn Ruby
i am practicing to get the data from the file

puts "what is your filename?"
filename = $stdin.gets.chomp


from the line two I can get the filename I want to read
However, if I just write gets.chomp it will turn into an error
I have already known $stdin means standard input but still cannot understand this
can anyone help me? THX

Answer

When invoking gets without specifying the stream, we are invoking Kernel#gets and when stream is specified we are invoking IO#gets

I believe Kernel#gets wraps around IO#gets under the hood but before it needs to create an IO object, that IO object will be a concatenation of all command line arguments(ARGV) ( it will try to open every single one as file in positional order) and them read from it. If there are no elements left on ARGV it will then read from stdin.

That behavior can be tested with this simple snippet:

while gets
        puts $_
end

When running ruby myscript.rb without parameters it will read stdin, if parameters are specified it will try to open as files and read from it, it will works similarly to cat command .

That stream could be tty, socket, file etc:

stream = File.open('/etc/passwd','r')

puts stream.gets 

stream.close

A simple http client using sockets:

require 'socket'

s = TCPSocket.new 'icanhazip.com',80

s.puts <<~EOF
GET / HTTP/1.1
Host: icanhazip.com

EOF

while line = s.gets
        puts line
end

s.close

More about Kernel#gets here More about IO#gets