Doc #62590 [Asn->Csd]: usort & al : documentation about callback is wrong

From: Date: Fri, 20 Jul 2012 02:36:04 +0000
Subject: Doc #62590 [Asn->Csd]: usort & al : documentation about callback is wrong
References: 1  Groups: php.doc.bugs 
Request: Send a blank email to doc-bugs+get-8593@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=62590&edit=1 ID: 62590 Updated by: googleguy@php.net Reported by: fabien dot delorme at gmail dot com Summary: usort & al : documentation about callback is wrong -Status: Assigned +Status: Closed Type: Documentation Problem Package: Documentation problem Operating System: MacOS lion PHP Version: 5.3.14 Assigned To: googleguy Block user comment: N Private report: N New Comment: This bug has been fixed in the documentation's XML sources. Since the online and downloadable versions of the documentation need some time to get updated, we would like to ask you to be a bit patient. Thank you for the report, and for helping us make our documentation better. Previous Comments: ------------------------------------------------------------------------ [2012-07-20 02:22:15] googleguy@php.net Automatic comment from SVN on behalf of googleguy Revision: http://svn.php.net/viewvc/?view=revision&amp;revision=326718 Log: Added caution for returning non-integer types to help clarify language for usort callback behavior. Address issues raised in Bug #62590 ------------------------------------------------------------------------ [2012-07-20 01:03:42] googleguy@php.net I forget to add that the after the last few values in the resulting array are computed their differences come out to -0.36, 0.41, and 0.05. So as you can see a cast of these values to (int) all result in 0 making the comparison a wash and the documentation notes that values compared as equal will have an undefined order, which is why the order of the last three elements there doesn't seem make any sense. ------------------------------------------------------------------------ [2012-07-20 01:00:12] googleguy@php.net The custom callback function should return an integer value either less-than, greater-than, or equal to zero. For less than, greater than, and equal comparison respectively. The documentation is really wrong here as it does explicitly state "an integer". The code in this example is clearly return floating point numbers. What happens is that the last two values in this array (6.17 and 5.76): Actual result: -------------- array(8) { [0]=> float(15.44) [1]=> float(10.43) [2]=> float(8.62) [3]=> float(8.91) [4]=> float(7.21) [5]=> float(6.12) [6]=> float(5.76) [7]=> float(6.17) } are both cast to integer values behind the scenes (from array.c line 592): long retval; convert_to_long_ex(&retval_ptr); retval = Z_LVAL_P(retval_ptr); zval_ptr_dtor(&retval_ptr); return retval < 0 ? -1 : retval > 0 ? 1 : 0; As you can see the comparison is quite similar to the proposed "return $x == $y ? 0 : ($x < $y ? -1 : 1);" you included here. What is really expected here is ($comparison > 0 || $comparison < 0 || $compirson == 0). I will try to make the documentation more clear about this where possible, but for now this is not concerned a documentation bug. I can appreciate a need for further clarification where subtle details may not be too obvious at first. ------------------------------------------------------------------------ [2012-07-17 19:56:12] fabien dot delorme at gmail dot com Description: ------------ The documentation for usort function (and, it seems, other relative functions, although I haven't tested all of them) is slightly wrong regarding the callback function. It says : "The comparison function must return an integer less than, equal to, or greater than zero if the first argument is considered to be respectively less than, equal to, or greater than the second." However it sometimes results in wrong results if the return value is not precisely -1, 0 or 1. For example, returning $arg2 - $arg1 won't always perform the correct operation. Even if PHP builtin comparison functions all have this behavior (returning precisely -1, 0 or 1), this is not necessarily the case for user-defined functions and either code or documentation should be clear about what values shall be returned. Test script: --------------- $a=array(15.44, 5.76, 10.43, 6.12, 6.17, 7.21, 8.62, 8.91); usort($a, function($x, $y) {return $y - $x; }); var_dump($a); // The above would work if the lambda was something like // function($x, $y) { return $x == $y ? 0 : ($x < $y ? -1 : 1);} Expected result: ---------------- array(8) { [0]=> float(15.44) [1]=> float(10.43) [2]=> float(8.91) [3]=> float(8.62) [4]=> float(7.21) [5]=> float(6.17) [6]=> float(6.12) [7]=> float(5.76) } Actual result: -------------- array(8) { [0]=> float(15.44) [1]=> float(10.43) [2]=> float(8.62) [3]=> float(8.91) [4]=> float(7.21) [5]=> float(6.12) [6]=> float(5.76) [7]=> float(6.17) } ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=62590&edit=1

« previous php.doc.bugs (#8593) next »