Mathieu Rochette wrote on 16/11/2015 10:00:
Would it be allowed to assign non immutable types to properties of an
immutable class ?
I think this is the trickiest part of trying to enforce immutability:
nesting. Consider the following:
// Basic properties
$my_immutable_object->foo = 42;
$my_immutable_object->foo++;
// Nested object - implicitly immutable? required to be explicitly
immutable?
$my_immutable_object->bar->something = 42;
$my_immutable_object->bar->setSomething(42);
// Array access - no idea how this should work
$my_immutable_object->quux[0] = 42;
$my_immutable_object->quux[] = 'Hello';
$my_immutable_object->quux['World'][0]['X'] = 'A';
The other problem is that to be useful, certain functions usually need
to be able to mutate the state of objects which are officially
immutable. For instance, implementations of PSR-7 need a set of copy
constructors for the withX methods. You could do this using the
suggested rule that immutability applies only to non-null properties,
and manually populate every property of an empty instance, but it's much
more efficient to "clone $this" and then change the one property that
needs to be different.
For this particular example, you could write quite a nice implementation
by "freezing" the instance once it's initialised:
// example plucked from
https://github.com/guzzle/psr7/blob/master/src/Request.php#L101
public function withMethod($method)
{
// The method starts by making a mutable clone of the immutable
$this
$new = clone $this;
$new->method = strtoupper($method);
# SUGGESTED ADDITION: new keyword to set an object to be immutable
freeze $new;
// After this point, nothing should be able to mutate the new
object, only clone it
return $new;
}
The freeze operation could perhaps be recursive, or perhaps it could
work like "clone", with an "__freeze" method responsible for freezing
nested objects as necessary. The ability to freeze an array would also
be useful in that case...
I realise this is a lot more complex than the original suggestion, but I
think something of this level of detail is needed to make it useful.
Regards,
--
Rowan Collins
[IMSoP]
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php