rfc:property_accessors

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
rfc:property_accessors [2021/05/04 09:25]
nikic
rfc:property_accessors [2022/04/28 09:30] (current)
ilutov Fix typos
Line 363: Line 363:
 </PHP> </PHP>
  
-Specifying the same accessor multiple types is also illegal.+Specifying the same accessor multiple times is also illegal.
  
 === By-reference getter === === By-reference getter ===
Line 387: Line 387:
 </PHP> </PHP>
  
-These indirect modification perform a call to the getter, followed by a call to the setter.+These indirect modifications perform a call to the getter, followed by a call to the setter.
  
 However, indirect array modification, as well as acquiring a reference are only supported by by-reference getters. In this case, the setter will not be invoked: However, indirect array modification, as well as acquiring a reference are only supported by by-reference getters. In this case, the setter will not be invoked:
Line 420: Line 420:
  
 While nominally well-defined, such an accessor would not have particularly useful semantics: It would be possible to change the property value arbitrarily, but only by writing ''$ref =& $test->prop; $ref = $value'' rather than ''$test->prop = $value''. While nominally well-defined, such an accessor would not have particularly useful semantics: It would be possible to change the property value arbitrarily, but only by writing ''$ref =& $test->prop; $ref = $value'' rather than ''$test->prop = $value''.
 +
 +TODO: An open problem is how implicit by-value ''get'' interacts with by-reference foreach. Currently, it's still possible to acquire a reference using this pathway:
 +
 +<PHP>
 +class Test {
 +    public $prop = null { get; private set; }
 +}
 +
 +$test = new Test;
 +foreach ($test as &$prop) {
 +    $prop = 1;
 +}
 +</PHP>
 +
 +This needs to be prevented in some way. This could either error, or it could silently return a value for properties for which no reference can be acquired. Otherwise it would no longer be possible to iterate arbitrary objects by-reference.
  
 === Isset and unset === === Isset and unset ===
Line 499: Line 514:
 === Interaction with by-reference getter === === Interaction with by-reference getter ===
  
-It is worth pointing out that the combination of ''&get'' with ''private set'' leaves a loophole that allows you do bypass the private setter and perform arbitrary modifications:+It is worth pointing out that the combination of ''&get'' with ''private set'' leaves a loophole that allows you to bypass the private setter and perform arbitrary modifications:
  
 <PHP> <PHP>
Line 524: Line 539:
 class A { class A {
     public $prop {     public $prop {
-        get { echo __METHOD, "\n";+        get { echo __METHOD__, "\n";
-        set { echo __METHOD, "\n"; }+        set { echo __METHOD__, "\n"; }
     }     }
 } }
 class B extends A { class B extends A {
     public $prop {     public $prop {
-        set { echo __METHOD, "\n"; }+        set { echo __METHOD__, "\n"; }
     }     }
 } }
Line 550: Line 565:
     public int|string $covariant { get; }     public int|string $covariant { get; }
     // This property is useless, but will serve for the sake of illustration.     // This property is useless, but will serve for the sake of illustration.
-    public int|string $contravariant { set {} }+    public int|string $contravariant { set { /* ... */ } }
 } }
  
Line 905: Line 920:
 class Test { class Test {
     // Illegal: Implicit get, explicit set.     // Illegal: Implicit get, explicit set.
-    public string $prop { get; set {} }+    public string $prop { 
 +        get; 
 +        set { /* ... */ } 
 +    }
     // Illegal: Implicit set, explicit get.     // Illegal: Implicit set, explicit get.
-    public string $prop { get {} set; }+    public string $prop { 
 +        get { /* ... */ } 
 +        set; 
 +    }
 } }
 </PHP> </PHP>
Line 930: Line 951:
     // Illegal: Default value on property with explicit accessors.     // Illegal: Default value on property with explicit accessors.
     public $prop = "" {     public $prop = "" {
-        get {}+        get { /* ... */ }
     }     }
 } }
Line 963: Line 984:
 This limitation exists to prevent embedding of very large property declarations in the constructor signature. This limitation exists to prevent embedding of very large property declarations in the constructor signature.
  
-=== var_dump, get_object_vars() etc ===+=== var_dump(), array cast, foreach etc ===
  
-''var_dump()'', and other functions or language features inspecting object properties will only return properties that have a backing property, i.e. those using implicit accessors. Explicit accessor properties are omitted, and accessors will never be evaluated as part of a ''var_dump()'', ''(array)'' casts, or similar.+''var_dump()'', ''(array)'' casts, foreach and other functions/features inspecting object properties will only return properties that have a backing property, i.e. those using implicit accessors. Explicit accessor properties are omitted, and accessors will never be evaluated as part of a ''var_dump()'', ''(array)'' cast, foreach, or similar.
  
 <PHP> <PHP>
Line 979: Line 1000:
 //   int(42) //   int(42)
 // } // }
 +
 +var_dump((array) $test);
 +// array(1) {
 +//   ["prop1"]=>
 +//   int(42)
 +// }
 +
 +foreach ($test as $name => $value) {
 +    echo "$name: $value\n";
 +}
 +// prop1: 42
 </PHP> </PHP>
  
rfc/property_accessors.1620120321.txt.gz · Last modified: 2021/05/04 09:25 by nikic