[Closed] Trying to 'overload' function within struct
This is why I told Martin to post here as I knew you had a way… if only I could remember it… Look forward to seeing your solution!
the idea is to have the same PrintMyVal function for all struct instances. in your case they are all unique. i can’t try it but more likely a copy of an instance doesn’t work:
b = myStruct()
b.PrintMyVal = (fn PrintMyVal val: = print (b.myVar * val))
c = copy b
b.myvar = 2
b.printmyval val:2 -- ?
c.myvar = 3
c.printmyval val:2 -- ?
Yes, that won’t work as the function holds a reference to the structure.
So the whole problem now seems to be reduced to how to get the function to self-reference the structure it belongs to. If only ‘this’ would work.
No, it doesn’t work. You get the same result.
I have tried this that seems to work, but I don’t know if it’s what we are looking for:
(
struct myStruct
(
ccc = this,
myVar = 0,
PrintMyVal,
on create do PrintMyVal = (fn PrintMyVal = print "Source")
)
local PrintMyVal = (fn PrintMyVal ref: val: = print (ref.myVar * val))
a = myStruct()
b = myStruct()
b.PrintMyVal = PrintMyVal
a.PrintMyVal()
b.myVar = 3
b.PrintMyVal ref:b val:2
c = copy b
c.myVar = 5
c.PrintMyVal ref:c val:4
)
Note: All my attemps to use ‘this’ have been a disaster
‘this’ is a special word for compiler. on compilation moment compiler replaces it with a reference to structure. so ‘this’ makes sense only in the structure body (same as rollout, plugin)
you pass the structure itself to the function. to be a function of a structure and get this structure as a parameter doesn’t make sense.
In my example:
print c --------> (myStruct myVar:5 PrintMyVal:PrintMyVal())
print c.this --------> (myStruct myVar:3 PrintMyVal:PrintMyVal())
print c.myvar --------> 5
print c.this.myvar --------> 3
Does it make sense?
struct theStruct
(
a,
b,
c,
action,
fn doAction = (c = action a b)
)
fn _action a b = (a * b)
a = theStruct a:2 b:3 action:_action
b = theStruct a:4 b:5 action:_action
a.doAction()
b.doAction()
c = copy b
c.a = 5
c.doAction()
as i said above i can’t try it without max. so please let me know how it works, and errors it displays if any
How would it be if I wanted to have these functions?
(
struct theStruct
(
a,b,c,d,e,f,g,h,
action,
fn doAction = (c = action a b)
)
-- fn f1 = return (a*b*c*d*e*f*g*h)
-- fn f2 = return ((a/b)*(f+g))
-- fn f3 = return (f-a)
)
This is the result…
#Struct:theStruct(
action:<data>; Public,
b:<data>; Public,
doAction:<fn>; Public,
c:<data>; Public,
a:<data>; Public)
_action()
(theStruct a:2 b:3 c:undefined action:_action())
(theStruct a:4 b:5 c:undefined action:_action())
6
20
(theStruct a:4 b:5 c:20 action:_action())
5
25
that means the code works absolutely right
does it work if we change only one line?
replace
action,
with
fn action a b = (),
as you can see _action has no idea about where it will be working. it might be passed to any structure which does do something with its two own properties.
the coolness of it is that different parts of code can change a and/or b properties, and action for them. these parts of code can do nothing about each other
the possible realization:
a = theStruct a:x_axis b:z_axis action:cross
b = theStruct a:x_axis b:z_axis action:dot
i see two solutions.
the first one is to use doAction functions for every possible kind arguments passing. it’s like c or c# multiple function definitions
the second is to make _action getting all possible parameters as optional, and pass them all in doAction:
fn _action a: b: c: d: = (...)
doAction = action a:a b:b c:c d:d
i would probably pass only one parameter of a specified type (some sub-structure)
I was actually hoping there would had been a way of self-referencing the variables. I find a little cumbersome to write a custom function for every other custom function you want to redefine that needs access to different properties.
doAction function can pass ‘this’, and action get a struct argument with the same properties as the main struct. that’s what you would do
struct theStruct
(
width, lenght, height,
action,
fn doAction = (action this)
)
fn _actionXY data = (data.widht*data.length)
fn _actionXZ data = (data.widht*data.height)