On 30 May 2025, at 21:29, Rowan Tommins [IMSoP] <imsop....@rwec.co.uk> wrote: > > On 30 May 2025 19:21:08 BST, Alwin Garside <al...@garsi.de> wrote: >> In the example above, I image calling or extending the `Foo::bar()` method >> from somewhere outside the `Acme` namespace would trigger an E_USER_WARNING >> or E_USER_NOTICE. The warning/notice could then be suppressed when >> explicitly overriding an `#[\Internal]` method with `#[\Override]`. > > > I don't see any reason for the message to be any quieter or easier to > override than calling a private method.
If there were a dedicated `internal` modifier keyword, sure. However if one simply wants to advertise clearly to other developers that they should expect the code to break anytime using an attribute, I feel a compile-time critical error is a bit too strict. > > Indeed, one use of an internal/module-private feature would be when the > author wants to split up a class that has a large number of private methods: > the new classes need to be able to talk to each other, so the existing > "private" keyword is no longer appropriate, but the intended surface to users > of the library has not changed. The user is making exactly the same decision > by ignoring the "internal" flag as they are if they use reflection or > code-rewriting to ignore/remove the "private" flag. I understand your point, but playing devil's advocate for a minute here: I'd argue that if a class reaches the point where it has too many private methods, something has clearly gone wrong in the architecture or abstraction of that class. It probably means part of the functionality needs to be hoisted out to a separate class with its own self-contained, stable interface. One could also argue that if the author really wishes to break private methods up across multiple classes, they could also use reflection (or preferably: a method call wrapped in a closure bound to the target class) to access their own private methods. My experience with module-level visibility out in the wild (mostly in Java), has mostly been libraries where the authors apparently couldn't be bothered to dedicate to a stable interface for more specific implementations of certain template-pattern adapters and the like – the Android source code is full of this. [rant] I specifically remember dealing with a DB adapter interface and accompanying abstract class, along with implementations for several DBMSs. There was an implementation for the specific DBMS I wanted to use, however, per the interface, it was completely tied into a separate pagination construction which led to a leaky abstraction, and was badly optimized for my use case. I just needed to override one or two methods to make it work for me, but the platform visibility on those methods meant I had to copy-paste both the abstract class and the adapter class to fix the functionality, giving me more code to maintain in the process. I think this is a good example where package/module-level visibility makes developers complacent, and not care about offering a library that is easy to extend or encapsulate. [/rant] Alwin