Hi Nikita,

On Mon, 11 Mar 2019 at 11:27, Nikita Popov <nikita....@gmail.com> wrote:

> The solution I would prefer is the ability to declare that within a
> project, all interactions with objects (whether they are my own or come
> from 3rd parties) should disallow the creation of dynamic properties. This
> differs from your proposal in two important points:
>  1. You cannot create dynamic properties on objects even if they come from
> 3rd-party code you do not control.
>  2. 3rd-party code may interact with your objects (and it's own) however
> it likes. It is not affected by the disabling of dynamic properties in your
> project code.
>


That's an interesting approach. I think it's conceptually a lot more
complicated (and probably more complicated to implement, too) - the same
object would behave in different ways in different contexts. There are also
edge cases to define which the current proposal doesn't need to worry
about, like stdClass, and objects which were created in one scope and
manipulated in another:

declare(strict_properties=0) {
    class Foo {}
    $foo = new Foo;
    $foo->bar = 42;
}
declare(strict_properties=1) {
    echo $foo; # Is $bar now 'defined', or do we only count the properties
in the original class definition?
}

More importantly, you would have to check that third-party code was
declaring the properties you needed before enabling it. For instance, a
library might document that you should set `$handler->debug = true`, read
that property internally, but never declare it; you'd then have to patch
the library before you could run in strict_properties mode.

It feels like at that point, we might as well just deprecate dynamic
properties altogether - which I'm beginning to think is the best approach.

To put it explicitly, what are the use cases where you'd turn such a flag
off?




> 1. The BC break section is not terribly clear due to the use of
> "semi-reserved". I initially assumed that this was a contextual keyword
> (i.e. only has special meaning immediately before "class") but apparently
> this is a normal reserved keyword in the implementation (i.e. no classes,
> functions, namespaces etc named "locked").
>


Oops, I'll hold my hands up to not actually testing that. I think I took
that wording from a comment in the parser, but probably didn't read it
properly.



2. It is possible to break a reference by reassigning it to another
> reference, like so:
>
>     $null = null;
>     $this->prop =& $null;
>     unset($null);
>
> This is not quite as good as unsetting because it leaves behind an rc=1
> reference, but that would be the way to remove a reference without unset().
>


Huh, cunning. :)

Regards,
-- 
Rowan Collins
[IMSoP]

Reply via email to