Currying is the process of baking some or all arguments to a function call for later use. You can then call a curried function, supplying missing parameters, and the actual call includes the stored arguments, combined with the ones provided when the curried function is called.
We have to abuse PackedScene (and ResourceLoader) to get instances of the Curry object, as will be seen in the SpiceRack test script.
Curry.gd script:
extends Node
#
# Currying bakes arguments into a function call for later use
# You can curry some or all of a method's paramters, than
# provide the remainder at the time of the call.
#
# One particular use of curry in GDScript is to work around
# call_deferred's 5-argument limitation.
#
var curry_call=[]
var curry_args=[]
func call_me(arglist):
if curry_call.size()<2:
pass
else:
var ob=curry_call[0]
var me=curry_call[1]
var args=[]
# add the curried arguments
for arg in curry_args:
args.append(arg)
# add the provided arguments to the curried ones
for arg in arglist:
args.append(arg)
# now do the appropriate Object.call
ob.callv(me,args)
func curry(ob,me,args):
curry_call=[ob,me]
curry_args.clear()
for arg in args:
curry_args.append(arg)
func _ready():
pass
- Create a Node, call it Curry, extend it (set script) to Curry.gd
- Save as Curry.tscn
SpiceRack.gd script:
extends Node
onready var Curry=load("Curry.tscn")
func testfunc(a="",b="",c="",d=""):
print("a=",a,", b=",b,", c=",c,", d=",d)
func somefunc(curried):
curried.call_me(["passed","as","argument"])
func _ready():
testfunc("called","normally")
var curry1=Curry.instance()
curry1.curry(self,"testfunc",["curry"])
var curry2=Curry.instance()
curry2.curry(self,"testfunc",["another_curry"])
curry1.call_me(["called","directly"])
somefunc(curry1)
curry2.call_me(["called","directly"])
somefunc(curry2)
- Create a Node, call it SpiceRack, extend it (set script) to SpiceRack.gd
- Save as SpiceRack.tscn
- In project settings, set default scene to SpiceRack.tscn
Enjoy!!!
Edit: Removed the inelegant wall of if's.