Take the 2-minute tour ×

I'm trying to run this code from Zed Shaw's Learn Ruby the Hard Way exercise 15:

filename = ARGV.first

prompt = '> '
txt = File.open(filename)

puts "Here's your file: #{filename}"
puts txt.read()

puts "I'll also ask you to type it again:"
print prompt
file_again = STDIN.gets.chomp()

txt_again = File.open(file_again)

puts txt_again.read()

Every time I run it I get an error message that says:

ex15.rb:4:in `initialize': can't convert nil into String (TypeError)
from ex15.rb:4:in `open'
from ex15.rb:4

What is going on? I can't get this code to work!

share|improve this question
When you executed it did you execute it like this ruby ex15.rb sample_text.txt ? –  limelights Aug 2 '13 at 7:47

4 Answers 4

up vote 0 down vote accepted

How did you run the script? It seems like the script expects an argument, like this: ruby my_script.rb file.txt.

Did you provide this argument? If not, ARGV[0] returns nil and the script fails on Line 4, as it evaluates to:

txt = File.open(nil)

File.open expects a filename / path to a file, see: File, Ruby 2.0 Docs.

share|improve this answer
Oh, duh! I completely forgot. Thanks! –  emaamodt Aug 2 '13 at 7:58

Look at the error message:

Line 4: File.open waits for a String as an argument, and gets instead a Nil reference.

That means the ARGV.first, which is the first argument from command line after your script name, is undefined.

share|improve this answer

In here:

filename = ARGV.first
# ...
txt = File.open(filename)

You are assuming filename, hence ARGV.first will be always there. This is an assumption that should be never made especially when dealing with inputs.

I'd suggest you to either provide a default value for filename in case none is given:

filename = (ARGV.count > 0) ?  ARGV.first : "default.txt"

or throw your own exception and let the upper level of abstraction to deal with it:

raise RuntimeError.new "No input file" unless ARGV.count > 0
share|improve this answer

I know this question is a little old but I figure the answer might help others searching for help on this same problem like myself earlier.

Had the same problem, here's what I did to make it work.

My code:

filename = ARGV.first
txt = open(filename)

puts "Here's your file #{filename}"
print txt.read

print "Type the filename again: "
file_again = $stdin.gets.chomp

txt_again = open(file_again)

print txt_again.read

That's the right code. BUT the trick to getting the file to work and get past that error isn't in the code for the ex15.rb file. It's with where and how you're creating the plain text ex15_sample.txt file.

If you're using TextWrangler or like in my case TextMate, create another tab or window and another file. Make SURE you choose plain text:

enter image description here

Then write the given text within the file:

This is stuff I typed into a file. It is really cool stuff. Lots and lots of fun to have in here.

Then save it in the same directory as your ex15.rb script.

Then go to the terminal. And type the following (not that the directory name and path I'm using is an example from mine, you'll have to fill it in using your correct information):

ruby /users/ilyafeynberg/desktop/rubyway/ex15.rb ex15_sample.txt

If you do all the steps correctly, it should run properly and prompt you properly through the terminal. Take note that you must provide the proper path to your ex15.rb file. If I would have cut it short and left out the director that I created and put it in "rubyway" it would have failed.

NOTE: I'm honestly not sure why, but creating a plain text file using the plain text feature with TextEdit on mac created a boat load of problems for me and did not work. Creating it as a plain text file within my editor and saving it properly made the difference and let me understand what I was doing wrong and what I had to do right. So I recommend not using TextEdit but the editor in which your writing your scripts.

Good luck!

share|improve this answer

Your Answer


