Skip to content
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

Setters/Getters don't allow functions with default arguments #74144

Open
cullumi opened this issue Mar 1, 2023 · 4 comments · May be fixed by #78991
Open

Setters/Getters don't allow functions with default arguments #74144

cullumi opened this issue Mar 1, 2023 · 4 comments · May be fixed by #78991

Comments

@cullumi
Copy link

cullumi commented Mar 1, 2023

Godot version

4.0-rc6_win64

System information

Windows 10

Issue description

I was converting a Godot 3.5 project of mine to Godot 4 and found the following code throws an error:

var dims : set = set_dims

func set_dims(_dims, some_arg=null):
{
    print(some_arg)
    dims = _dims
}

Error: Function "set_dims" cannot be used as setter because of its signature.

I can luckily get the functionality to work with alternative syntax, but it's a bit silly and overly verbose when you have a lot of setters that should otherwise be very simple. It impacts readability quite a bit.

For example, the following:

var dims : set = set_dims
var surface : set = set_surface
var counts : set = set_counts
var bedrock : set = set_bedrock
var size : set = set_size

Becomes this:

var dims :
    set(_dims): set_dims(_dims)
var surface :
    set(_surface): set_surface(_surface)
var counts :
    set(_counts): set_counts(_counts)
var bedrock :
    set(_bedrock): set_bedrock(_bedrock)
var size :
    set(_size): set_size(_size)

I can't see any particular reason for this not to work, seeing as normal function calls can call functions without overriding default values. I'd probably call this a regression.

I found an issue back from 3.1 beta10, which seems to be when the original functionality was implemented: #26530

Steps to reproduce

The sample code from above should do it:

var dims : set = set_dims

func set_dims(_dims, some_arg=null):
{
    print(some_arg)
    dims = _dims
}

Minimal reproduction project

N/A

@dalexeev
Copy link
Member

dalexeev commented Mar 1, 2023

See godotengine/godot-proposals#6107.

Now you can work around it like this:

var my_var:
    get: return get_my_var()
    set(value): set_my_var(value)

func get_my_var(a = 1, b = 2):
    ...

func set_my_var(value, a = 1, b = 2):
    ...

@nyxkn
Copy link

nyxkn commented Jun 26, 2023

@dalexeev That doesn't seem to be working.

With that code, both setter and getter trigger an infinite loop.

var my_var = 0:
	get: return get_my_var()
	set(value): set_my_var(value)

func get_my_var(a = 1, b = 2):
	return my_var

func set_my_var(value, a = 1, b = 2):
	my_var = value

func _ready() -> void:
	print(my_var) # triggers infinite recursion
	my_var = 2 # triggers infinite recursion

@dalexeev
Copy link
Member

Use a private variable:

var my_var:
    get: return get_my_var()
    set(value): set_my_var(value)

var _my_var = 0

func get_my_var(a = 1, b = 2):
    return _my_var

func set_my_var(value, a = 1, b = 2):
    _my_var = value

func _ready() -> void:
    print(my_var)
    my_var = 2

@nyxkn
Copy link

nyxkn commented Jun 26, 2023

Brilliant. That's how it is. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants