"private" aktuell wertlos

Übersicht BlitzMax, BlitzMax NG Allgemein

Gehe zu Seite 1, 2  Weiter

Neue Antwort erstellen

 

Dreamora

Betreff: "private" aktuell wertlos

BeitragFr, Jan 07, 2005 6:56
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich bin aktuell dabei verschiedene Datenstrukturen zu implementieren in Form eines Modules, dass ich dann auch zum Download anbieten werde. Zusammen mit dieser Entwicklung wollte ich eigentlich auch ein kleines Tut zu Modulen und Informationhiding machen.

Doch min. letzteres muss man knicken, weil private total nutzlos ist.

Das einzige was sich in private Blöcken befinden darf, sind funktionen, globals und andere non OO Dinge.

Wenn man darin allerdings Types deklariert und public types die diese privaten Types nutzen, dann weigert sich der compiler strickt weil er meint dass die types in der .i datei nicht gefunden wurde.

Damit alle verstehen, was ich meine, hänge ich hier ma den Source des Stack Modules ran:



Code: [AUSKLAPPEN]
Strict

Module datastructure.stack


Private
' Implementation

Type TStack_Element
   Field element:Object
   Field connected:TStack_Element
   
   Function create:TStack_Element( _elem:Object )
      ' create a TStack_Element
      
      Local temp:TStack_Element   = New TStack_Element
      If _elem = Null
         Throw "No element given"
      EndIf
      
      temp.element            = _elem
      Return temp
      
   End Function
   
End Type

Type TStack_Imp
'   Implementation class
'       Musste geknickt werden, da die im private auch net akzeptiert wird
'   Field _top:TStack_Element
'   Field _count:Int
   
End Type


Public
' Module Export

Type TStack extends TStack_Imp
   Field _top:TStack_Element
   Field _count:Int
   
   Function create:TStack()
      Local temp:TStack   = New TStack
      Return temp
   End Function
   
   Method Push( _elem:Object )
      Local temp:TStack_Element
         
      temp         = TStack_Element.create( _elem )   
      temp.connected   = _top
      _top         = temp
      _count          :+ 1

   End Method
   
   Method Pop:Object ()
      Local temp:TStack_Element
      Local ret:Object
      
      If _count > 0
         _count   :- 1
         temp   =    _top
         _top   =   _top.connected
      EndIf
      ret   = temp.element
      Release temp
      Return ret
   End Method
   
   Method Top:Object ()
      Return _top.element
   End Method
   
   Method Count:Int ()
      Return _count
   End Method
   
End Type


Die Compilation des Modules funktioniert fehlerfrei. Wenn man es jedoch verwenden will kommt folgender Fehler:

Code: [AUSKLAPPEN]

[ERROR]: Compile Error:Identifier 'TStack_Element' not found
[ERROR]: [e:\programming\blitzmax/mod/datastructure.mod/stack.mod/stack.d.i;2;1]




Ich frage mich ehrlich, was ( wenn überhaupt ) sich mark da überlegt hat. Er programmiert selbst seit Jahren mit C++ und sollte definitiv wissen, von welch elementarer Bedeutung das ist.
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen.

bruZard

BeitragFr, Jan 07, 2005 8:41
Antworten mit Zitat
Benutzer-Profile anzeigen
Der Fehler kommt nur wenn Du versuchst aus dem importierenden Source auf Private Strukturen zuzugreifen. Private Daten dürfen nur von Private Funktionen (Methoden) verändert werden.
PIV 2,4GHz - 1GB DDR 333 - ATI Radeon9600 - WinXP - DX9.0c - BMax 1.14 - B3D 1.91 - 1280x1024x32

User posted image
 

Dreamora

BeitragFr, Jan 07, 2005 8:57
Antworten mit Zitat
Benutzer-Profile anzeigen
Und das verhalten ist so falsch wie es Private unbrauchbar macht.

Sorry wir haben eine OO Sprache hier, wo ist da der nutze wenn man kein Information- und Implementationhiding betreiben kann?

