php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #49934 Add possibility to pass callbacks to assert()
Submitted: 2009-10-20 14:38 UTC Modified: 2017-08-24 13:31 UTC
From: ninzya at inbox dot lv Assigned: tpunt (profile)
Status: Closed Package: *General Issues
PHP Version: * OS: *
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: ninzya at inbox dot lv
New email:
PHP Version: OS:

 

 [2009-10-20 14:38 UTC] ninzya at inbox dot lv
Description:
------------
The current assert() implementation is very uncomfortable, for me at least. assert() does not skip code execution inside it's parentheses when assertions are disabled. Also, when you are using strings to optimize runtime of app having full of assert()s around in cases like this - assert( 'return false;') - is very hard to read, and, if variables are being also involved, the code looks very ugly and is error prone.

I would like to propose to take the full advantage of closures and add possibility to pass callbacks to assert() function. Passing callbacks to this function would solve the both problems - bring in the readability, and would optimize runtime by not calling callbacks when assertions are disabled. The effect would be the same as if using strings as parameters, but the code would become more readable a look more nicer.

Here is an example of how does assert() code look like in current PHP versions. Assume foo() is a method of an object:

function foo( $bar) {
  // This way of testing assertion
  //  results in a low performance, because when you disable
  //  assertions, the code between parentheses is still being
  //  executed, thus, resulting in a waste of computer resources.
  assert( !$bar->testAssert( '5'));

  // Another way of testing assertion. This is more optimized,
  //  because the passed string is not eval()ed when assertion
  //  checking is disabled. Good, but... strings? Unreadable,
  //  ugly, error prone. Yes, i know, i could use double-quotes
  //  here, but that's not the point, strings are no way to good,
  //  maintainable code.
  assert( '!$bar->testAssert( \'5\')');
}

Here is an example of what i would like to see in PHP:

function foo( $bar) {
  // The new way of testing assertion. Code is good, IDEs can take
  //  advantage of a PHP syntax and highlight the statements for me
  //  in my closure. Readable, sexy, way better, than having strings.
  //  Also, closures allow to encapsulate larger blocks of code, which
  //  with string approach would result in a multi-line string
  //  concatenation hell.
  assert( function(){
    return $bar->testAssert( 5);
  });

  // As closures are callbacks by their type, the string callback also
  //  should be valid as assert()'s param:
  assert( 'MyClass::myTestAssertion');
}

And here comes the problem, right, how to distinguish between strings of code ('!$bar->testAssert( \'5\')') and strings - callbacks ('MyClass::myTestAssertion')? Right, there's no good way to do this, so i propose to create a separate version of assert(), for example, assert_cb() (assert by callback), to maintain compatibility with those, who use the old assertion testing approach.

Reproduce code:
---------------
-

Expected result:
----------------
-

Actual result:
--------------
-

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-10-20 14:54 UTC] ninzya at inbox dot lv
This is what i use right now in my apps:

/**
 * Check if assertions are true (only in debug mode)
 *
 * @param callback.. $callbacks
 */
function assert_cb() {
  if( !DEBUG_MODE)
    // do not test for assertions in non-debug mode
    return;
  
  // we assume that all arguments are callbacks, so we
  //  execute them one by one, until we get 'false' as a
  //  result.
  foreach( func_get_args() as $cb) {
    if( call_user_func( $cb) ===false) {
      // assertion has failed
      throw new Exception( 'ASSERT_FAILED');
      
    }
  }
  
  // all assertions are valid
}
 [2010-12-17 12:14 UTC] jani@php.net
-Package: Feature/Change Request +Package: *General Issues -Operating System: any +Operating System: * -PHP Version: 5.3SVN-2009-10-20 (SVN) +PHP Version: *
 [2017-08-24 13:31 UTC] tpunt@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: tpunt
 [2017-08-24 13:31 UTC] tpunt@php.net
Zero cost assertions were introduced into PHP 7.0, so I'm closing this issue.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Apr 19 01:01:28 2024 UTC