Why is this possible?

BlitzMax Forums/BlitzMax Programming/Why is this possible?

ziggy(Posted 2007) [#1]
Why is this possible?
Type MyTypeA
    Field MyField:MyTypeB = New TypeB
End Type
Private
Type MyTypeB
    Method Draw:int()
    End Method
End Type
Public

Local MyInstance:TypeA = New TypeA
MyInstance.MyField.Draw()

Why it is possible to access private types functionality by a public field? Shouldn't this produce compiler errors?

If it is legit, then you can use a private type instanced in a field of a public type to store and get all private fields, methods, globals and funcs in a class!!

Something like:
Type MyClass
    Field _Private:MyClassPrivate = New MyClassPrivate
    Method MyMethod1:int()
         'Use a private field:
         Return _Private.PrivateField1
    End Method
    Method MyMethod2(K:int, J:Int)
        'Call internally a private method:
        Local X:int = _private.MyMethod1(self, k)
        'Store the result in a private field:
        _private.PrivateField1 = x
    End Method
End Type
Private
Type MyClassPrivate
    Field PrivateField1:int, PrivateField2
    Method PrivateMethod1:int(BaseClass:MyClass, OtherParams)
    End Method
end Type


Is this 'legal' ?


Dreamora(Posted 2007) [#2]
Why is this possible: Private only means that stuff within that area can not accessed by anything outside this BMX
it does not protect it from any other stuff.

It is only for functionality hidding.
Its similar to Javas Protected that only allows access within the same package.


ziggy(Posted 2007) [#3]
Yes but it is allowed in modules!

It compiles but it doesn't find methods or fields. That's awesome.

code for MyFile.bmx:
SuperStrict
Import blide.test1

Local i:MyTypeA = New MyTypeA
i.MyField.Draw() 


code for module blide.test1 (blitzmax/mod/blide.mod/test1.mod/test1.bmx)
Type MyTypeA
    Field MyField:MyTypeB = New MyTypeB
End Type
Private
Type MyTypeB
    Method Draw:int()
    End Method
End Type
Public

Local MyInstance:MyTypeA = New MyTypeA
MyInstance.MyField.Draw() 


Isn't this a very interesting way to have a sort of private fields and methods on modules?


Dreamora(Posted 2007) [#4]
No it is not.
Extension is broken which makes them quite pointless / totally defeats the point of OO.

There are potentially simpler ways to get it out of the "known variable space".


ziggy(Posted 2007) [#5]
No, extension is not broken, that's the amazing point!
I think the example i was providing is not really showing what I mean:

Code for module blide.test1 (blitzmax/mod/blide.mod/test1.mod/test1.bmx)
SuperStrict
Import brl.max2d
Type LineConcat
	Field _private:TLConcatPrivate = New TLConcatPrivate
	Method DrawLine(x:Int, y:Int) 
		_private.DrawLine(Self, x, y) 
	End Method
	Method SetPos(x:Int, y:Int) 
		_private.X = x
		_private.Y = y
	End Method
End Type
Private
Type TLConcatPrivate
	Field X:Int
	Field Y:Int
	Method DrawLine(LC:LineConcat, x:Int, y:Int) 
		brl.max2d.DrawLine(x, y, Self.X, Self.Y) 
		Self.X = x
		Self.Y = y
	End Method
End Type
Public


And then, the sample code for MyFile.bmx:
SuperStrict
Import blide.test1
Graphics(800, 600) 
Cls
Flip
Local P:LineConcat = New LineConcat
p.SetPos(Rand(0, 800), Rand(0, 600)) 
While Not KeyHit(KEY_ESCAPE) 
	p.DrawLine(Rand(0, 800), Rand(0, 600)) 
	SetColor 0, 0, 0
	DrawText("Using base class. (PRESS ESC)", 1, 1) 
	SetColor 255, 255, 255
	DrawText("Using base class. (PRESS ESC)", 0, 0) 
	Flip() 
Wend
Cls
Type LineConcatExtended Extends LineConcat
	Method DrawLine(x:Int, y:Int) 
		SetColor(Rnd(0, 255), Rnd(0, 255), Rnd(0, 255)) 
		Local F:Float = GetLineWidth() 
		SetLineWidth (7) 
		Super.DrawLine(x, y) 
		SetLineWidth(F) 
	End Method
End Type
Local p2:LineConcatExtended = New LineConcatExtended
While Not KeyHit(KEY_ESCAPE) 
	p2.DrawLine(Rand(0, 800), Rand(0, 600)) 
	SetColor 0, 0, 0
	DrawText("Using extended class. (PRESS ESC)", 1, 1) 
	SetColor 255, 255, 255
	DrawText("Using extended class. (PRESS ESC)", 0, 0) 
	Flip() 
Wend


In fact, in this example, the class LineConcat has a 'friend private' fields X and Y. Those fields are not accesible outside the module becouse they're based on a private type, but the class is still extensible outside the module. they are not real 'private' obviously, but they work a lot like visual basic .net 'friend' atributes, so they are only accesible inside the module. Obviously extending the class outside the module won't give you access to this sort of private fields and you will still have to call super.whatever to let the base class use them internally, but isn't this how friend fields are suposed to work? Am I missing something? I know it is not elegant, and maybe a litle bit heretic, but taking in consideration we don't have public and private at field or method level...

Let me know what you think, please.


Dreamora(Posted 2007) [#6]
OK that works.

But you again assume that users accept the _ as private classifier.

If they don't do, it totally bombs out the whole thing.

It is by worlds simpler to just remove classes, definitions and functions from the .i files of the modules.
There are only a few requirements that need to be met in your code ordering and it will work.
Actually I do not understand why BM does not support it out of the box.


ziggy(Posted 2007) [#7]
Dreamora: Yes, modifying interfaces can solve the issue. But the interesting thing here is:
If they don't do, it totally bombs out the whole thing.

No it doesn't. If you try to use anything of the _private field, the compiler will tell you 'can't find field X' or whatever. So it is not possible to modify the contents of this field from the bmx file using the module.