Schlimm genug das man Private nicht IN Types verwenden kann aber scheinbar kann man es im zusammenhang mit Types und OO überhaupt nicht brauchen was imho heisst das man es einfach garnet brauchen kann und ernsthafte Modulentwicklung auch glei kicken kann. ( solange man membervariablen der types net vor zugriff sperren kann ist das nicht möglich )

Da weder

Private

type a
endtype

mit:

public

type b extends a
endtype

noch mit:

public

type c
field xx:a
end type


funktionieren, kann man private auch glei vergessen ( an non OO bin ich net interessiert, dafür kann ich PB benutzen )


[edit]

Hinweis zu oberem: wenn man das modul kompiliert geht es. wenn man allerdings eine instanz des types b oder c erzeugt kommt ein fehler das a in module.i / module.d.i nicht gefunden wurde, dabei hat es danach garnix zu suchen, da mein Source der das Module benutzt keine Instanz von a hat, sondern nur b und c die selbst member des moduls sind!!!
der compiler ist aktuell einfach noch zu blöd um effizient zu arbeiten. was haben bloss die betatester die letzten monate gemacht??
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen.

bruZard

BeitragFr, Jan 07, 2005 9:42
Antworten mit Zitat
Benutzer-Profile anzeigen
Ja, die Implementation ist schon merkwürdig, funktioniert aber:
Code: [AUSKLAPPEN]

Print "schnicks"

Public

Type TTest
   Field x:Int
   
   Method InitX(xx:Int) Abstract
   Method GetX() Abstract
End Type

test:TTest2   = New TTest2
test.InitX(100)
t:Int=test.GetX()

Print "T= "+t

rem
   Private Daten und Methoden
End Rem

Private

Type TTest2 Extends TTest
   Field x:Int
   
   Method InitX(xx:Int)
      x=xx
   End Method
   
   Method GetX:Int()
      Return x
   End Method
End Type


Definiere einfach im Public Bereich alle Methoden der Typen als Abstract und implementiere sie erst im Private Bereich.

Dennoch ein Bug: Wenn ich das "Print "Schnicks"" oben wegnehme, erfolgt keine Ausgabe im Debugger Shocked
PIV 2,4GHz - 1GB DDR 333 - ATI Radeon9600 - WinXP - DX9.0c - BMax 1.14 - B3D 1.91 - 1280x1024x32

User posted image
 

Dreamora

BeitragFr, Jan 07, 2005 9:55
Antworten mit Zitat
Benutzer-Profile anzeigen
das bringt mir aber nix, ich brauche es in die umgekehrte Richtung!
In die richtung ist es ja kein problem nur halt total nutzlos ...

Der Grundtype muss im Private sein und der extended im Public damit die Fields etc von aussen weder einsehbar noch modifizierbar sind so dass ich die Systemkonsistenz "garantieren" kann ( zumindest bis an den Punkt wo sie der GarbageCollector selbst nicht mehr garantieren kann wie die ausführung von Delete etc )


Hier ein kleines Beispiel:

Code: [AUSKLAPPEN]

private

Type Vector3D_Imp
 ' Die werte hier drin können von ausserhalb nicht gesetzt werden
 field _x,_y,_z:float
 
 global list:TList
 
 method new()
  if list = null
    list = new TList
  endif
  list.addlast( self )
 end method
end type

public

type Vector3D extends Vector3D_Imp
 ' die hier enthaltenen funktionen und methoden sind von aussen verwendbar
 function create:Vector3D( x,y,z:float )
  local temp:Vector3D = new Vector3D
  temp._x = x
  temp._y = y
  temp._z = z
  return temp
 end function

end type


Ich will zb in diesem fall nicht dass die programmierer von aussen an die liste oder koordinaten ran kommen um daran rumzumanipulieren. Ich weiss, ist nicht das optimale Beispiel ... Aber es gibt in jedem OO System variablen die man nicht von aussen manipulieren darf wie zb klasseninvarianten in dergleichen und dafür wird diese splittung benötigt.
Das ist nur aktuell nicht möglich ... sehr schade und sehr unverständlich da mark seit jahren OO programmierer ist und die wichtigkeit des information hidings und access restriction kennen sollte
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen.
 

