-
-
Notifications
You must be signed in to change notification settings - Fork 21.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Static method override fails when call site is base script #72973
Comments
I'd say that's definitely a bug, for instance/non-static methods it'd call the overridden method just fine. Also if calling static method on an instance (which seems to be allowed) it does call the proper overridden static method. In the MRP: print(v)
print(Derived.get_script_name_static())
print(v)
print(Derived.new().get_script_name_static())
print(v) Output:
|
This is still present in 4.0.3 |
I'm not sure if this can be called a 100% bug. The expected behavior is not documented anywhere. For example, PHP has Late Static Bindings, you can explicitly specify with the See also:
Example<?php
class A {
static function overriden(): string {
return "A::overriden";
}
static function not_overriden(): string {
return "A::not_overriden";
}
static function test_overriden(): void {
echo "A::test_overriden\n";
echo "=================\n";
echo "overriden (self): " . self::overriden() . "\n";
echo "overriden (static): " . static::overriden() . "\n";
echo "not_overriden (self): " . self::not_overriden() . "\n";
echo "not_overriden (static): " . static::not_overriden() . "\n";
echo "\n";
}
static function test_not_overriden(): void {
echo "A::test_not_overriden\n";
echo "=====================\n";
echo "overriden (self): " . self::overriden() . "\n";
echo "overriden (static): " . static::overriden() . "\n";
echo "not_overriden (self): " . self::not_overriden() . "\n";
echo "not_overriden (static): " . static::not_overriden() . "\n";
echo "\n";
}
}
class B extends A {
static function overriden(): string {
return "B::overriden";
}
static function test_overriden(): void {
echo "B::test_overriden\n";
echo "=================\n";
echo "overriden (self): " . self::overriden() . "\n";
echo "overriden (static): " . static::overriden() . "\n";
echo "not_overriden (self): " . self::not_overriden() . "\n";
echo "not_overriden (static): " . static::not_overriden() . "\n";
echo "\n";
}
}
A::test_overriden();
A::test_not_overriden();
B::test_overriden();
B::test_not_overriden();
|
Godot version
4.0.rc1
System information
windows 10
Issue description
When overriding a static method, it is possible to call the override "from outside", when the call site is using a reference to the derived script, and it is also possible to invoke the base implementation from within the overridden implementation using "super()". BUT, if a given method is not overridden and it's implementation calls another method which has an override in the derived script, then the overridden implementation does not get called at all, only the base implementation.
I think that, If static method override is desired in gdscript, then the static method call should be bound to the script reference lastly used to invoke the method, that is, the derived scripts which may override static methods, and this binding should propagate to other static calls within the method implementation unless a new script reference is used.
If this is not a bug, but an unwanted behavior, then we should warn the user that overriding static methods between scripts is not supported. But if this is indeed a bug, then it could be interesting consider doing something like in php: in php, when using the 'static' keyword inside a method, it refers always to the most derived script used to initiate the call stack, whereas the 'self' keyword refers always to the current script where the keyword was written. If similar keywords existed in gdscript, we could use
static.myStaticMethod()
to ensure themyStaticMethod()
call is bound to the most derived script, whereasself.myStaticMethod()
(obviously the keyword should be other since self is already used) would be bound always to the script where the keyword is written. Or maybe we could make get_script() work somehow in static contexts and always return the most derived script used in the call stack, so that we can useget_script().myStaticMethod()
to ensure the overriden method is called andMyScriptName.myStaticMethod()
to ensure the base implementation is calledSteps to reproduce
Create a Base class. Then create a Derived class which extends from base. In the Base class implement two methods, A and B, A will call B. In the Derived class, override method B but not A. Then, from a third script, call Derived.a() and notice how Derived.b() is never called
Minimal reproduction project
StaticMethodOverrideFailsPropagatingBoundScript.zip
The text was updated successfully, but these errors were encountered: