> It can be perfectly ok to allow the lib to be extended and the constructor > extended/replaced with a compatible one.
Well sure, it's great to override constructors completely. If the lib authors didn't want you to do that, they should've made it final (which is what I said they should do now). You have every reason to expect this will work and keep working. Without call super. But "extending" a constructor in some made-up way where you override and just *guess* you need to call super if one exists -- after your additional code? before? why one over the other? -- without any formal documentation at all about the consequences? I think that's a stink bomb and I'm sticking with that view. It's like you're treating the superctor as simultaneously opaque and knowable. Say it happens to work at first b/c you don't touch any resources that the superctor needs, or you assign them and the superctor runs afterward and resets them to a workable state (unbeknownst to you). For the sake of argument, let's call this compatibility instead of luck. And how do you keep it compatible? You don't. They could change the superctor signature (oops! you're out of luck because you don't pass them what they need). Internally, they could change what resources superctor expects you to leave alone, what it doesn't, and in what order. It's simple to break this kind of thing, where a third-party doesn't want you to do something but they forgot to stop you. > Either the lib author needs to add an empty constructor into every class > just to make sure that it will be there to provide a painless upgrade when > the need arises for a constructor There's no guarantee at all that it will be painless, because the signatures could mismatch, not to mention every single other dependency being subject to your guesswork. If the authors change their approach, it should be to the Template Method/subinit pattern, not making an "official" Call Super reqt that'll still be doomed to failure. > otherwise the lib consumer has to write boilerplate to make sure > that the parent constructor will be only called whet ot is there. Which is still just a guess, and basically doomed. Why would you think you can run an opaque parent:__construct() at any time? I would never just trust that. And I'm hardly risk-averse. :) Look, my gripe isn't with silencing/catching the call to unknown methods in lieu of method_exists(). If that gets easier to do in the language, fine. But I think this use case stinks as a justification. Still, I'll lay off after this e-mail because I will have said my piece. :P > Your example also shows an overengineered solution for a simple problem. But it's 4 lines long! The rest is comments and examples of usage. And it's a _real_ solution to the problem, so it could only be overengineered vs. something else that is functionally equivalent. The Template Method pattern ensures that the child classes do not need to "remember" to invoke a particular method within their initializer. Simply by having an init() method in your derived class, you ensure that upper-level dependencies will be taken care of, and you don't have to have an init() method at all if you don't want to, or you can have an empty one with no side effects. The initialization hierarchy is baked into the object model at the outermost possible layer (since you can't go one more level out into language constructs). This doesn't mean you don't need documentation of what you should/shouldn't do when you init, but it is way closer to being manageable over time. The Call Super pattern requires that the user remember to call within their ctor code, and even worse, the situation under discussion is truly the worst possible argument for the pattern, since _you don't even have any word from the library author_ that call super is recommended or required... so not only can you not enforce the contract, you're making up the notion of the contract off the top of your head. Cheers regardless -- -- S. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php