Exercise 15: Reading Files

You know how to get input from a user with gets.chomp or ARGV . Now you will learn about reading from a file. You may have to play with this exercise the most to understand what's going on, so do the exercise carefully and remember your checks. Working with files is an easy way to erase your work if you are not careful.

This exercise involves writing two files. One is the usual ex15.rb file that you will run, but the other is named ex15_sample.txt . This second file isn't a script but a plain text file we'll be reading in our script. Here are the contents of that file:

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

What we want to do is "open" that file in our script and print it out. However, we do not want to just "hard code" the name ex15_sample.txt into our script. "Hard coding" means putting some bit of information that should come from the user as a string directly in our source code. That's bad because we want it to load other files later. The solution is to use ARGV or gets.chomp to ask the user what file to open instead of "hard coding" the file's name.

1 2 3 4 5 6 7 8 9 10 11 12 13 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

A few fancy things are going on in this file, so let's break it down real quickly:

Lines 1-2 uses ARGV to get a filename. Next we have line 3, where we use a new command open . Right now, run ri "File#open" and read the instructions. Notice how, like your own scripts and gets.chomp , it takes a parameter and returns a value you can set to your own variable. You just opened a file. Line 5 prints a little message, but on line 6 we have something very new and exciting. We call a function on txt named read . What you get back from open is a File , and it also has commands you can give it. You give a file a command by using the . (dot or period), the name of the command, and parameters, just like with open and gets.chomp . The difference is that txt.read says, "Hey txt ! Do your read command with no parameters!"

The remainder of the file is more of the same, but we'll leave the analysis to you in the Study Drills.

What You Should See Warning Pay attention! I said pay attention! You have been running scripts with just the name of the script, but now that you are using ARGV you have to add arguments. Look at the very first line of the example below and you will see I do ruby ex15.rb ex15_sample.txt to run it. See the extra argument ex15_sample.txt after the ex15.rb script name. If you do not type that you will get an error so pay attention! I made a file called ex15_sample.txt and ran my script. $ ruby ex15.rb ex15_sample.txt Here's your file ex15_sample.txt: This is stuff I typed into a file. It is really cool stuff. Lots and lots of fun to have in here. Type the filename again: ex15_sample.txt This is stuff I typed into a file. It is really cool stuff. Lots and lots of fun to have in here.

Study Drills This is a big jump, so be sure you do this Study Drill as best you can before moving on. Above each line, write out in English what that line does. If you are not sure, ask someone for help or search online. Many times searching for "ruby THING" will find answers to what that THING does in Ruby. Try searching for "ruby open." I used the word "commands" here, but commands are also called "functions" and "methods." You will learn about functions and methods later in the book. Get rid of the lines 8-13 where you use gets.chomp and run the script again. Use only gets.chomp and try the script that way. Why is one way of getting the filename better than another? Start irb to start the irb shell, and use open from the prompt just like in this program. Notice how you can open files and run read on them from within irb ? Have your script also call close() on the txt and txt_again variables. It's important to close files when you are done with them.