Nemesis

BeitragFr, Jan 07, 2005 11:58
Antworten mit Zitat
Benutzer-Profile anzeigen
Also das Private und Public ned zu gebrauchen ist ist mir auch schon aufgefallen.
Da bleibt dir im moment wohl nichts anderes übrig als darauf zu vertrauen das der Anwender des Modules die Varriablen des Types nur über die entsprechenden Setter und Getter Funktionen ändert und ausliest. Wer sich dan hald nicht daran hällt soll sich nicht beschweren wenn das Programm fehler anfällig ist.

bruZard

BeitragFr, Jan 07, 2005 12:02
Antworten mit Zitat
Benutzer-Profile anzeigen
Wenn die Fields erst in der Implementation definiert werden und der Private Bereich als Modul kompiliert wird, können die User die Fields nicht einsehen und somit auch keine Werte gesetzt werden.
PIV 2,4GHz - 1GB DDR 333 - ATI Radeon9600 - WinXP - DX9.0c - BMax 1.14 - B3D 1.91 - 1280x1024x32

User posted image
 

Dreamora

BeitragFr, Jan 07, 2005 12:16
Antworten mit Zitat
Benutzer-Profile anzeigen
Und was meinst du damit genau?

Ich will einen Type haben der die daten enthält und interne methoden und einen der aus dem module ( ich meine wirklich explizit module nicht ein source, da da andere regeln zu gelten scheinen ).

Oben wurde ja mal das mit TTest und TTest2 genannt. Nur TTest2 kann man nicht benutzen da es nach einer Modulkompilation nicht mehr existiert was ja bei mir auch das problem ist, weil es der kompiler zersägt!!!

Direkt in einer Exe ist alles ja kein problem aber das nutzt mir 0.0 wenn ich ein datentype modul machen will!!!

wenn du mir allerdings funktionierenden modulsource hast der das informationhiding beinhaltet: Immer her damit, habe nix dagegen das es geht Very Happy
Es folgt dann aber auf jeden fall keiner normalen programmierlogik noch den OO design "regeln"
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen.

bruZard

BeitragFr, Jan 07, 2005 12:49
Antworten mit Zitat
Benutzer-Profile anzeigen
Sobald ich hier unter Linux endlich diese verf****en ATI Treiber installiert habe werde ich das mal testen ... kann ja garnicht sein dass es da keine Lösung geben soll Wink
PIV 2,4GHz - 1GB DDR 333 - ATI Radeon9600 - WinXP - DX9.0c - BMax 1.14 - B3D 1.91 - 1280x1024x32

User posted image
 

Dreamora

BeitragFr, Jan 07, 2005 12:57
Antworten mit Zitat
Benutzer-Profile anzeigen
Warum?
Er hats schon verpennt Private / Public innerhalb von types zu ermöglichen. ich würd sagen er hat es implementiert als er noch garkein OO hatte und nun ist es schrott.
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen.
 

MasterK

BeitragFr, Jan 07, 2005 13:49
Antworten mit Zitat
Benutzer-Profile anzeigen
seit wann sollte man private variablen/typen/wasauchimmer im public bereich nutzen können? es heisst doch nicht umsonst "private".

wenn ich in c++/java/wasauchimmer versuche im public-bereich einen struct zu benutzen den ich im private-bereich deklariert habe geht das auch nicht. so sollte es doch auch sein.
+++ www.masterk.de.vu +++
Lila FTW!
 

Black

BeitragFr, Jan 07, 2005 13:58
Antworten mit Zitat
Benutzer-Profile anzeigen
Erm, im allgemeinen ist das interface public und die implementation private.
Also genau umgekehrt:

public
type abstract myInterface
blabla
end type

private
type myImp extends myInterface
hier kommt die implementation
end type

public
Function GetImp:myInterface()
Return new myImp
End Function
 

Dreamora

BeitragFr, Jan 07, 2005 13:58
Antworten mit Zitat
Benutzer-Profile anzeigen
type = class nicht struct

Das prob ist das wir private / public nicht innerhalb der types benutzen können wo sie eigentlich hingehören.

das problem ist dass du in privates globals, const und funktionen deklarieren kannst die du im rest des modules nutzen kannst, wieso also sollte man nicht types deklarieren können die man im rest dieser BMX nutzen kann???
das ist ja sinn und zweck der übung, dass man dinge nach "aussen" versteckt und nicht innerhalb der sourcefile selbst.


black: und wie willst du in die richtung darauf zugreifen?
Du kannst ja nur auf superklassen und deren implementationen zugreifen, nicht auf nachfolgeklassen ... also in normalen OO sprachen zumindest.

und solange der imp teil ausserhalb des privates nicht existiert kann man ihn nicht zuweisen oder instanzieren... dann gehts nur über die verkorkste variante des BRL.System wo
global driver:TSystemDriver
deklariert ist um das verkorkste private / public zu umgehen.
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen.
  • Zuletzt bearbeitet von Dreamora am Fr, Jan 07, 2005 14:03, insgesamt einmal bearbeitet

bruZard

BeitragFr, Jan 07, 2005 14:01
Antworten mit Zitat
Benutzer-Profile anzeigen
@MasterK: Das Problem: Ich kann in einem Type (welches privat implementiert wurde) in BMax dennoch Fields von aussen verändern ohne die dafür vorgesehenen Methoden des Objekts zu verändern.

Guckst Du hier:
Code: [AUSKLAPPEN]

Private
Type TTest
  x:Int

  Method SetX(xx:Int) Final
    x=xx
  End Method
End Type

Public
test:TTest = New TTest
test.x = 100

Habe es jetzt nicht getestet, sollte aber im Kontext mit meinem obigen Source funktionieren und das darf nicht sein.
PIV 2,4GHz - 1GB DDR 333 - ATI Radeon9600 - WinXP - DX9.0c - BMax 1.14 - B3D 1.91 - 1280x1024x32

User posted image
 

MasterK

BeitragFr, Jan 07, 2005 14:04
Antworten mit Zitat
Benutzer-Profile anzeigen
wenn man konstanten etc im private-bereich deklarieren kann die man überall nutzen kann ist das schon schlimm genug. ist doch gut dass man dass nich auch noch mit types machen kann Smile

ich versteh nich so ganz wieso du sachen nach "aussen" verstecken willst wenn du aussen doch eh wieder von ihnen ableitest. private sollte eben wirklich nur private sein.

oder versuchst du hier so ne art "protected" zu realisieren?
+++ www.masterk.de.vu +++
Lila FTW!
 

Dreamora

BeitragFr, Jan 07, 2005 14:12
Antworten mit Zitat
Benutzer-Profile anzeigen
ich versuche effektiv ein "type internes" private zu realisieren ...

aber solange ich types aus dem private GARNICHT verwenden kann selbst innerhalb des selben modules ( in normalen programmen ist es garkein problem da dort kein module generiert wird! das ist ja das schlimme an der situation ... source -> exe geht, source -> module geht net! ) kann man einfach kein information hiding machen.


mit dem export nach aussen bei den extends hast du leider recht, soweit habe ich net gedacht.
Aber selbst dann könnte man es über
Code: [AUSKLAPPEN]


private

Type A
 field trala
end type

public

Type B
 field A
 ' funktionen zum A modifizieren
end type


"faken" ... aber das würde voraussetzen das private nur ausserhalb des modules gültig ist ... was es eben nicht ist. Warum er allerdings beim module compile nicht motzt weiss der geier ...
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen.
 

Nemesis

BeitragFr, Jan 07, 2005 16:27
Antworten mit Zitat
Benutzer-Profile anzeigen
MasterK: was er/wir wollen ist nur einzelne Felder eines types Privat zu machen das man sie nur über die entsprechenden setter und getter routinen setzten und auslesen kann um sicherzustellen das nur gültige werte hineinkommen.
 

Dreamora

BeitragFr, Jan 07, 2005 18:07
Antworten mit Zitat
Benutzer-Profile anzeigen
Es hat mich stunden gekostet, aber hier ist nun die Lösung!

