Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:69605 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 25498 invoked from network); 17 Oct 2013 11:57:12 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 17 Oct 2013 11:57:12 -0000 X-Host-Fingerprint: 80.4.21.210 cpc22-asfd3-2-0-cust209.1-2.cable.virginmedia.com Received: from [80.4.21.210] ([80.4.21.210:10992] helo=localhost.localdomain) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id C9/C2-12663-290DF525 for ; Thu, 17 Oct 2013 07:57:09 -0400 To: internals@lists.php.net,Sebastian Krebs Message-ID: <525FD08F.8000100@php.net> Date: Thu, 17 Oct 2013 12:57:03 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130625 Thunderbird/17.0.7 MIME-Version: 1.0 References: <525FC834.4060501@php.net> In-Reply-To: Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Posted-By: 80.4.21.210 Subject: Re: [PHP-DEV] Assertions From: krakjoe@php.net (Joe Watkins) On 10/17/2013 12:45 PM, Sebastian Krebs wrote: > 2013/10/17 Joe Watkins > >> On 10/17/2013 11:51 AM, Julien Pauli wrote: >> >>> On Thu, Oct 17, 2013 at 9:25 AM, Joe Watkins wrote: >>> >>> Morning All, >>>> >>>> I'd like to draw some attention to how poor assertions are in >>>> PHP. >>>> >>>> The current assertion API is not usable in my opinion; it has a >>>> considerable overhead, relies on eval(), and is generally poorly >>>> implemented. >>>> >>>> I have done some work toward implementing assert at the Zend >>>> level, giving assertions a more modern, usable feel to them. >>>> >>>> https://github.com/krakjoe/****php-src/compare/assert >>>> >>>>> >>>> >>>> This implementation of assert removes the old implementation and >>>> associated functions and INI settings, and replaces it with a single INI >>>> setting to control assertion compilation. >>>> >>>> Failed assertions throw an AssertionException (which extends >>>> ErrorException 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 assertion >>>> causing no error, because strings are no longer treated as code, because >>>> eval is evil(); >>>> >>>> Setting zend.assertions=0 system configuration setting will stop >>>> ZEND_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 ?? >>>> >>> >>> >>> 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, >> >> That was brought up in IRC yesterday, someone pointed out that >> generators 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 is >> the 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's >> a 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 invoke >> a 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?"; >> } >> > > 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)) { > echo "oh rly?"; > } > > /** > * @var FooObject $foo properly set up FooObject-object > */ > function getByName (FooObject $foo) { > assert($foo->getName()); // unusable without name. You use this > function wrong. Fix your application!!! > } > > >> >> Makes much more sense ... I would rather encourage or even require >> that than reimplement callbacks ... they only seemed to exist to service >> the current implementation. >> >> In summary then, I think exceptions make more sense than errors >> and callbacks ... >> >> So what do we think about callbacks and errors now, am I making >> any sense ?? > > > 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. > > >> >> >> 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