Godot version:
v3.0.2.stable.official
Issue description:
I cannot find any way to instantiate a class from one of it's own methods. For example:
class Example:
var _data = []
func _init():
#just want to show that the constructor takes no arguments
func duplicate():
var copy = new()
copy._data = _data.duplicate()
return copy
This will produce the error message "nonexistent function 'new' in base Reference ()"
If I replace var copy = new() with var copy = Example.new() I get an error message about "Example" not being defined.
If I eschew the inner class and copy it's body into a new script "Example.gd", it still does not work.
If there is a way to do it, I would really appreciate someone pointing it out. There is no documentation on this.
Someone might point out that I can work around this by creating new instances of Example in another class. This is not an acceptable solution however.
Objects are meant to encapsulate their data. Therefore in the example above, only the Example class should know how to produce a copy of itself and what level of depth is appropriate when making the copy. Having to leak the implementation details of how Example represents its inner data to another class just to create a copy breaks this encapsulation.
A GDScript class can self-instantiate with get_script().new().
See also #944.
@KellyThomas does this work for scripts that extend Reference?
I tried it and get_script() was returning null. I suspect it only works for Nodes.
I tried it and get_script() was returning null. I suspect it only works for Nodes.
There's no reason it should work only for nodes.
In any case, my PR for static typing (#19264) should solve this issue, even if you don't use typing.
@KellyThomas @vnen Sorry, I was mistaken. I'm not sure why I remember it returning null last night, but I just tried it again and get_script().new() works. Thank you for the solution.
I was looking at some old code by someone else.
They were doing something like:
static func create(some, options):
var instance = new()
instance.init_stuff(some, options)
return instance
This was Godot 2.1 code. However, in Godot 3.1 with typed GDScript, this is no longer possible. get_script().new() also does not work as it says can't call non-static function from a static function.
@chanon @vnen Yeah this is definitely still a problem, but only in the domain of static functions. In order to do it, I usually have to use a load(<hard-coded path to same file>).new() in order to create factory methods.
@willnationsdev Should this issue be closed in favor of #27491?
Closing in favor of #27491.
Most helpful comment
I was looking at some old code by someone else.
They were doing something like:
This was Godot 2.1 code. However, in Godot 3.1 with typed GDScript, this is no longer possible. get_script().new() also does not work as it says
can't call non-static function from a static function.