rfc:object-initializer
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
rfc:object-initializer [2019/09/13 08:32] – changed above into following in front of some examples brzuchal | rfc:object-initializer [2019/10/24 07:36] (current) – closing vote, moving to declined brzuchal | ||
---|---|---|---|
Line 2: | Line 2: | ||
* Version: 1.0 | * Version: 1.0 | ||
* Date: 2019-09-03 | * Date: 2019-09-03 | ||
- | * Author: Michał Brzuchalski <michal.brzuchalski@gmail.com> | + | * Author: Michał Brzuchalski <brzuchal@php.net> |
- | * Status: | + | * Status: |
* First Published at: http:// | * First Published at: http:// | ||
- | |||
- | |||
===== Introduction ===== | ===== Introduction ===== | ||
Line 15: | Line 13: | ||
- Pass created a fully initialized object. | - Pass created a fully initialized object. | ||
- | That's where object initializer optimization can benefit with single expression statement and it can be used to initialize any kind of object // | + | In current PHP implementation with Typed Properties, it is possible to instantiate class which doesn' |
+ | properties in an uninitialized state. | ||
+ | |||
+ | That's where object initializer optimization can benefit with single expression statement and it can be used to initialize any kind of object // | ||
+ | required properties are properly initialized, | ||
+ | |||
+ | The initializer block can use any properties and variables available in the containing scope, but one has to be wary of the fact that initializers are run after constructors. | ||
===== Proposal ===== | ===== Proposal ===== | ||
Object initializers allow assigning values to any accessible properties of an object at creation time without having to invoke a constructor followed by lines of assignment statements. The object initializer syntax enables to specify arguments for a constructor or omit the arguments (and parentheses syntax). | Object initializers allow assigning values to any accessible properties of an object at creation time without having to invoke a constructor followed by lines of assignment statements. The object initializer syntax enables to specify arguments for a constructor or omit the arguments (and parentheses syntax). | ||
- | |||
- | The following example shows how to use an object initializer with a // | ||
<code php> | <code php> | ||
Line 36: | Line 38: | ||
} | } | ||
} | } | ||
- | |||
- | $customer = new Customer { | ||
- | id = 123, | ||
- | name = "John Doe", | ||
- | }; | ||
class Car | class Car | ||
Line 47: | Line 44: | ||
public string $vin; | public string $vin; | ||
} | } | ||
+ | </ | ||
+ | |||
+ | The following example shows how to use an object initializer with a '' | ||
+ | |||
+ | <code php> | ||
+ | <?php | ||
+ | |||
+ | $customer = new Customer { | ||
+ | id = 123, | ||
+ | name = "John Doe", | ||
+ | }; | ||
$car = new Car { | $car = new Car { | ||
Line 54: | Line 62: | ||
</ | </ | ||
- | The object initializers syntax allows to create an instance, and after that, it assigns the newly created | + | > **Note!** If in current scope there are constants with exactly the same name as property names used in the above example, they do not impact |
- | The following example is an equivalent to the previous one. | + | The following example is equivalent to the previous one. |
<code php> | <code php> | ||
Line 72: | Line 80: | ||
The main difference is that object initializers allow creating a new object, with its assigned properties in a single expression. For eg. factory methods where normally a significant amount of argument has default values or simple Data Transfer Objects could benefit. | The main difference is that object initializers allow creating a new object, with its assigned properties in a single expression. For eg. factory methods where normally a significant amount of argument has default values or simple Data Transfer Objects could benefit. | ||
- | > Note! Currently, language allows instantiating object and initializing only a subset of typed non-nullable properties without a default value. These rules apply to object initializer the same way, meaning the creation of properly initialized object state is in authors responsibility, | + | > **Note!** Currently, language allows instantiating object and initializing only a subset of typed non-nullable properties without a default value. These rules apply to object initializer the same way, meaning the creation of properly initialized object state is in authors responsibility, |
- | ==== Constructors | + | ==== Restrictions |
+ | Using Object Initializer enforce that if a class is instantiated with the Object Initializer, | ||
+ | This helps to avoid bugs where a property is added to the class but forgot to be assigned it a value in all cases where the class is instantiated and initialized. | ||
- | Due to the fact that initializer block purpose is a simplification of instantiating and initializing object properties, constructors are called before initialization takes apart. Constructors allow initializing default values // | + | The object initializers syntax allows to create an instance, and after that, it assigns the newly created object, with its assigned properties, to the variable in the assignment. |
+ | |||
+ | <code php> | ||
+ | <?php | ||
+ | |||
+ | $customer = new Customer { | ||
+ | name = "John Doe", | ||
+ | }; // throws RuntimeException: | ||
+ | |||
+ | $car = new Car { | ||
+ | yearOfProduction = 2019, | ||
+ | }; // throws RuntimeException: | ||
+ | </ | ||
+ | |||
+ | |||
+ | ==== Constructors ==== | ||
+ | Due to the fact that initializer block purpose is a simplification of instantiating and initializing object properties, constructors are called before initialization takes apart. Constructors allow initializing default values // | ||
Due to the fact that objects in PHP simply have constructor directly declared in class definition or indirectly through the defaulting constructor, | Due to the fact that objects in PHP simply have constructor directly declared in class definition or indirectly through the defaulting constructor, | ||
- | > Note! Object instantiation allows only constructors without required arguments to be used. Any class which requires passing arguments to constructor cannot be used in combination with object initializer. | + | > **Note!** Object instantiation allows only constructors without required arguments to be used. Any class which requires passing arguments to constructor cannot be used in combination with object initializer. |
Line 106: | Line 132: | ||
- | > Note! Classes without constructor desired to mimick " | + | > **Note!** Classes without constructor desired to mimick " |
- | > Note! If a class needs validation upon to validate its invariants a proper validation logic needs to be called after initialization. To combine it with object initializer and keep the validation process encapsulated, | + | > **Note!** If a class needs validation upon to validate its invariants a proper validation logic needs to be called after initialization. To combine it with object initializer and keep the validation process encapsulated, |
==== Lexical scope ==== | ==== Lexical scope ==== | ||
Line 208: | Line 234: | ||
}; | }; | ||
</ | </ | ||
- | |||
- | |||
===== Backward Incompatible Changes ===== | ===== Backward Incompatible Changes ===== | ||
- | This proposal changes the meaning of above example which uses curly brace to fetch array offset //(which is already deprecated since PHP 7.4)// which is very rare usage. | + | This proposal changes the meaning of the above example which uses a curly brace to fetch array offset //(which is already deprecated since PHP 7.4)// which is very rare usage. |
<code php> | <code php> | ||
Line 222: | Line 246: | ||
$var = 123 | $var = 123 | ||
}; | }; | ||
+ | </ | ||
+ | |||
+ | ===== Reflection ===== | ||
+ | Both '' | ||
+ | |||
+ | <code php> | ||
+ | <?php | ||
+ | |||
+ | $reflectionClass = new ReflectionClass(Customer:: | ||
+ | $customer = $reflectionClass-> | ||
+ | // equivalent to | ||
+ | $customer = new Customer {name = ' | ||
</ | </ | ||
Line 269: | Line 305: | ||
As this is a language change, a 2/3 majority is required. | As this is a language change, a 2/3 majority is required. | ||
- | The vote is a straight Yes/No vote for accepting the RFC and merging the patch. | + | The vote is a straight Yes/No vote for accepting the RFC. |
+ | |||
+ | <doodle title=" | ||
+ | * Yes | ||
+ | * No | ||
+ | </ | ||
+ | . | ||
+ | <doodle title=" | ||
+ | * = | ||
+ | * => | ||
+ | </ | ||
===== Patches and Tests ===== | ===== Patches and Tests ===== |
rfc/object-initializer.1568363554.txt.gz · Last modified: 2019/09/13 08:32 by brzuchal