Replies: 2 comments
-
I agree, that's goofy and should probably be changed.
Considering your reasoning, I would rather have the interpreter throw an error if super() is never called in an overridden virtual function. That would make it impossible to forget the otherwise invisible 'default' of calling/not calling virtual functions, making the best user experience in my opinion. |
Beta Was this translation helpful? Give feedback.
-
hmm that doesn't make all that much sense to me. if we acknowledge that in the special case of virtual functions, it doesn't make sense for super() to never be called, then why not have it happen implicitly like we are used to from Godot 3? there is no point in requiring users to write it out unless they need the super() call to happen at a specific point between some logic of the "overwriting" function. |
Beta Was this translation helpful? Give feedback.
-
Imho this should be a proposal rather than a discussion as it proposes a concrete solution / implementation, but I'll post here nonetheless as it may be controversial.
When I say "implicit", I am referring to the virtual functions being called automatically by the engine.
In Godot 3.x, the virtual functions -
_ready()
,_process()
, etc. - were called implicitly including in the scenario where they were also declared by an inheriting class.I think the implicit call made sense as things like setup and process logic of a node should not rely on the logic of an inheriting node class by default. Now, it feels like an inconsistency to me that virtual functions sometimes are and sometimes aren't called implicitly. For new users, too, I think it's easiest & most intuitive to learn about them as "functions the engine takes care of calling for you".
As it is now in Godot 4, I feel like it is much more of a source of potential bugs than it was in 3. We have to litter our code with
super()
calls that need to be maintained. When adding a virtual function declaration in a superclass, we have to think of checking all inheriting classes to see if they have a virtual function that needs asuper()
call added. Yesterday I spent many hours looking for a bug of which the cause turned out to be an earlyreturn
in_process
that skipped asuper()
call. It was an exhausting experience. :)Furthermore, currently
@onready
is considered a declaration of_ready()
and thus prevents the implicit calls of inherited_ready()
functions, so people have to write rather silly code:Generally the required
super()
just seems like a lot of unnecessary boilerplate as in the vast majority of cases the exact point at which the superclass function is called isn't relevant (or a default point would do just fine). Of course as a reminder, I am exclusively referring to the virtual i.e. engine called functions here, which generally belong to nodes.The only scenario where always requiring
super()
makes sense is when an user would sometimes need the virtual function in the superclass to never be called at all, but when that's the case, then I reckon it's an issue of code architecture and the user should rearrange their class inheritance and/or logic instead.While how Godot 3 did things worked just fine for me, I understand that the new approach of explicitly calling
super()
gives more control over exactly at which point in the logic the superclass function is invoked.So why not have the best of both worlds: Still call inherited virtual functions implicitly like usual, but when the user puts an explicit
super()
in the corresponding function of the inheriting class, then the implicit call is skipped.Implementation example: When a _process function concludes or returns, then the engine should do a check if super() has already been called, and when it hasn't, it should be called by the engine. This would result in the behavior we know from Godot 3 with the added functionality of being able to specify a "custom call location" via super(). For _ready and _init, the behavior would slightly differ from Godot 3 as unlike with _process, Godot 3 calls the superclass first for these functions. However, this doesn't really matter since in the scenario where the user needs that behavior, they can put the explicit
super()
now.This existing proposal addresses the same issue, however I'd like to open a new one as I frankly don't see the need for the additional annotation it proposes.
I have read through this discussion of the past where people seem to be overwhelmingly in favor of not calling superclass virtual functions automatically, though I still wanted to start a new discussion as
Beta Was this translation helpful? Give feedback.
All reactions