Re: Assertions
| From: | Joe Watkins | Date: | Thu, 17 Oct 2013 11:57:03 +0000 |
| Subject: | Re: Assertions | ||
| References: | 1 2 3 4 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-69605@lists.php.net to get a copy of this message | ||
On 10/17/2013 12:45 PM, Sebastian Krebs wrote:
2013/10/17 Joe Watkins <krakjoe@php.net>On 10/17/2013 11:51 AM, Julien Pauli wrote:Actually if an assertion fails it means, that the application is totally broken and cannot get recovered. The use case you describe is more like "validation". This means, that even if it throws an AssertionException, when you are able to catch it and recover the process, it means, that "assert" was the wrong choice if (!$expression && !(CONSTANT_MASK & HAS_BITS)) {On Thu, Oct 17, 2013 at 9:25 AM, Joe Watkins <krakjoe@php.net> wrote: Morning All,I like the idea. However, there is always the debatte about if a Core feature should throw an Exception or generate an error. In our current system, they don't throw Exceptions but generate errors. Also : someone could use a callback, and then make them throw exceptions if he wants to ; the callback on assertion fail, which IMO is a good feature, has dissapeared in your patch. Julien.Pauli Morning Julien,I'd like to draw some attention to how poor assertions are inPHP.The current assertion API is not usable in my opinion; it has aconsiderable overhead, relies on eval(), and is generally poorly implemented.I have done some work toward implementing assert at the Zendlevel, giving assertions a more modern, usable feel to them.https://github.com/krakjoe/****php-src/compare/assert<https://github.com/krakjoe/**php-src/compare/assert><https:/**/github.com/krakjoe/php-src/**compare/assert<https://github.com/krakjoe/php-src/compare/assert>This implementation of assert removes the old implementation andassociated functions and INI settings, and replaces it with a single INI setting to control assertion compilation.Failed assertions throw an AssertionException (which extendsErrorException with a severity of E_ERROR), setting the message of the exception to the expression asserted.The syntax of assertion is the same as [all] other languages:T_ASSERT expr ';'This means that assert("some code here") will pass assertioncausing no error, because strings are no longer treated as code, because eval is evil();Setting zend.assertions=0 system configuration setting will stopZEND_ASSRT compilation.So, we have:try { assert (PHP != JUNK);} catch(AssertionException $ex) { printf("Assertion failed: %s\n", $ex->getMessage()); printf("Something is horribly wrong ...\n"); }Better, no ??That was brought up in IRC yesterday, someone pointed out thatgenerators throw exceptions in some places (from an object method, but still). So it's not unprecedented, and nobody has provided reason for the preference to use errors over exceptions ... however, general case aside:Throwing exceptions here makes much more sense than errors, and isthe reason there is no need for callbacks; should you need to control the flow of execution or take some action because of a failed assertion you can catch the AssertionException and do that without cluttering ini and module globals in order to do it.In general, of course, an assertion should abort execution, that'sa bit final for PHP and runs contrary to carry-on-executing-no-matter-**what, which we like, on the interweb. But, should you need to take some action and stop that exception from bubbling to the surface you should do that with language constructs try/catch rather than dated callbacks, which don't give you the same kind of recovery options so easily, they additionally require a new scope, a new function entry, module globals for support, and ini settings to configure ...That being said, I would rather reimplement the ability to invokea callback than scrap the idea all together ... but might we have something a bit more PHP5 ??assert( $expression != false || (CONSTANT_MASK & HAS_BITS), function(){ echo "oh rly?"; } );I still think it's a bit unnecessary, and this:try { assert($expression != false || (CONSTANT_MASK & HAS_BITS));} catch (AssertionException $ex) { echo "oh rly?"; }echo "oh rly?";} /** * @var FooObject $foo properly set up FooObject-object */ function getByName (FooObject $foo) {assert($foo->getName()); // unusable without name. You use thisfunction wrong. Fix your application!!! }While tinking about it: As assertions are a way to describe conditions, that are valid _in every case_ (or else the application is unrecoverable broken), it is somehow different from just "exeptional cases", that may be recovered during runtime. Therefore I'd prefer "the hard with" with errors and such. I think they are somehow comparable to compile-errors, but during runtime. Or with a "LogicException", that isn't simply (and without side effects) solveable by replacing the value of one variable with another one.Makes much more sense ... I would rather encourage or even requirethat than reimplement callbacks ... they only seemed to exist to service the current implementation.In summary then, I think exceptions make more sense than errorsand callbacks ...So what do we think about callbacks and errors now, am I makingany sense ??Cheers Joe -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Actually if an assertion fails it means, that the application is totally broken and cannot get recovered.If a failed assertion should _just_ abort execution then a callback, or catch block are not even required. Never mind the example, the point is that a callback does the same job as a catch block, without requiring module globals, ini settings, and supporting functions etc ... Cheers Joe