Re: [RFC] Data Classes
| From: | Rowan Tommins [IMSoP] | Date: | Sat, 23 Nov 2024 17:34:11 +0000 |
| Subject: | Re: [RFC] Data Classes | ||
| References: | 1 2 3 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-126036@lists.php.net to get a copy of this message | ||
On 23/11/2024 16:05, Rob Landers wrote:
Looking closer, there's a hint at what you expect to happen in your Rectangle example: $bigRectangle = $rectangle->resize(10, 20); assert($bigRectangle !== $rectangle); // true It seems that modifications to $this aren't visible outside the method, creating a purely local clone, which would be discarded if it wasn't returned (or saved somewhere). I can see the logic, but the result is a bit unintuitive: data class Example { public function __construct(public int $x) {} public function inc(): void {Your RFC doesn't discuss this - the changeName example shows behaviour *inside* the method, but not behaviour when *calling* itAn interesting observation, can you explain more as to what you mean?
$this->x++;} } $foo = new Example(0); $foo->x++; $foo->inc(); echo $foo->x; // 1, not 2 I think it would be clearer to prevent direct modification of $this: data class Example { public function __construct(public int $x) {} public function inc(): void {
$this->x++; // ERROR: Can not mutate $this in data class} public function withInc(): static {
$new = $this; // explicitly make a local copy of $this $new->x++; // copy-on-write separates $new from $this return $new;} } That would still be compatible with Ilija's suggestion, which was to add special "mutating methods": data class Example {
public function __construct(public int $x) {}
public mutating function inc(): void {
$this->x++;
}
}
$foo = new Example(0);
$foo->x++;
$foo->inc!(); // copy-on-write triggered *before* the method is called
echo $foo->x; // 2
--
Rowan Tommins
[IMSoP]