38

Are they the same, or are there subtle differences between the two commands?

Brian Webster
  • 30,033
  • 48
  • 152
  • 225
stanigator
  • 10,768
  • 34
  • 94
  • 129

4 Answers4

43

gets will use Kernel#gets, which first tries to read the contents of files passed in through ARGV. If there are no files in ARGV, it will use standard input instead (at which point it's the same as STDIN.gets.

Note: As echristopherson pointed out, Kernel#gets will actually fall back to $stdin, not STDIN. However, unless you assign $stdin to a different input stream, it will be identical to STDIN by default.

http://www.ruby-doc.org/core-1.9.3/Kernel.html#method-i-gets

Dylan Markow
  • 123,080
  • 26
  • 284
  • 201
32

gets.chomp() = read ARGV first

STDIN.gets.chomp() = read user's input

Kick Buttowski
  • 6,709
  • 13
  • 37
  • 58
Rick Lien
  • 321
  • 3
  • 2
10

If your color.rb file is

first, second, third = ARGV

puts "Your first fav color is: #{first}"
puts "Your second fav color is: #{second}"
puts "Your third fav color is: #{third}"

puts "what is your least fav color?"
least_fav_color = gets.chomp

puts "ok, i get it, you don't like #{least_fav_color} ?"

and you run in the terminal

$ ruby color.rb blue yellow green

it will throw an error (no such file error)

now replace 'gets.chomp' by 'stdin.gets.chomp' on the line below

least_fav_color = $stdin.gets.chomp

and run in the terminal the following command

$ ruby color.rb blue yellow green

then your program runs!!

Basically once you've started calling ARGV from the get go (as ARGV is designed to) gets.chomp can't do its job properly anymore. Time to bring in the big artillery: $stdin.gets.chomp

cjpillette
  • 111
  • 1
  • 3
  • 1
    Ruby white belt here currently chiseling through the granite walls of Ruby the Hard Way and this chapter had me stumped until I found your explanation. Thanks for this! – user2136000 Feb 17 '18 at 21:52
  • Simple and clean example. Thanks! – vishal Mar 15 '19 at 19:36
5

because if there is stuff in ARGV, the default gets method tries to treat the first one as a file and read from that. To read from the user's input (i.e., stdin) in such a situation, you have to use it STDIN.gets explicitly.

Shoot Sahan
  • 163
  • 1
  • 4
  • 9