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/