Custom Type Object reference inside Function
BlitzMax Forums/BlitzMax Programming/Custom Type Object reference inside Function
| ||
Hi I would like to create some kind of helper function manipulating custom type object. I'm wondering how to pass instanced object inside a function so i can modify them. A bit like getColor(r,g,b) which modify every given variable. I know it as something to do with varptr but it's getting harder with custom Type Object ! Thanks |
| ||
objects are allways by reference. colors thought are not objects, they are always by value. if you want to pass them by ref, do so through var (see max2d getcolor, getscale etc) |
| ||
Thanks ! I forgot this attribute :) Well I never use it to be exact ^^ |
| ||
objects are allways by reference. That's not trueLocal lista:TList = New TList lista.AddFirst("Hello") Print lista.Count() ChangeList(lista) Print lista.Count() ChangeList2(lista) Print lista.Count() Function ChangeList(list:TList) list = New TList End Function Function ChangeList2(list:TList Var) list = New TList End Function the output of this code is: 1 1 0 if they were passed always by reference, the output would be 1 0 0 the objects are passed by value, but having the value of an object lets you change its fields and use its methods and functions, etc. |
| ||
Hum interesting to know that particular case. Thanks Ziggy ! Currently var do the job since I just need to change fields, use methods and so on. But it's probably why when I try to pass a 'self' object and get error. Example : Type myType Field value:Int Method run() Print value myFunctionA(value) 'value could have been of any other type except self Print value myFunctionB(Self) Print value End Method End Type Function myFunctionA(o:Int Var) 'this function work's o = 10 End Function Function myFunctionB(o:Object Var) 'this one not no matter I set o:Object or o:myType ... myType(o).value = 20 'Casting won't help too End Function Local t:myType = New myType t.run |
| ||
You can't mix Var to object with self. Allowing this would be very dangerous as 'self' could be modified inside the function, and obviously that would leave your calling class in a very inconsistent state. Remove Var from the function as you're only changing a field on the class. It should work.Type myType Field value:Int Method run() Print value myFunctionA(value) 'value could have been of any other type except self Print value myFunctionB(Self) Print value End Method End Type Function myFunctionA(o:Int Var) 'this function work's o = 10 End Function Function myFunctionB(o:Object) 'this one not no matter I set o:Object or o:myType ... myType(o).value = 20 'Casting won't help too End Function Local t:myType = New myType t.run |
| ||
Oh ! Thanks Manel :) I was a little bit lost there and forgot some rules ^^ I check with Blide debbuger and now I'm sure my helper function work 100% as I would. Very handy this debbuger ! |
| ||
objects are allways by reference. Actually it is. I'll be a bit nit picky here, but when you use "Var" on an object parameter, what happens is that the *reference* to the object is passed by...reference (!).That's not true So in your example the call to ChangeList indeed modifies "lista" (which is just a reference), but the object it initally pointed to (the TList instance created on the first line) is kept unchanged. |
| ||
@Koriolis: You're right. :D that's the correct way to explain it, it is the reference that is passed by reference. |
| ||
On the self thing: Self as super is no fully fledged object reference. There are things you can do with regular object references that are not possible with self as the GC protects some stuff from "within the object" for consistency. |
| ||
I'm not getting the difference, could you explain it more please. |
| ||
Me neither. |
| ||
Basically and object reference can be changed: Example: Local X:Tlist X = New Tlist 'First Change X.AddFirst("Hello") Local Y:Tlist Y = New Tlist X = Y 'Change of reference A 'self' object reference can't do that: 'Example of what should not be done under any circumstance!!! Type MyType Field Value:int Method GenerateBug() Self = new MyType 'That's not allowed. Imagine the inconsistence of the object it that was allowed!!!!! end Method End Type so at the end: 'Another example of what should not be done under any circumstance!!! Type MyType Field Value:int = 100 Method Danger() ChangeInstance(Self) 'this is also not allowed in a var parameter, as inside the function self could be modified!!!! End Method End Type Function ChangeInstance(Obj:MyType var) Obj = New MyType End Function But while you're using regular references this is obviously allowed: Type MyType Field Value:int = 100 End Type Function ChangeInstance(Obj:MyType var) Obj = New MyType End Function Local X:MyType = New MyType X.Value = 100 print X.Value ChangeInstance(X) Print X.Value And in this case the output is: 100 hope that makes it a little bit clearer 10 |
| ||
that Self can not do that and is not meant to do that is clear. Thats a totally brain dead idea, sorry. if you call Self, you ARE on the object! So you definitely don't want to alter it completely while working on it, thats about the most stupid and consistency wise worst idea you could come up with ... the only thing it does is guarantee unpredictable behavior ... |
| ||
@Dreamora: Making clear what you say was the objective of the previous post, and that's why the compiler doesn't let you do that. It was just an example for those who doesn't understand how exactly self works. I would recomend noob users to think about self as a private read-only reference of each object, just in case this helps people understand how self works. (just my 2 cents) |