Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

-1 as a return value

Tags:

php

This question is specifically about PHP, but I'm guessing it might be applicable to other languages as well.

I've noticed that between PHP4 and PHP5, the designers of the language shifted away from using -1 as a return value to using constants or other forms of output. This makes sense, as -1 is not particularly evocative, and I'm guessing this practice led to confusion.

That said, I am sometimes inclined to return -1 when I want to quickly add another return option to a function, and -1 often seems like a perfectly valid way to express the outcome I am coding for.

So here are my questions:

  1. Is my observation generally correct, regarding the move away from -1 as a return value in PHP5 vs PHP4?

  2. What are the cons of returning -1, beyond for the reason I mentioned above, wherein the -1 return value doesn't contribute positively to code clarity?

like image 476
Dmitry Minkovsky Avatar asked Jan 17 '23 09:01

Dmitry Minkovsky


2 Answers

This is just a hunch, but in my experience there is little reason or consistency to design choices in PHP. I also find a lot of functions that return FALSE on failure, many with an added note that you have to explicitly distinguish between FALSE and other (valid) values that coerce to FALSE, e.g. 0. In such cases I think -1 is a much nicer return value.

Of course you could always just return -1 and define constants that have meaningful names and are just mapped to -1.

like image 177
Joey Avatar answered Jan 18 '23 22:01

Joey


I would guess that any PHP functions that still return -1 are doing so for legacy reasons.

For simple functions where there's a logical, reasonable error response that doesn't involve returning a cryptic numeric code, then that should be used. For example, returning null, false, or 0 might be enough to communicate what happened. But for more complicated functions, especially those that can have multiple failure modes, consider breaking them up into different functions that each handle a smaller chunk of the overall task.

You can also throw exceptions:

function doSomething() {
    if (fooFails()) {
        throw new Exception('Foo failed to work properly.');
    } else if (barFails()) {
        throw new Exception('Bar failed this time.');
    }

    return "blahblah";
}

You can also subclass the Exception class to provide even more specificity, and you can detect which one by using a try-catch block. In general, I think it's better to use Object-Oriented principles like this. It produces code that's much clearer and maintainable, especially 6 months down the line after you've completely forgotten why you wrote your code the way you did.

class FooException extends Exception {
    // nothing else needed here
}

class BarException extends Exception {
    // nothing else needed here
}

function doSomething() {
    if (fooFails()) {
        throw new FooException();
    } else if (barFails()) {
        throw new BarException();
    }

    return "blahblah";
}

Then you can use:

try {
    $output = doSomething();

} catch (FooException $e) {
    // respond to the FooException case

} catch (BarException $e) {
    // respond to the BarException case

} catch (Exception $e) {
    // respond to any and all other exceptions that might be thrown
}
like image 21
curtisdf Avatar answered Jan 18 '23 22:01

curtisdf