Doc #62590 [Asn->Csd]: usort & al : documentation about callback is wrong
| From: | googleguy@php.net | 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&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