Both sides previous revisionPrevious revisionNext revision | Previous revisionNext revisionBoth sides next revision |
rfc:proper-range-semantics [2023/03/30 13:30] – Version 0.2 girgias | rfc:proper-range-semantics [2023/05/08 14:31] – Fix grammar in several places theodorejb |
---|
| |
* If both start and end values are strings with at least one byte (e.g. <php>range('A', 'Z');</php>, <php>range('AA', 'BB');</php>, or <php>range('15', '25');</php>): | * If both start and end values are strings with at least one byte (e.g. <php>range('A', 'Z');</php>, <php>range('AA', 'BB');</php>, or <php>range('15', '25');</php>): |
* If one of the inputs is a float numeric string, or the <php>$step</php> parameter is a float: go to the handle float input branch | * If one of the inputs is a float numeric string, or the <php>$step</php> parameter is a float: go to the handle float input branch. |
* If one of the inputs is an integer numeric string: go to the generic handling branch | * If one of the inputs is an integer numeric string: go to the generic handling branch. |
* Otherwise: discard every byte after the first one and return an array of ASCII characters going from the start ASCII code point to the end ASCII code point. | * Otherwise: discard every byte after the first one and return an array of ASCII characters going from the start ASCII code point to the end ASCII code point. |
* If one of the start or end value is a float or the <php>$step</php> parameter is a float (e.g. <php>range(10.5, 12);</php>, <php>range(1, 3, 1.5);</php>, or <php>range(1, 3, 1.0);</php>): cast start and end values to float and return an array of floats | * If the start or end value is a float or the <php>$step</php> parameter is a float (e.g. <php>range(10.5, 12);</php>, <php>range(1, 3, 1.5);</php>, or <php>range(1, 3, 1.0);</php>): cast start and end values to float and return an array of floats. |
* Otherwise (generic handling): cast start and end values to int and return an array of int. | * Otherwise (generic handling): cast start and end values to int and return an array of integers. |
| |
The generic case will accept //any// type. | The generic case will accept //any// type. |
==== Issues surrounding usage of INF and NAN values ==== | ==== Issues surrounding usage of INF and NAN values ==== |
| |
Infinite values are handles as part of the range boundary checks, or for the <php>$step</php> parameter when checking that the step is less than the range being requested, and will throw ValueErrors. | Infinite values are handled as part of the range boundary checks, or for the <php>$step</php> parameter when checking that the step is less than the range being requested, and will throw ValueErrors. |
| |
However, NAN values are not specifically handled and result in nonsensical ranges: | However, NAN values are not specifically handled and result in nonsensical ranges: |
</PHP> | </PHP> |
| |
Where using a NAN values as a step even breaks the expectation that <php>range()</php> will return a non empty list. | Where using a NAN value as a step even breaks the expectation that <php>range()</php> will return a non empty list. |
| |
| |
The changes are as follows: | The changes are as follows: |
| |
* If <php>$step</php> is a float but is compatible with ''int'' interpret it as an integer. | * If <php>$step</php> is a float but is compatible with ''int'' (i.e. <php>(float)(int)$step === $step</php>) interpret it as an integer. |
* Introduce and use a proper ZPP check for ''int|float|string'' <php>$start</php> and <php>$end</php> parameters, this will cause <php>TypeError</php>s to be thrown when passing objects, resources, and arrays to <php>range()</php>. It will also cause a deprecation warning to be emitted when passing ''null''. | * Introduce and use a proper ZPP check for ''int|float|string'' <php>$start</php> and <php>$end</php> parameters; this will cause <php>TypeError</php>s to be thrown when passing objects, resources, and arrays to <php>range()</php>. It will also cause a deprecation warning to be emitted when passing ''null''. |
* Throw value errors if <php>$start</php>, <php>$end</php>, or <php>$step</php> is a non-finite float (-INF, INF, NAN). | * Throw value errors if <php>$start</php>, <php>$end</php>, or <php>$step</php> is a non-finite float (-INF, INF, NAN). |
* Throw a more descriptive <php>ValueError</php> when <php>$step</php> is zero. | * Throw a more descriptive <php>ValueError</php> when <php>$step</php> is zero. |
* Throw a <php>ValueError</php> when passing a negative <php>$step</php> for increasing ranges. | * Throw a <php>ValueError</php> when passing a negative <php>$step</php> for increasing ranges. |
* Emit an <php>E_WARNING</php> when <php>$start</php> or <php>$end</php> is the empty string, and cast the value to ''0'' | * Emit an <php>E_WARNING</php> when <php>$start</php> or <php>$end</php> is the empty string, and cast the value to ''0'' |
* Emit an <php>E_WARNING</php> when <php>$start</php> or <php>$end</php> has more than one byte. | * Emit an <php>E_WARNING</php> when <php>$start</php> or <php>$end</php> has more than one byte if it is a non-numeric string. |
* Emit an <php>E_WARNING</php> when <php>$start</php> or <php>$end</php> is cast to an integer because the other boundary input is a number or numeric string. (e.g. <php>range('5', 'z');</php> or <php>range(5, 'z');</php>) | * Emit an <php>E_WARNING</php> when <php>$start</php> or <php>$end</php> is cast to an integer because the other boundary input is a number or numeric string. (e.g. <php>range('5', 'z');</php> or <php>range(5, 'z');</php>) |
* Emit an <php>E_WARNING</php> when <php>$step</php> is a float when trying to generate a range of characters. | * Emit an <php>E_WARNING</php> when <php>$step</php> is a float when trying to generate a range of characters. |
<php>E_WARNING</php>s are emitted for various issues. | <php>E_WARNING</php>s are emitted for various issues. |
| |
Calls to <php>range()</php> that have integer boundaries but a float step that is compatible as an integer will now return an array of integers instead of an array of float: | Calls to <php>range()</php> that have integer boundaries but a float step that is compatible as an integer will now return an array of integers instead of an array of floats: |
<PHP> | <PHP> |
var_dump( range(1, 5, 2.0) ); | var_dump( range(1, 5, 2.0) ); |