Custom Type Object reference inside Function

BlitzMax Forums/BlitzMax Programming/Custom Type Object reference inside Function

Armitage 1982(Posted 2008) [#1]
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


Dreamora(Posted 2008) [#2]
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)


Armitage 1982(Posted 2008) [#3]
Thanks !

I forgot this attribute :)
Well I never use it to be exact ^^


ziggy(Posted 2008) [#4]
objects are allways by reference.
That's not true
Local 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.


Armitage 1982(Posted 2008) [#5]
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



ziggy(Posted 2008) [#6]
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



Armitage 1982(Posted 2008) [#7]
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 !


Koriolis(Posted 2008) [#8]
objects are allways by reference.

That's not true
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 (!).
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.


ziggy(Posted 2008) [#9]
@Koriolis: You're right. :D that's the correct way to explain it, it is the reference that is passed by reference.


Dreamora(Posted 2008) [#10]
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.


Czar Flavius(Posted 2008) [#11]
I'm not getting the difference, could you explain it more please.


Gabriel(Posted 2008) [#12]
Me neither.


ziggy(Posted 2008) [#13]
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
10
hope that makes it a little bit clearer


Dreamora(Posted 2008) [#14]
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 ...


ziggy(Posted 2008) [#15]
@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)