Hey Pedro,

On Fri, May 22, 2020 at 5:43 PM Pedro Magalhães <m...@pmmaga.net> wrote:

> Hi internals,
>
> I want to put up for discussion an RFC (
> https://wiki.php.net/rfc/inheritance_private_methods) that proposes to
> remove some inappropriate signature checks that are still done on private
> methods. Namely, those checks are:
>
> - When a method has the same name as a parent's final private method
> - When a method has the same name as a parent's static private method and
> the child's method is non-static, or vice-versa
> - When a method has the same name as a parent's concrete private method and
> the child's method is abstract
>
> I have 2 open issues on the RFC that I would like to hear some opinions on.
> - Whether or not to issue a compiler warning whenever "final private
> function" is used, to alert the user that it will not achieve what that
> construct is currently used for. The disadvantage of introducing it is the
> BC break.
> - Whether or not to make an exception to this rule for magic methods. Given
> that this is widely to restrict object instantiation and cloning, it could
> make sense to still allow the use on those cases. However, I think that the
> similar effect that can be achieved with "final protected function" would
> cover most of the cases. And if we open up that exception for magic
> methods, for the sake of clarity maybe we should just keep the "final
> private" behavior on all methods and just change the static and the
> abstract behaviors. Some discussion on this subject can be found on the PR
> (
> https://github.com/php/php-src/pull/5401) for this RFC.
>

Overall, this RFC breaks some design capabilities that are within the
language, specifically around `__`-prefixed methods in the language.

For instance, I design (on purpose) sealed types as following:

```php
abstract class Email
{
    final private function __construct() {}
    public static function business(): Business {
        return new Business();
    }
    public static function personal(): Personal {
        return new Personal();
    }
}

final class Business extends Email {}
final class Personal extends Email {}
```

The above approach guarantees that no further subtypes exist for `Email`,
other than `Business` or `Personal`, effectively forming a safe union type,
which can only be broken by reflection.

In addition to that, I often prevent serialization of types that are not
intended to be serialized (when not final):

```php
abstract class InMemorySecret
{
    final private function __sleep() {}
}
```

Effectively, the `final` modifier applies to `private` symbols too, and
prevents child classes from deviating from imposed design constraints.

It is **intentional** for `private` symbol overrides to not compile in
these cases.

Both of the above examples only apply to special/magic methods: I can see
and understand that for custom methods this RFC may be valid, and adding a
further refinement to lift the restriction only on custom methods is a good
idea.

Marco Pivetta

http://twitter.com/Ocramius

http://ocramius.github.com/

Reply via email to