Just trying to understand setget functions

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Dumuz

The docs use this example:

var myvar setget my_var_set, my_var_get

func my_var_set(new_value):
    my_var = new_value

func my_var_get():
    return my_var # Getter must return a value.

It’s makes sense for me, up until my_var_get(). It’s returning a variable that isn’t actually a part of it’s function and when I try to make something like this script in godot, it tells me the variable in the get func isn’t declared in the current scope. What am I not understanding?

What I made:

var junc setget junc_set, junc_get

func junc_set(new_value):
	var check
	if new_value < 10:
		check = 0
	if new_value > 10:
		check = 100
		
func junc_get():
	return check
:bust_in_silhouette: Reply From: tastyshrimp

I think you got confused by what each part of the statement does, so to go through it.

We have this statement from the docs:

var variable = value setget setterfunc, getterfunc

The first part of the statement:

var variable = value

Is the normal declaration of a variable in GDScript, and what your error is about, you are declaring a variable called junc and using check inside your get and set methods.

setget setterfunc, getterfunc

Here you are defining which methods will be called when you try to either set or get the variable.
When setting variable = something the method setterfunc will be called.
And when getting something = variablethe method getterfunc will be called.

I feel I understand all that stuff just fine. But in that same example with the func my_var_get(): returning a variable that is not inside of it’s function itselfreturn my_var
It’s only in the setter function:

func my_var_set(new_value):
    my_var = new_value

So how does the getter function has access to this function in the example on the docs? How can it return a value that is inside another function without that variable being passed to it somehow?

Dumuz | 2019-12-19 22:22

it’s because myvar is the name of the variable set in the top line:

var myvar setget my_var_set, my_var_get

basically you are saying here, create in my current class context a variable called myvar which has a set validator called my_var_set and a get validator called my_var_get. So myvar is available for the entire class as it is a class member. Same way as in:

var myvar

func method():
   return myvar

tastyshrimp | 2019-12-19 22:26

Thank you for taking the time to help me understand this. I apologize for all the questions.

Correct me if I’m wrong, but the variable the getter is using in the doc’s example is NOT returning the myvar variable. It’s returning my_var which is an entirely new variable that was made inside the setter, specifically.

This is where I’m confused, because my_var (at least from my extremely limited understanding of coding in general) is different than myvar, because of the underscore that is used, is that right?

Dumuz | 2019-12-19 22:39

No, in this case the setter is using the above variable. In GDScript you can assume that a variable is only using the most internal one if it is declared. In case of the set method myvar is not being declared, the var keyword does that, as such, it is using the external one.
What you are describing would require the set method to be like this:

func my_var_set(new_value):
  var my_var = new_value

Or like this:

func my_var_set(my_var):
  my_var = 10

In the first case, myvar is being declared inside the function scope again, so it uses the internal one. In the second case, myvar is variable being passed as a parameter, that means it is being declared inside that scope.

tastyshrimp | 2019-12-19 22:46

So, how does:

func my_var_get():
    return my_var # Getter must return a value.

have access to my_var? Inside the doc example:

var myvar setget my_var_set, my_var_get

func my_var_set(new_value):
    my_var = new_value

func my_var_get():
    return my_var # Getter must return a value.

Dumuz | 2019-12-19 23:06

1: var myvar setget my_var_set, my_var_get
2: 
3: func my_var_set(new_value):
4:    my_var = new_value
5:
6: func my_var_get():
7:   return my_var # Getter must return a value.

On line 1, you are creating myvar for this script.
On line 4, you are setting the script level, line 1, myvar with the value new_value.
On line 7, you are getting the script level, line 1, myvar.

For your code to work you need to move the var check outside the setter, so it becomes a script level variable.
Just a basic how code works because who knows, maybe it helps, whenever you open a new context, in case of gdscript, add 1 tab. Whatever new var whatever you declare dies the moment you exit the context and whatever is in the context above, at least one less tab, can be accessed by whoever is in the internal context.

tastyshrimp | 2019-12-19 23:16

I understand what you’re saying, I feel so dumb right now.

I guess I just can’t grasp why var myvar is the same as my_var in sub sequential functions. That underscore is throwing me off.

Dumuz | 2019-12-19 23:26

Oh shit, you are right, shame on me. I didnt see that and I’m pretty sure you found a typo in the docs. myvar is supposed to be my_var for it to work.

It seems I automatically parsed it in my head, my bad.

And looking at the latest version of the docs, it is fixed: GDScript reference — Godot Engine (latest) documentation in English

tastyshrimp | 2019-12-19 23:30

OOOOOHHHHHHH!

Hahaha, I’m not crazy! XD

Okay, it all makes sense now. Thank you very much!

I didn’t realize I was looking at an older version of the docs.

Dumuz | 2019-12-19 23:36

You are welcome, and good we defined neither of us are crazy.

tastyshrimp | 2019-12-19 23:38