in reply to Re^2: pushing file counts for adding
in thread pushing file counts for adding

opendir doesnt NEED an or die. If you get no results, it didn't work. In this setting I'm guessing that he knows what his directories are and entered them correctly.

The regular expression is there in case there are any blank lines in the directory.txt file, so it dosen't try to process them. But again, it would just return a zero value if it did. I nver trust user input, I try to check it where I can. Old habits. Much easier to accidently hit the return an extra return at the end of the file, this takes care of it.

$_/$file, ya got me. I missed changing that one to $dir in the final sweep. My bad.

Replies are listed 'Best First'.
Re^4: pushing file counts for adding
by Anonymous Monk on Mar 21, 2016 at 23:25 UTC
    opendir doesnt NEED an or die.
    $ perl -wMstrict -le 'opendir FOO, "/FOOBAR"; my @x = readdir FOO' readdir() attempted on invalid dirhandle FOO at -e line 1.

    Also, what if the directory is inaccessible, etc... debugging code that doesn't check opendir et al for errors isn't fun. (Note autodie can be useful in addition to Use strict and warnings.)

    I'm guessing that he ... entered them correctly. ... I nver trust user input, I try to check it where I can.

    ?

    The regular expression is there in case there are any blank lines in the directory.txt file

    Just that the regex will also skip files named, for example, 0_0. Probably better to just check the length.

      I agree that checking for errors that don't open the directory isn't fun. I think my comment needs some more explanation though.

      There are only two situations where you should use "open or die". The first is in an academic setting where you are learning the language, sitting at your terminal, and can see when you code exits early and then fix the problem.

      The other situation where "open or die" is the correct thing to do is when you have written a script for yourself, are sitting at your terminal when you run it, and can address anything that causes it to exit early.

      There are, however, a plethora of situations where "open or die" is definitely not the right thing to do:

      • When you have written the script for someone else to run, but they are not a programmer. They are just running the script.
      • When you have the script running as a cron job.
      • When the script is an application on a website processing data input by users.
      • When the script is part of a larger application, especially in an SaaS kind of setting.
      • Probably more but they would just get repetitive.

      In these settings you don't want to use "open or die" because any good data that comes after the bad data doesn't get processed. Had I been hired to write the script above, I would have added an ELSE statement to the "if open" so that I could capture/log the input that failed to open. That way it could be reported, investigated, and corrected.

      In a website/service setting, the "open or die" is not good because it would exit in-elegantly, giving the user a 500 error. Something of no use to anyone except the programmer. What you want is a structure where the error does not crash the program, but rather reports the bad data and keeps processing OR exits in an elegant fashion by telling the user what went wrong and who to contact to fix it. The "open or die" definitely will not do that because the end user doesn't get to see the error logs.

      As I said, there are times when "open or die" is the right choice, but it is never the right choice when compared to the needs of the end client/user who is expecting a result, not an error. In a commercial script (one you are hired to write for someone else), you need to always put the client/user first. "or die" does not do that. Using an "if-else" that will handle the exception elegantly does do that.

      In the OP's situation, he has already been running his data for some time, so he has already validated it. That was why I didn't bother with the "die" or an "else" statement. Had I been hired to write a script to process it, I would have included the else statement to capture the bad data and report it to him so he didn't have to go figuring out what it was. I would have put his needs above my needs.

      I hope that people will think more on the "or die" and when they are implementing it. It serves a purpose, but it's not always the best way to handle an exception.

        Ok - so it sounds like you agree that the return value of calls like open and opendir should always be checked. Whether or not the result of a failed call is to cause the program to abort is definitely a matter of design.

        However, note that there are at least two other ways to catch an open ... or die. There's $SIG{__DIE__}, and there's eval, the latter of which can be made even more useful by a module like Try::Tiny. For CGI scripts, there's CGI::Carp, and other web frameworks have similar ways of gracefully handling errors. And when correctly configured, cron will email warning and error messages to someone who can deal with them.

        Also, since you so clearly state that 'There are only two situations where you should use "open or die".' and 'a plethora of situations where "open or die" is definitely not the right thing to do', I'm going to disagree with you there, on a more philosophical note. You said 'I didn't bother with the "die" or an "else" statement' - in a situation like that, I would still always write either ... or die $!; or at least warn if it really is acceptable for the program to continue in the case of a failure like that (and in my experience, those are much more rare than the cases where it's better to die).

        Code has a way of sneaking into production; copy & paste is many a programmer's best friend. In the case of the code in question, the opendir could fail silently, and the program would give the wrong result; if it had warnings enabled, it would give confusing messages like "readdir() attempted on invalid dirhandle" to the user instead of "Failed to opendir /foo/bar: Permission denied" (and that it's better to Use strict and warnings is attested to by the fact that the code contained a mistake that warnings would have helped catch). So I still say it's better to always, always die or otherwise handle the error.

        he has already been running his data for some time, so he has already validated it. That was why I didn't bother with the "die" or an "else" statement

        Sounds like an exit interview! Or an epitaph. Or famous last words.

        Giving the benefit of the doubt, maybe you are just saying that the program doesn't need specifically to die() on every exception. True, but die() is just one possible course of action after you check the return values of just about every operation and handle the errors usefully (gracefully being a distant second priority). If your program needs to read a directory or open a file, but it can't because the path doesn't exist, that's generally gonna affect the output. 99 times out of a hundred, if you were expecting to be able to open a file or directory and can't, you'll want an opportunity to stop and figure out what's up. That's why die() is so often used on file-opening operations.

        You might also avoid the need to die() if you check for the existence of, or some attribute of, the file before attempting to open it, or in some way avoid the fatal error beforehand. It's fine to trap the error and then continue, but not checking is sloppy, and to the observer, a sign of a programmer who doesn't think things through.

        Also not true that a 500 error is not useful over http. You can control what message is output by die(), and your webserver can have a handler to offer more info, or links out of there, or a game (see Chrome) or whatever. In most web applications it's far more problematic that the server pretends everything is OK so the user won't notice a problem, than if the application produces a useful message on error.


        The way forward always starts with a minimal test.

        Thats some good thinking there :)

        I hope that people will think more on the "or die" and when they are implementing it. It serves a purpose, but it's not always the best way to handle an exception.

        :) it is the best way, because otherwise it isn't an exception, die is for exceptions :D

        sub MyApiCall { open ... or die ... } sub UserInterface { Beginning() or die "nothing to do "; while( NextPiece() ){ eval { MyApiCall (...) ; 1 } or warn "Whooops, trying next one"; } }

        Thats the difference, use die for everything important, for all show stoppers, but trap the exception when its merely a hiccup ... always sugar coat stuff for the end user