in reply to Need help with a conceptual speed bump

Lose the ingrained attitude.

The advice about symbolic refs applies to people who are using them to store an unknown amount of arbitrary data and who don't realize that they may accidentally create clashes between different parts of their code, and that they might wipe out something important.

You're using them for meta-programming, which is exactly what they are good for.

Incidental question. Why are you returning the string 'SUCCESS' rather than just using true/false normally? (Using true/false would seem like less code, should run faster, and reduces opportunities for typing something like 'SUCCSES' to make for a runtime logic error that might not be easy to spot.)

  • Comment on Re: Need help with a conceptual speed bump

Replies are listed 'Best First'.
Re^2: Need help with a conceptual speed bump
by mstone (Deacon) on May 03, 2005 at 23:33 UTC

    Incidental question. Why are you returning the string 'SUCCESS' rather than just using true/false normally?

    Readability in the sample code. In real life, I'd probably return undef for success, an arbitrary error description string for failure, and use if ($result->{$key}) to scan for errors.

    I do prefer human-readable error messages over simple booleans, though. They give me better feedback, and more ways to track down errors while debugging.

    Your brick upside the head is appreciated, though. That's two people whose opinions I respect not telling me that I've gone completely wacko. Thanks.

      My inclination for something this unlikely to go wrong, and where going wrong is a real error, is to return the set value and throw an exception if there is a problem.

      Another common strategy is to return true/false to be interpreted normally and then make the error available elsewhere. For instance DBI does this, with the error in the errstr method.

      A cute idea that I just had is that you could return a true value for success, and an overloaded false string for failure.

        Point taken. I was thinking about stuff like a validation function, which in this model would be about three steps down the call chain from the client's get() call. Code like that would be designed to fail at specific times and for specific reasons, and is the best source for information about which zero/one/many conditions the input failed to meet.

        Silent-on-success/noisy-on-failure is conceptually similar to throwing an exception. The code up the call chain that tests/reads the result string is vaguely like a series of exception handlers. You do have to organize the code a little differently, walling off any code that shouldn't execute with bad data behind a conditional, but in most cases that isn't too difficult. The main trick is to avoid putting a big list of things that can fail all in the same function.

        I generally solve that problem by iterating over a list of function pointers and dropping out of the loop if something fails. And whenever possible, I prefer to run the whole loop, collect all the errors, and then proceed or exit based on the existence/nonexistence of one or more failures. That keeps me from ripping out what little hair I have left because of the old, "okay, I solved the problem that made the code choke there, and now it's choking in the next condition three lines further on," scenario.

        Sometimes you do run into logic that requires exceptions, but this works pretty well for me most of the time.

        The overloaded FALSE string does sound like fun, though.. I may have to play with that one of these days when I'm feeling silly.