Verse Of The Day

Thursday, February 07, 2008

Reading And Writing Text Files in Ruby

On a recent project, I had everything automated up to the point where I had to give feedback to the business analysts on what, if any, of their data had to be fixed and re-run.

I ended up writing some Ruby scripts to run through a file of transaction responses, and sort out the various error types into separate files, and produce a summary report of the error counts in each category.
Now the only manual part was cutting and pasting the summary into an email, and attaching the various sorted files.

I was pleasantly surprised at how easy it was to read and write text files in Ruby. Let's say you just want to read a text file, line by line, and spit it back out, a la "cat"..., "r").each { |line| puts line }
Wow, that was easy, eh? Let's try reading that file into an array for use later...
results = [], "r").each { |line| results << line }
Let's say you want to capitalize everything in the file, and spit it out to a new file...
out_file ="upper_case.txt","w")
results.each do |line|
out_file.puts line.upcase

That was easy. It's probably obvious, but the first argument passed to the File constructor is the filename, and second is the read/write flag.

For comparison' sake, let's read a file in Java and spit it out line for line...
BufferedReader is = new BufferedReader(new FileReader(fileName));
String line = "";

try {
while (line != null)
line = is.readLine();
catch (Exception e) { /* do nothing for now */ }
try {is.close();}catch(Exception f) { }

Definitely not "hard", but it is a bit more code. Writing a file is very similar, except of course you use FileWriter and BufferedWriter instead of FileReader and BufferedReader, and write to the file instead of reading from it.

I'm not really trying to prove anything here -- Ruby isn't better than Java, Java isn't too hard or too verbose, etc. I like Java. I like Ruby. Against my better judgment, I even like Oracle, but that's another topic. I just found that working with files was easier than I expected, even for a Ruby beginner like myself.


Anonymous said...

I'm a bash script purist...I resort to Perl when I have to otherwise I do everything in bash.

tr [[:lower:]] [[:upper:]] < file > file2


Oh, Ruby on Rails is cool and all but it doesn't replace sounds development practices. Check out this post from Jay Pipes on varchar use in MySQL:

Anonymous said...

No language, framework, or tool set should replace sound development practices. Tools are nice, but they don't replace knowledge. The prevalent tools at my first job were 'vi', 'cc', 'dbx', and 'make' on an AIX box. The closest to an IDE was having multiple xterms up with 'vi' running in them. When you start there, you learn to appreciate modern tools, but still know what's really going on.

About 5 or 6 years ago I was in the undesirable position of trying to explain to an "Oracle developer" why her database design was not optimal. She just wasn't understanding integrity constraints, normalization, or even what a natural primary key was versus a generated sequence. She knew how to use the ERWin tool, but didn't understand the underlying database concepts. She couldn't even read or understand the DDL that ERWin generated.

Or last year, trying to explain to a developer new to .NET what really happens when she tries to call one of our web services. That "one call " failed, and was the call to our web service, so it must be our issue. Sure it *looks* like one call, since you just blindly ran a .NET wizard and don't understand there are generated client stubs under the hood somewhere. Try to explain serialization, deserialization, security, opening and closing of connections, and transport to someone who just pushes buttons instead of writing code.

Anonymous said...

this could be the software I'm looking for...

My problem is that I testing a GUI application via LoadRunner, which I can handle I'm experienced there...BUT from within the loadrunner VUGEN I need to remote connect to a unix machine, pass a particular account parameter and execute a shell script...I know there's no direct way to do that except by creating a custom routine within LR ..suggestions welcome!

John Yavelak
QA Analyst III, AT&T