Considering that the code you just provided is not even close to what your guidelines were suggesting he do, you just cheated.
You must not understand my one liner then. Per perlrun the -n mode creates an implicit 'while ( <> )' loop. The file opening and closing is also done implicitly (see perlop under the '<>' operator. So in those regards, my code does just as I suggested: open both files, iterate over each line, do some processing, etc. The -i switch means "inline editing." The documented internal implementation of inline editing is to create a temp file, read the input file, write to the temp file, and then rename the temp file over the input file as the last step. So in this regard, my code also does just as I recommended. It writes to a temp file, and in the end, renames the temp file over the original input file.
The only thing that was ambiguous in my original criteria was that I didn't get into what processing would be done on each line. In my previouis one-liner I chose to just skip the output of any line that matched the new name being added. And then at the end, print that new name. My original suggestion didn't specify what processing to do, but did specify that at the end, the new name could be appended, which my one-liner accomplishes.
Just because I used code techniques that do things behind the scenes doesn't mean that the things aren't being done as I described in the first place. And I find it a little surprising that you would say I'm cheating just because I used idioms that you wouldn't have picked yourself.
As for your snippet, I see no reason for setting autoflush. Also, your regexp is flawed because it doesn't allow for the "\n" newline that will be present on each input line (because we're not bothering to chomp). But beyond that, let's see it in one-liner form:
perl -ni -e "BEGIN{print qq/Enter new student name: /; chomp( $student
+ = <STDIN> ); $found = 0 } $found++ if /^\Q$student\E\s*$/i; print $_
+ . (eof and not $found) ? qq/$student\n/ : qq//;" students.dat
Disecting it: The begin block allows you to do things before the implicit while(<>) loop begins. That's where I grabbed the new student name. It's a little kludgy, but mimicks all previous solutions. Next, $found is initialized to a "false" value. Ok, we're done with the begin block. Now just imagine a "while( <> ) {.....}" block wrapped around the rest of the one-liner. So, first we read one line from the infile, check to see if it matches the new student name. If it does match, set $found to a "true" value. Then print what was just read in from the infile. Finally, check to see if we're at the end of the file. If we are, check to see if we've already found the student name to exist in the file. If not, go ahead and add to the end of the file one more line; the student's name. We use concatenation to accomplish this.
As you can see, I'm doing everything you're doing (after correcting the bugs). No cheating here, just less wordy idioms. That's a problem?
By the way, someone requested unix/linux friendly versions of these one-liners. They actually should work just fine under both Win32 and Unix/Linux.
|