Lambdas capture local variables by value

In Godot, GDScript lambdas only copy the value of each variable it captures (by design; see godotengine/godot#69014). However, since the value of a Variant is itself a reference, you can use a Variant to get around this problem if you want the lambda to mutate a capture. 1 2

For example, this does not work: 2

func foobar():
	var stop = false
	var stop_callback = func():
			stop = true
	some_signal.connect(stop_callback)
 
	await get_tree().create_timer(10).timeout
 
	print(stop) # Always false

But this does: 2

func foobar():
	var stop = { "value": false }
	var stop_callback = func():
			stop["value"] = true
	some_signal.connect(stop_callback)
 
	await get_tree().create_timer(10).timeout
 
	print(stop["value"]) # Either true or false

I used to consider this a Godot crime, but I have since changed my mind. 3 2

History

Footnotes

  1. godot lambdas do not capture by design

  2. 20240704072433 2 3 4

  3. 202310030153