Re: Consensus gathering: allowing unsetting of backed property hooks
On Wed, Feb 26, 2025, at 09:17, Rowan Tommins [IMSoP] wrote:
>
>
> On 25 February 2025 23:31:25 GMT, [email protected] wrote:
> >On 2/25/25 4:51 PM, Rowan Tommins [IMSoP] wrote:
> >> I actually started writing an RFC to rationalise some of this behaviour
> >
> >I'm glad I'm not the only one who considers this an issue worth pursuing!
>
> Sorry, I wasn't clear: I was looking at the existing typed vs untyped, unrefined vs
> uninitialised mess, before property hooks even existed.
>
>
> >
> >> Here are some of the things that might happen as a result of unset($foo->bar):
> >
> >I don't disagree that there's a lot of weirdness. But for better or worse
> >that's where PHP is now - it's a fundamentally weird language. I think it's better to
> >be consistently weird than to be inconsistently weird.
>
> My point is that it's *already* inconsistently weird.
>
>
> > It would be inconsistent to allow unsetting some types of properties but not others, and
> > which ones can and can't be unset are indistinguishable to a 3rd-party consumer.
>
> unset() can already have a bunch of different effects depending on the implementation of the
> class. As well as __unset being able to do *absolutely anything*, I missed from my list
> "readonly" properties, which reasonably enough *always throw an error for unset*, just
> like hooked properties.
>
>
> >I can't comment from an implementation perspective, but as a user of PHP I would
> >expect unsetting a backed property to return the property the "uninitialized" state, and
> >subsequent access would proceed as if it were the first access of the uninitialized property.
>
> An untyped property is currently never in the "uninitialised" state, only a different
> "undefined" state. Presumably this inconsistency would need to be preserved (for
> consistency)
>
>
> >Unsetting a virtual property could simply do nothing, but not result in a fatal error. I
> >don't think a warning is even necessary because no action is taken.
>
> I don't see how that would be useful. The user presumably expected it to do *something*,
> so informing them that it didn't seems preferable to silently ignoring their request. It would
> also be inconsistent: a virtual property with no "set" hook throws an error when you try
> to set it, it doesn't silently discard the value.
>
>
>
> > I certainly don't want to be required to define an unset hook for every single backed
> > property; rather unset()
should have a default behavior.
>
> I think you're focusing too closely on one use case, rather than all the ways people will
> want to use hooked properties. Imagine you have two properties which you want to keep in sync:
> setting either of them recalculates the other, using set hooks.
>
> * It would be really surprising to the class author if a user of the class could "reach
> in" and invalidate the state by calling unset() on one of the properties.
> * It would be really surprising to the user if doing so worked on one of the properties, but
> silently did nothing on the other because it was implemented as virtual.
> * It might be appropriate for the class author to add "unset" hooks to both
> properties, and for the user to see that unsetting one unset the other, just as setting one sets the
> other.
>
> That's just one scenario, I'm sure there are others where you could picture different
> expectations, particularly accounting for some of the other behaviour of unset(). That's what I
> mean by it being hard to specify the behaviour; nothing to do with the implementation.
>
> Regards,
> Rowan Tommins
> [IMSoP]
I do think it makes sense to have an unset hook though, so long as it is thought out well. For
example, would the unset hook be called automatically during garbage collection? Is it only called
via unset() or are there other cases where it could be called too?
Regardless of how wise it is to unset from outside a class, doing the suggested workaround from
inside the class seems a bit odd as well.
— Rob
Thread (8 messages)