Loginskip to content

October 30th, 2006

15 $cases_sold->{$type} += $sold; 16 } 17 else

You’re not required to stick to only one idiom, mind you. It’s common for people to choose different ones according to the way they think about the operation they’re expressing. You have to be fanatical about checking return codes if you want to write quality programs. For instance, in the first example in the preceding list, the copyfunction from File::Copyalso returns true or false and sets $! on failure. It would be a strange sort of program that wouldn’t have a reason to ensure that this had happened. Some functions return something besides true/false but still set $!, for example, chmod, chown, and unlinkeach take a list of files to operate upon, return the number of files actually modified, and if there were any errors, set $! to the last one. (Unfortunately it’s not possible to tell which file(s) had problems without checking manually afterwards.) Know your operating system. A student in one of my classes encountered the following. The assignment was to create a temporary directory and a bunch of files in it, perform some operations on them, and then to remove the files and the directory. Part of his code looked something like this: foreach my $file (@files) { open OUT,”>$file” or die “Can’t open $file: $!n”; # write something to the file } # Open the files in the directory and do something # with the contents die “Unlink didn’t get everything: $!n” unless unlink @files == @files; chdir ‘..’ or die “Couldn’t go up a level: $!n”; rmdir $tmpdir or die “Couldn’t rmdir $tmpdir: $!n”; Every return code dutifully checked, but the rmdir failed, and $! said, “Directory not empty.” Yet when he looked in the directory, there were no files there. What was going wrong? The problem was that he had omitted the close statement from the loop that created the files. Whenever Perl encounters an open statement using an existing filehandle, it closes that filehandle for you, so all but the last file had already been closed. On Unix, if any process has a file open, it is not removed by unlink until the file is closed, so the last file in @files had not been removed at the time the rmdir was executed. But then the program exited, which meant that all its open filehandles were closed; at that point the file was removed, destroying the evidence.

Hint: This post is supported by Gama hrvatski web hosting services

Comments are closed.