Ich möchte mich dabei kurz bei MasterK bedanken für den Einwurfe mit Java und den Interfaces. Er erinnerte mich an etwas was wir vor einiger Zeit ma hatten, das ich aber wegen "Unnützigkeit" wieder verworfen hatte, das mir jetzt aber doch sehr zu Gute gekommen ist.


Hier ist die Lösung wie man Information Hidding betreibt.

Exportiert aus dem Module wird nur TStack, der Rest bleibt vor der Welt versteckt.

Wird in mein "how to create a module" tutorial einfliessen als natürlich auch mein Datenstrukturen Module, das in naher Zukunft auch zur Verfügung stehen wird, wenn alles sauber implementiert ist.

Modulsource:

Code: [AUSKLAPPEN]


Strict

Module datastructure.stack


Private

' Stack Implementation

Type TStack_Element
   Field _element:Object
   Field _connected:TStack_Element
   
   Function create:TStack_Element( _elem:Object )
      ' create a TStack_Element
      
      Local temp:TStack_Element   = New TStack_Element
      
      temp._element            = _elem
      Return temp
      
   End Function
   
   Method Delete()
      _element    = Null
      _connected    = Null
   End Method
End Type

Type TStack_Imp Extends TStack
'   Implementation of stack
   Field _top:TStack_Element
   Field _count:Int
   
   Function create:TStack_Imp()
      Local temp:TStack_Imp   = New TStack_Imp
      Return temp
   End Function
   
   Method push( _elem:Object )
      Local temp:TStack_Element
         
      temp         = TStack_Element.create( _elem )   
      temp._connected   = _top
      _top         = temp
      _count          :+ 1

   End Method
   
   Method pop:Object ()
      Local ret:Object
      
      If _count > 0
         _count         :- 1
         ret            =    _top._element
         _top         =   _top._connected
      EndIf
      Return ret
   End Method
   
   Method top:Object ()
      Return _top._element
   End Method
   
   Method count:Int ()
      Return _count
   End Method
   
   Method clear()
   
      While count() > 0
         pop()
      Wend
      
   End Method
End Type


Public
' Module Export


Type TStack

   Function create:TStack()
      Local temp:TStack = TStack_Imp.create()
      Return TStack( temp )
   End Function

   Method push( _elem:Object ) Abstract
   
   Method pop:Object () Abstract
   
   Method top:Object () Abstract
   
   Method count:Int () Abstract
   
   Method clear() Abstract

End Type



Testsamplesource:

Code: [AUSKLAPPEN]

Strict

Local stack:TStack   = TStack.create()
Local i:Int

For i = 1 To 2000
   stack.push( String("Test "+i) )
Next

Print "Elemente im Stack: " + stack.count()
Print "Erstes Element: " + String( stack.pop() )

flushmem
Print "Benötigter Speicher: " + MemAlloced()

stack.clear
FlushMem
Print "Benötigter Speicher: " + MemAlloced()
Print "Anzahl Elemente: " + stack.count()

Delay 10000
End



PS: Ich hasse es wenn ich meine eigenen Aussagen nach unzähligen Stunden, 200g Kaffeepulver, 5L Eistee und viel Kopfweh selber wiederlege!!! 8)
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen.

TheShadow

Moderator

BeitragFr, Jan 07, 2005 19:18
Antworten mit Zitat
Benutzer-Profile anzeigen
also funzt alles wie es soll? was war falsch?
AMD64 3500+ | GeForce6600GT 128MB | 1GB DDR | WinXPsp2
 

Demon

BeitragFr, Jan 07, 2005 21:54
Antworten mit Zitat
Benutzer-Profile anzeigen
Zitat von bruZardZitat:
Definiere einfach im Public Bereich alle Methoden der Typen als Abstract und implementiere sie erst im Private Bereich.


Zitat von DreamoraZitat:
Es hat mich stunden gekostet, aber hier ist nun die Lösung!


Nichts für ungut, aber das hätte ich jetzt nicht zugegeben.
Don't drink and derive!

Gehe zu Seite 1, 2  Weiter

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group