Thursday, November 17, 2011

Exercise 20: Functions And Files: Learn Ruby The Hard Way: Practicum

This is the point where many people, who program casually, start to get glassy eyed (well, at least in the past, this is where I often got that way). Functions are incredibly powerful ways to show what is happening to code in a small and distinct place, and it helps a lot to keep code modular and portable.

The disadvantage is that code can get to be really hard to follow if you are not focusing on and aware of what's happening. This is especially true when we start putting in file actions and the opening/closing/modifying of files both outside of and within functions. So let's take this one slowly and see what's going on.

Pay close attention to how we pass in the current line number each time we run print_a_line.

What You Should See

$ ruby ex20.rb test.txt
First let's print the whole file:

To all the people out there.
I say I don't like my hair.
I need to shave it off.

Now let's rewind, kind of like a tape.
Let's print three lines:
1 To all the people out there.
2 I say I don't like my hair.
3 I need to shave it off.


Extra Credit

Go through and write English comments for each line to understand what's going on.

Each time print_a_line is run you are passing in a variable current_line. Write out what current_line is equal to on each function call, and trace how it becomes line_count in print_a_line.

[Current_line starts out with a value of one, and then before each print_a_line() call, current_line gets incremented (added to) by one. For those familiar with C and C type languages, this is where the shorthand variable++ comes from (it means the same thing, take variable and increment it by one). See my second draft for the value of current_line in each case.]

Find each place a function is used, and go check its def to make sure that you are giving it the right arguments.

[In this case, though the function is defined as receiving a value of 'f', that is local in scope. The value being passed to the functions in each case is 'current_file', and in the case of 'print_a_line', 'current_line' is passed into the function as well, and described within the function as 'line_count'.]

Research online what the seek function for file does. Look at the rdoc documentation using the ri command and see if you can figure it out from there.

[The ri documentation doesn't give me much of anything for this, at least not on my PC. I can deduce that seek allows me to pinpoint a position in a file and go to that location. In this case, since the first value is 0, I assume it means go to the beginning of the file, and the execution of the code proves that.]

Research the shorthand notation += and rewrite the script to use that.

[variable += 1 is the equivalent of saying variable = variable + 1. See below for a rewrite.]


So we have some new material to work with here. We see our first direct reference to using the seek method within the file object, and we are introduced to the idea (and the shorthand) for incrementing variables. For straightforward linear scripts, incrementing works and can be useful, but it really shows its power when we start dealing with looping of code (it's a way to keep track of what we've done and control how many times loops are executed). This example also helps show how the scope of variables changes as a value moves from one function to another, and that values modified outside of the function can affect what goes on inside of a function.


Anonymous said...

I can't tell what is happening with all the f's in this one. Beginning with line 3, I am very confused.

Anonymous said...

Just to clarify, I would expect to see something like:

f = input_file

but I don't see anything like this connecting f to the file.

Anonymous said...

It looks like Zed covers the issue with the f's in the Python version comments, but not in the Ruby comments.