rfc:user_defined_operator_overloads
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revisionNext revisionBoth sides next revision | ||
rfc:user_defined_operator_overloads [2021/12/07 21:37] – Reflection jordanrl | rfc:user_defined_operator_overloads [2021/12/11 09:34] – typo jordanrl | ||
---|---|---|---|
Line 1: | Line 1: | ||
====== PHP RFC: User Defined Operator Overloads ====== | ====== PHP RFC: User Defined Operator Overloads ====== | ||
- | * Version: 0.5 | + | * Version: 0.6 |
* Date: 2021-08-14 | * Date: 2021-08-14 | ||
* Author: Jordan LeDoux, jordan.ledoux@gmail.com | * Author: Jordan LeDoux, jordan.ledoux@gmail.com | ||
Line 338: | Line 338: | ||
Because comparisons have a reflection relationship instead of a commutative one, the $operandPos argument is omitted as it could only be used for evil (making '' | Because comparisons have a reflection relationship instead of a commutative one, the $operandPos argument is omitted as it could only be used for evil (making '' | ||
- | Comparison | + | Equality and comparison |
The signature for the equals operator has the additional restriction of returning '' | The signature for the equals operator has the additional restriction of returning '' | ||
Line 352: | Line 352: | ||
Any return value larger than 0 will be normalized to 1, and any return value smaller than 0 will be normalized to -1. | Any return value larger than 0 will be normalized to 1, and any return value smaller than 0 will be normalized to -1. | ||
- | The $operandPos argument is omitted as it could only be used for evil e.g. implementing different comparison logic depending on which side its on. Instead of passing $operandPos the engine will multiply the result of the call by (-1) where appropriate: | + | The $operandPos argument is omitted as it could only be used for evil e.g. implementing different comparison logic depending on which side it' |
<code php> | <code php> | ||
Line 412: | Line 412: | ||
Several changes to reflection must be made to support this feature. | Several changes to reflection must be made to support this feature. | ||
- | === Changes to getMethods(), | + | === Changes To ReflectionClass === |
+ | |||
+ | == Changes to getMethods(), | ||
These methods need to be updated to ignore the operator methods. Since these are stored internally like any other function on the class entry, they need to be filtered from the results. | These methods need to be updated to ignore the operator methods. Since these are stored internally like any other function on the class entry, they need to be filtered from the results. | ||
- | The reason for removing the operators from this result is because the operator methods are not callable with string literals on the object. Since they cannot be called like a method is, the should be returned with the other methods on a class. | + | The reason for removing the operators from this result is because the operator methods are not callable with string literals on the object. Since they cannot be called like a method is, they should |
- | === Adding getOperators(), | + | == Adding getOperators(), |
These methods must be added to interact with the function handlers for the operator implementations. They will act as an inverse to the changes above. | These methods must be added to interact with the function handlers for the operator implementations. They will act as an inverse to the changes above. | ||
Operator methods will be represented by an instance of '' | Operator methods will be represented by an instance of '' | ||
+ | |||
+ | === Changes To ReflectionMethod === | ||
+ | |||
+ | == New Method isOperator() == | ||
+ | |||
+ | Returns true if the method being reflected uses the '' | ||
===== FAQ ===== | ===== FAQ ===== | ||
Line 511: | Line 519: | ||
<code php> | <code php> | ||
- | function processMoneyValues(Money $left, Money $right) | + | class Money { |
- | { | + | operator +(Money $other, OperandPosition |
- | return $left + $right; | + | |
} | } | ||
- | processMoneyValues( | + | $result = new Money(5, ' |
- | | + | |
- | | + | |
- | ); | + | |
// Type error, Vector2d can't be used as Money | // Type error, Vector2d can't be used as Money | ||
</ | </ | ||
- | This can also be caught by typing the arguments to the operator implementations themselves. | + | This can also be caught by typing the arguments to a helper function: |
<code php> | <code php> | ||
- | class Money { | + | function processMoneyValues(Money $left, Money $right) |
- | operator +(Money $other, OperandPosition | + | { |
+ | return $left + $right; | ||
} | } | ||
- | $result = new Money(5, ' | + | processMoneyValues( |
+ | | ||
+ | | ||
+ | ); | ||
// Type error, Vector2d can't be used as Money | // Type error, Vector2d can't be used as Money | ||
Line 614: | Line 622: | ||
// The rest of the extension' | // The rest of the extension' | ||
</ | </ | ||
+ | |||
+ | To further help extensions support this feature, there are two helper functions: | ||
+ | |||
+ | <code c> | ||
+ | int has_overload = zend_std_has_op_overload(opcode, | ||
+ | |||
+ | zend_function overload_method = zend_std_get_op_overload(opcode, | ||
+ | </ | ||
+ | |||
+ | It is safe to pass any zval pointer to '' | ||
==== To Opcache ==== | ==== To Opcache ==== |
rfc/user_defined_operator_overloads.txt · Last modified: 2022/01/17 01:16 by jordanrl