rfc:lazy-objects
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
rfc:lazy-objects [2024/07/24 14:50] – lbarnaud | rfc:lazy-objects [2024/08/30 15:32] (current) – Status: Implemented lbarnaud | ||
---|---|---|---|
Line 4: | Line 4: | ||
* Date: 2024-06-03 | * Date: 2024-06-03 | ||
* Author: Arnaud Le Blanc < | * Author: Arnaud Le Blanc < | ||
- | * Status: | + | * Status: |
* First Published at: https:// | * First Published at: https:// | ||
Line 174: | Line 174: | ||
* Calling < | * Calling < | ||
* Calling < | * Calling < | ||
+ | * Cloning (see the " | ||
This behavior makes lazy objects fully transparent to their consumers. | This behavior makes lazy objects fully transparent to their consumers. | ||
Line 186: | Line 187: | ||
* Calls to < | * Calls to < | ||
* Calls to < | * Calls to < | ||
- | * Cloning, unless '' | ||
By excluding these cases from triggering initialization, | By excluding these cases from triggering initialization, | ||
Line 206: | Line 206: | ||
- Before calling the initializer, | - Before calling the initializer, | ||
- The initializer is called with the lazy proxy as first parameter. | - The initializer is called with the lazy proxy as first parameter. | ||
- | - The return value of the initializer has to be an instance the same class as the lazy-object, | + | - The return value of the initializer has to be an instance the same class as the lazy-object, |
- The real instance is set to the return value. | - The real instance is set to the return value. | ||
- | - The value of properties used with < | + | - The value of properties used with < |
- | - Properties | + | - After that, any property access |
The proxy object is _not_ replaced or substituted for the real instance. After initialization, | The proxy object is _not_ replaced or substituted for the real instance. After initialization, | ||
Line 215: | Line 215: | ||
The real instance is allowed to escape the proxy and to create direct references to itself. This is demonstrated in the section named "About Proxies" | The real instance is allowed to escape the proxy and to create direct references to itself. This is demonstrated in the section named "About Proxies" | ||
- | Although the initializer receives the proxy object as first parameter, it is not expected to make changes to it (this is allowed, but any changes will be lost during the last step of the initialization). However, the proxy object can be used to make decisions based on the value of some initialized property, or on the class or the object, or on its identity. For example, the initializer may use the value of an initialized property: | + | Although the initializer receives the proxy object as first parameter, it is not expected to make changes to it (this is allowed, but any changes will be lost during the last step of the initialization). However, the proxy object can be used to make decisions based on the value of some initialized property, or on the class or the object, or on its identity. For example, the initializer may use the value of an initialized property |
<PHP> | <PHP> | ||
Line 222: | Line 222: | ||
}); | }); | ||
</ | </ | ||
- | |||
- | < | ||
=== Common Behavior === | === Common Behavior === | ||
Line 404: | Line 402: | ||
</ | </ | ||
- | If the object is already | + | |
+ | If the object is an initialized | ||
+ | |||
+ | If the object is lazy and non-initialized, a < | ||
Objects whose all properties were initialized are not lazy anymore, as specified in the " | Objects whose all properties were initialized are not lazy anymore, as specified in the " | ||
Line 446: | Line 447: | ||
The < | The < | ||
- | Its behavior is the same as described for Ghost Objects in the Initialization Sequence section, except that the initializer is not called. | + | Its behavior is the same as described for Ghost Objects in the Initialization Sequence section, except that the initializer is not called. After that, the object is indistinguishable from an object that was never lazy, and was created with < |
The return value is the object itself. | The return value is the object itself. | ||
Line 509: | Line 510: | ||
==== Cloning ==== | ==== Cloning ==== | ||
- | Cloning a lazy object triggers its initialization. | + | Cloning a lazy object triggers its initialization |
- | For ghost objects: The object is cloned and the clone is returned. | + | For proxy objects, the proxy and its real instance are cloned, and the proxy clone is returned. The < |
- | For proxy objects: The proxy object and its real instance are cloned. The < | + | Rationale: Initialization before cloning ensures that a clone and the original object have separate states. That is, updating the original object or the state of its initializer after cloning should not have an impact on the clone. Cloning the proxy and its real instance, rather than returning a clone of the real instance, ensures that the < |
- | + | ||
- | Rationale: Initialization before cloning ensures that a clone and the original object have separate states. That is, updating the original object or the state of its initializer after cloning should not have an impact on the clone. | + | |
==== Readonly properties ==== | ==== Readonly properties ==== | ||
Line 562: | Line 561: | ||
<PHP> | <PHP> | ||
class Connection { | class Connection { | ||
+ | public $prop; | ||
public function __construct() { | public function __construct() { | ||
$this-> | $this-> | ||
Line 573: | Line 573: | ||
$reflector = new ReflectionClass(Connection:: | $reflector = new ReflectionClass(Connection:: | ||
- | $connection = $reflector-> | + | $reflector-> |
$connection = null; // Does not call destructor (object is not initialized) | $connection = null; // Does not call destructor (object is not initialized) | ||
Line 765: | Line 765: | ||
Returning an instance of a parent class is not allowed if the proxy class declares additional properties. It would imply that the proxy has a state of its own, which is far-reaching in the implementation. This would impact the behavior of < | Returning an instance of a parent class is not allowed if the proxy class declares additional properties. It would imply that the proxy has a state of its own, which is far-reaching in the implementation. This would impact the behavior of < | ||
- | Furthermore, | + | Furthermore, |
In use-cases where the proxy and the real instance are not instances of the same class, the proxy is considered to be aware of laziness, so it can adhere to these constraints. | In use-cases where the proxy and the real instance are not instances of the same class, the proxy is considered to be aware of laziness, so it can adhere to these constraints. | ||
+ | |||
+ | The externally visible type of a lazy proxy is the type of the proxy object, even if the real object is of a parent type. This includes the get_class() function, the ::class constant, the instanceof operator and type checking in parameter, return and property types. | ||
===== Future scope ===== | ===== Future scope ===== | ||
Line 785: | Line 787: | ||
==== Lazy cloning ==== | ==== Lazy cloning ==== | ||
- | The RFC proposes that the < | + | The RFC proposes that the < |
- | Although it may be possible to implement lazy cloning while preserving < | + | Although it may be possible to implement lazy cloning while preserving < |
However, it may be possible to make cloning lazy in the future by introducing a new flag (e.g. < | However, it may be possible to make cloning lazy in the future by introducing a new flag (e.g. < | ||
Line 803: | Line 805: | ||
* Add lazy-objects as described to the engine: yes/no (2/3 required to pass) | * Add lazy-objects as described to the engine: yes/no (2/3 required to pass) | ||
- | ===== Patches and Tests ===== | + | Voting started on 2024-07-26 and will end on 2024-08-11 00:00 GMT. |
+ | |||
+ | <doodle title="Add lazy-objects as described to the engine" | ||
+ | * Yes | ||
+ | * No | ||
+ | </ | ||
+ | |||
+ | ===== Implementation | ||
- | https:// | + | https:// |
rfc/lazy-objects.1721832610.txt.gz · Last modified: 2024/07/24 14:50 by lbarnaud