Re: exceptions
| From: | Greg Beaver | Date: | Tue, 08 Jun 2004 18:57:47 +0000 |
| Subject: | Re: exceptions | ||
| References: | 1 2 3 4 5 6 7 | Groups: | php.pear.dev |
| Request: | Send a blank email to pear-dev+get-30200@lists.php.net to get a copy of this message | ||
Hans Lellelid wrote:
I'm not bashing PEAR, I'm laughing at it. :) j/k ... well, to be precise, I'm laughing at these ideas that exceptions are bad because they're different and encapsulation is bad because it adds methods.I think both sides need to stop thinking of this in the abstract. Encapsulation is not necessarily going to cause tremendously noticeable speed differences in code, mainly because most properties are not a simple: $obj->a = 6; Most object properties are complex arrays or other objects that require some setup to get them working right. The question is do you force your users to write this setup every time, or do it inside a getter/setter? On the other hand, some code really doesn't require any setup at all and is used millions of times in a single program, and so providing a getter/setter makes little sense, since performance will take a noticeable hit. PEAR_PackageFileManager has a single array with 5 or 6 getter/setters to the same variable! In fact, PEAR_Common's decision to expose the internal array that results from parsing package.xml means that we are forced to use that format for BC reasons, and it also makes verifying BC extremely difficult, as every single array index must be tested to be certain. PEAR_PackageFile (in the devel work I'm doing on PEAR 1.4) solves this issue by having BOTH getter/setters for individual properties and the ability to setup the object by passing in a complete array. In both cases, input must be validated prior to use. DB_Dataobject's representation of a database record is essentially a glorified array, but this is OK because validation is done only when needed, on insert/update/delete. Forcing getters/setters does not make sense here. It is pretty obvious to me that specifying a standard way of doing things here would be nothing short of stupid - you can't standardize algorithms that people use to solve future problems, why standardize the API decisions? It is enough to ask new devs to learn from the mistakes of the existing packages, and to offer advice. Crappy code can always be removed if it really sucks. The best we can do with regulation is to require ALL packages that rewrite to take advantages of PHP5 to remain alpha for at least 2 or three releases, so that dumb design choices can be changed when they are discovered to be as such.
Plus, the analogy is really funny to me. Don't get me wrong, I'm not criticizing PEAR; I'm criticizing what to me are very dumb-sounding proposed policies. I think that I and many other PHP developers have been excited to see PHP5 do away with conventions like PEAR_Error -- which admittedly is a good solution for PHP4 (not as good as ErrorStack, but still pretty good).Let's get a few other things straight: - Exceptions are designed to handle exceptional situations. - PEAR_Error is designed to handle everything, but in a way that is not compatible with php5 exceptions due to lack of ESP (forgiveable offense :) - PEAR_ErrorStack is designed to centralize informational output that relates to unusual code situations. Unusual code situations include: * debug output * administrator information * warnings/notices/errors * exceptions (faults) Note that exceptions are only about 1/4 of typical unusual code situations. Exceptions, like anything else of that ilk, are designed to make it easier to find mistakes in your code or your program's input, and to recover from them gracefully. Notice that most of the problems found through pear-general come from users running pear -vvv. This causes tons of informational output to be produced, and is much more important than even basic error handling. PEAR_ErrorStack is designed to allow easy logging and display of this type of information, regardless of the source. This means you can continue to use Exceptions for the narrow purpose they fulfill, but have a common logging object for exceptions, PEAR_Error for legacy apps, trigger_error() for Smarty, PHP warnings/notices/errors, custom warnings/notices in your own code, and any informational or debug output that may be necessary. Exceptions will never remove the need for code that logs and handles unusual output, let's get that straight right now. Even if you only use exceptions, if you wish to do any advanced logging, you must either call a logging method in *every* catch() block: <?php define('FRUNK_ERROR_SOMETHING', 1); try { frunk(); } catch (Exception $e) { logException($e); // handle exception } function frunk() {
throw new Exception('oops');
}
?>
or let a package like errorstack do it for you - with the user's option of CHANGING the logging at any point in the code, something that would be absolutely onerous with the solution above.
<?php
define('FRUNK_ERROR_SOMETHING', 1);
require_once 'PEAR/ErrorStack.php';
try {
frunk();
} catch (Exception $e) {
logException($e);
// handle exception
}
function frunk()
{
throw PEAR_ErrorStack::staticPush('frunk', FRUNK_ERROR_SOMETHING, 'exception', array(), 'oops');
}
?>
Let's stop quibbling about either/or - there's no point. Programming will ALWAYS need both solutions. As there is nothing satisfactory built into the language (yet?), packages like PEAR_ErrorStack will fill that void until PHP does.
Greg