Makrooperator
Moderator: Moderatoren
- brandelh
- Foren-Moderator
- Beiträge: 15696
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 66 Mal
- Danksagung erhalten: 33 Mal
- Kontaktdaten:
Hi Manfred,
versuche es mal mit meiner MyLocalSelf ... oder lass die Feldvariablen weg und nimm Arrays, wie weiter unten angerissen ...
Was mir auffiel
CLASS VAR cAlias -> ein cAlias macht nur Ärger, ich mache immer:
use DBF NEW // das NEW ist wichtig
if ! neterr()
::nAlias := select()
...
(::nAlias)-> ... Zahlen sind eindeutig ...
du ließt in DATENBANK die Felder mit Struktur ein und verwendest dann aber je Datei namentliche Feldvariablen, warum nicht ein Array (wie es für z.B. DBCREATE() benutzt wird) anlegen, das enthält dann Name und Art des Feldes ... und in deiner Klasse intern über FieldPut(nFeld), FieldGet(nFeld) und FiledName(..) bzw. Fieldpos() gehen. Fieldinfo kann Blank auch ersetzten. Eventuell sparst du dir sogar die XBTools3 DLLs.
So vermeidest du die Macros, du brauchts kein Blank (dort mußt du doch auch unterscheiden zwischen num und text ... das spart auch Zugriffe auf die Datei. Die Methoden nach außen können natürlich auch Namen empfangen, diese setzt du dann über das Array auf Feldnummern um.
Für das Leeren eines Datensatzes nehme ich z.B.
for x := 1 to fCount()
do case
case fieldinfo(x,FLD_TYPE)="C"
fieldput(x, "")
case fieldinfo(x,FLD_TYPE)="N"
fieldput(x, 0)
...
Du hättest dann ja auch die Struktur schon im ::ArrrayMitStrukur ...
natürlich in deinem Beispiel immer mit dem alias:
(::nAlias)->(fieldput(...))
Wenn ich recht verstanden habe sind die übergebenen object Variablen vom gleichen Typ wie die Klasse in der du das programmierst ?
Das sollte nicht nötig sein, innerhalb der Klasse hat man immer auf die eigenen Instanzvariablen Zugriff.
Wenn man allerdings eine Klasse ableitet und dann dort erneut eine gleichnamige Variable erstellt, dann sperrt diese die andere, dann muß man :
::Masterclasse:MyVar und ::MyVar hier wird bei ::MyVar immer
die in der abgeleiteten Classe benutzt, man muß genau ::Masterclasse:MyVar schreiben wenn man diese will.
auch blockiert ein lokal self .... das eigentliche self ... da muß man aufpassen ...
::MySle:irgendeinevent := {|p1,p2,self| ::Fenstermethode() }
hier knallt es, denn :: ist nicht mehr das self des Fensters, sondern die lokale Variable self aus der Parameterleiste ...
Das hat mich schon Nerven gekostet, weil einige Beispiele dort self statt oXbp verwenden.
Ich hoffe es war was für dich dabei, wenn nicht, auf in die Mülltonne
versuche es mal mit meiner MyLocalSelf ... oder lass die Feldvariablen weg und nimm Arrays, wie weiter unten angerissen ...
Was mir auffiel
CLASS VAR cAlias -> ein cAlias macht nur Ärger, ich mache immer:
use DBF NEW // das NEW ist wichtig
if ! neterr()
::nAlias := select()
...
(::nAlias)-> ... Zahlen sind eindeutig ...
du ließt in DATENBANK die Felder mit Struktur ein und verwendest dann aber je Datei namentliche Feldvariablen, warum nicht ein Array (wie es für z.B. DBCREATE() benutzt wird) anlegen, das enthält dann Name und Art des Feldes ... und in deiner Klasse intern über FieldPut(nFeld), FieldGet(nFeld) und FiledName(..) bzw. Fieldpos() gehen. Fieldinfo kann Blank auch ersetzten. Eventuell sparst du dir sogar die XBTools3 DLLs.
So vermeidest du die Macros, du brauchts kein Blank (dort mußt du doch auch unterscheiden zwischen num und text ... das spart auch Zugriffe auf die Datei. Die Methoden nach außen können natürlich auch Namen empfangen, diese setzt du dann über das Array auf Feldnummern um.
Für das Leeren eines Datensatzes nehme ich z.B.
for x := 1 to fCount()
do case
case fieldinfo(x,FLD_TYPE)="C"
fieldput(x, "")
case fieldinfo(x,FLD_TYPE)="N"
fieldput(x, 0)
...
Du hättest dann ja auch die Struktur schon im ::ArrrayMitStrukur ...
natürlich in deinem Beispiel immer mit dem alias:
(::nAlias)->(fieldput(...))
Wenn ich recht verstanden habe sind die übergebenen object Variablen vom gleichen Typ wie die Klasse in der du das programmierst ?
Das sollte nicht nötig sein, innerhalb der Klasse hat man immer auf die eigenen Instanzvariablen Zugriff.
Wenn man allerdings eine Klasse ableitet und dann dort erneut eine gleichnamige Variable erstellt, dann sperrt diese die andere, dann muß man :
::Masterclasse:MyVar und ::MyVar hier wird bei ::MyVar immer
die in der abgeleiteten Classe benutzt, man muß genau ::Masterclasse:MyVar schreiben wenn man diese will.
auch blockiert ein lokal self .... das eigentliche self ... da muß man aufpassen ...
::MySle:irgendeinevent := {|p1,p2,self| ::Fenstermethode() }
hier knallt es, denn :: ist nicht mehr das self des Fensters, sondern die lokale Variable self aus der Parameterleiste ...
Das hat mich schon Nerven gekostet, weil einige Beispiele dort self statt oXbp verwenden.
Ich hoffe es war was für dich dabei, wenn nicht, auf in die Mülltonne
Gruß
Hubert
Hubert
- Manfred
- Foren-Administrator
- Beiträge: 21191
- Registriert: Di, 29. Nov 2005 16:58
- Wohnort: Kreis Wesel
- Hat sich bedankt: 210 Mal
- Danksagung erhalten: 67 Mal
hat es auch nicht gebracht...Martin Altmann hat geschrieben:Und wenn Du jetzt noch dafür sorgst, dass cField nicht als local sondern als private deklariert wird?
Viele Grüße,
Martin
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
- Manfred
- Foren-Administrator
- Beiträge: 21191
- Registriert: Di, 29. Nov 2005 16:58
- Wohnort: Kreis Wesel
- Hat sich bedankt: 210 Mal
- Danksagung erhalten: 67 Mal
Hi Hubert,
danke erstmal auch Dir für die Mühe (und den anderen natürlich auch)
Wie ich oben geschrieben habe, das Objekt ist richtig. Also daran liegt es nicht.
Blank() übernimmt für mich die ganze Prüfung, welche Art die Variabel hat, also für mich keine Arbeit mehr.
Was Du geschrieben hast, habe ich jetzt auf die Schnelle nicht verstanden.
Ich wollte doch nur wissen, warum das so nicht klappt....
Das es Alternativen gibt ist mir klar....
danke erstmal auch Dir für die Mühe (und den anderen natürlich auch)
Wie ich oben geschrieben habe, das Objekt ist richtig. Also daran liegt es nicht.
Blank() übernimmt für mich die ganze Prüfung, welche Art die Variabel hat, also für mich keine Arbeit mehr.
Was Du geschrieben hast, habe ich jetzt auf die Schnelle nicht verstanden.
Ich wollte doch nur wissen, warum das so nicht klappt....
Das es Alternativen gibt ist mir klar....
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
- brandelh
- Foren-Moderator
- Beiträge: 15696
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 66 Mal
- Danksagung erhalten: 33 Mal
- Kontaktdaten:
Hi Manfred,
geh doch mal hin und definiere in dieser Methode eine lokale Varible :
local MySelf := self
und verwende diese MySelf statt dem :: bzw self: in dem auskommentierten Aufruf. Wenn es mit der Variable object funktioniert müßte es auch mit MySelf funktionieren ...
Macros als solche sind halt schwer zu durchschauen wenn es ans Eingemachte geht.
geh doch mal hin und definiere in dieser Methode eine lokale Varible :
local MySelf := self
und verwende diese MySelf statt dem :: bzw self: in dem auskommentierten Aufruf. Wenn es mit der Variable object funktioniert müßte es auch mit MySelf funktionieren ...
Macros als solche sind halt schwer zu durchschauen wenn es ans Eingemachte geht.
Gruß
Hubert
Hubert
- Manfred
- Foren-Administrator
- Beiträge: 21191
- Registriert: Di, 29. Nov 2005 16:58
- Wohnort: Kreis Wesel
- Hat sich bedankt: 210 Mal
- Danksagung erhalten: 67 Mal
Hi Hubert,
Wenn ich jetzt Deinem Vorschlag folge, dann müßte es ja wieder so sein, wie es ist, wenn es mit dem Objekt direkt angesprochen wird.
Oder liege ich hier falsch?
Das kann ich jetzt nicht so direkt umsetzen. Im ursprünglichen Code wurde ja mit dem übergebenen Objekt direkt garbeitet, also m.E. doppelt, gemoppelt. Das klappt auch. Ich verstehe/verstand bisher nicht, warum es mit :: bzw. self: nicht geht.Hi Manfred,
geh doch mal hin und definiere in dieser Methode eine lokale Varible :
local MySelf := self
und verwende diese MySelf statt dem :: bzw self: in dem auskommentierten Aufruf. Wenn es mit der Variable object funktioniert müßte es auch mit MySelf funktionieren ...
Macros als solche sind halt schwer zu durchschauen wenn es ans Eingemachte geht.
Wenn ich jetzt Deinem Vorschlag folge, dann müßte es ja wieder so sein, wie es ist, wenn es mit dem Objekt direkt angesprochen wird.
Oder liege ich hier falsch?
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
- Manfred
- Foren-Administrator
- Beiträge: 21191
- Registriert: Di, 29. Nov 2005 16:58
- Wohnort: Kreis Wesel
- Hat sich bedankt: 210 Mal
- Danksagung erhalten: 67 Mal
Also,
im Moment kann ich nur ansagen, das im Debugger alle Memvars des self zu sehen sind, aber der Fehler sofort auftaucht, wenn die 1.Membervariable der erbenden Klasse aufgerufen wird in der Schleife, also in dem Fall k_barcode von der Klasse Kunde.
Die müßte doch aber zum kompletten Objekt gehören?
Wenn ich den Wert der Membervar im Debugger abfrage, dann wird er mir auch angezeigt.
Alles recht merkwürdig.
im Moment kann ich nur ansagen, das im Debugger alle Memvars des self zu sehen sind, aber der Fehler sofort auftaucht, wenn die 1.Membervariable der erbenden Klasse aufgerufen wird in der Schleife, also in dem Fall k_barcode von der Klasse Kunde.
Die müßte doch aber zum kompletten Objekt gehören?
Wenn ich den Wert der Membervar im Debugger abfrage, dann wird er mir auch angezeigt.
Alles recht merkwürdig.
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
- Lewi
- 1000 working lines a day
- Beiträge: 830
- Registriert: Di, 07. Feb 2006 14:10
- Wohnort: Hamburg
- Danksagung erhalten: 2 Mal
Genau diese Meldung würde ich jetzt nach dem Studium Deiner Datenbank-Klasse erwarten. Wie bereits in dem Beitrag von brandelh richtig angemerkt wurde, sind in Deiner Datenbankklasse die Felder nicht direkt über eine Memberariable (::FELDNAME ) ansprechbar sondern über object:FELDNAME. Das Problem liegt also nicht am Makro-Operator als solches.Manfred hat geschrieben:Die Fehlermeldung sagt aus, das das Objekt keine Membervariablen mit diesem Namen hat.
Das werde ich jetzt nochmal genau nachsehen. Nicht das da ein falsches angepackt wird mit self....
Und warum "muß" eigentlich das Objekt "object" verschwinden?
- Manfred
- Foren-Administrator
- Beiträge: 21191
- Registriert: Di, 29. Nov 2005 16:58
- Wohnort: Kreis Wesel
- Hat sich bedankt: 210 Mal
- Danksagung erhalten: 67 Mal
Nun, warum muß das Objekt verschwinden.
Ich bin jetzt mal ganz naiv und erkläre das mal so:
In der OOP soll es doch so sein, dass ich eine Klasse habe und davon evtl. andere erben. Also soll es so sein, wenn ich die Methoden und/oder Membervariablen der Superklasse nicht hidden sondern exported setze, alles vererbt wird und sichtbar sein sollte.
Wenn ich jetzt von der erbenden Klasse ein Objekt bilde und damit dann die Methode der Superklasse aufrufe, sollte doch alles zur Verfügung stehe, von oben nach unten usw.
Das scheint aber nicht der Fall zu sein, oder aber ich verstehe hier was falsch. Es müßte doch so sein, dass ich das Objekt überhaupt nicht mitgeben muß. Es ist ja schließlich das, was die Methode aus der eigenen geerbten Superklasse aufruft. (Anders käme es ja auch nicht da dran)
Die ursprüngliche Frage war nur, wo ich wohl einen Denkfehler mache, weil es ohne Übergabe des aufrufenden Objektes nicht geht. Tja, das war dann wohl doch wieder eine problembehaftete Frage, oder aber ein BUG im System.
Ich bin jetzt mal ganz naiv und erkläre das mal so:
In der OOP soll es doch so sein, dass ich eine Klasse habe und davon evtl. andere erben. Also soll es so sein, wenn ich die Methoden und/oder Membervariablen der Superklasse nicht hidden sondern exported setze, alles vererbt wird und sichtbar sein sollte.
Wenn ich jetzt von der erbenden Klasse ein Objekt bilde und damit dann die Methode der Superklasse aufrufe, sollte doch alles zur Verfügung stehe, von oben nach unten usw.
Das scheint aber nicht der Fall zu sein, oder aber ich verstehe hier was falsch. Es müßte doch so sein, dass ich das Objekt überhaupt nicht mitgeben muß. Es ist ja schließlich das, was die Methode aus der eigenen geerbten Superklasse aufruft. (Anders käme es ja auch nicht da dran)
Die ursprüngliche Frage war nur, wo ich wohl einen Denkfehler mache, weil es ohne Übergabe des aufrufenden Objektes nicht geht. Tja, das war dann wohl doch wieder eine problembehaftete Frage, oder aber ein BUG im System.
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
- Lewi
- 1000 working lines a day
- Beiträge: 830
- Registriert: Di, 07. Feb 2006 14:10
- Wohnort: Hamburg
- Danksagung erhalten: 2 Mal
Das kannst Du wie folgt erreichen:Manfred hat geschrieben:Nun, warum muß das Objekt verschwinden.
Das scheint aber nicht der Fall zu sein, oder aber ich verstehe hier was falsch. Es müßte doch so sein, dass ich das Objekt überhaupt nicht mitgeben muß.
Code: Alles auswählen
CLASS DATENBANK
protected:
var oDb
....
ENDCLASS
und dann unter
Method Datenbank:INIT( cDatenbank )
::oDb := OpenDb( cDatenbank )
...
Return ( self )
METHOD datenbank:fieldsEmpty()
LOCAL cWert, cField
LOCAL nI, nOldSelect := SELECT()
DBSELECTAREA( ::oDb:nArea)
FOR nI := 1 TO (ALIAS())->(FCOUNT()) -1
cName := (ALIAS())->(FIELDNAME(nI))
cWert := (ALIAS())->(Fieldget( FieldPos(cField) ))
// oder cWert := (ALIAS() )->(Fieldget(i))
::oDb:Fieldput( n1 ) := BLANK(cWert,.T.)
// bzw. ::oDb:Fieldput( ::oDb:Fieldpos(cField) )
NEXT
DBSELECTAREA(nOldSelect)
RETURN self
- Manfred
- Foren-Administrator
- Beiträge: 21191
- Registriert: Di, 29. Nov 2005 16:58
- Wohnort: Kreis Wesel
- Hat sich bedankt: 210 Mal
- Danksagung erhalten: 67 Mal
Nochmals ich,
so, ich habe mir die Methode nochmal zur Brust genommen und nun folgenden Entschluß gefaßt:
1) Das Objekt bleibt drin, weil ich damit irgendein Objekt nehmen kann, mit/von dem ich die Methode aufrufe, ich muß nur das Objekt übergeben, dessen Membervar ich leeren will. (War auch so geplant, wurde aber bisher noch nicht genutzt, deshalb.)
2) Ich lasse die Methode so, wie sie ist, indem ich das Objekt mit angebe. Muß ja dann auch sein, wenn es ein anderes Objekt ist, was übergeben wurde.
3) Ich finde mich erstmal damit ab, das es anders nicht klappt.
Wenn ich mal wieder viel Zeit und Muße habe, dann werde ich mich damit auseinandersetzen und wenn es dann zu einem Erfolgserlebnis kommt, werde ich euch hier teilhaben lassen daran.
Ansonsten kann ich mich nur nochmal für den Einsatz von eurer Seite bedanken und werde mal wieder im Untergrund verschwinden und zusehen, das mein Projekt voran kommt.
so, ich habe mir die Methode nochmal zur Brust genommen und nun folgenden Entschluß gefaßt:
1) Das Objekt bleibt drin, weil ich damit irgendein Objekt nehmen kann, mit/von dem ich die Methode aufrufe, ich muß nur das Objekt übergeben, dessen Membervar ich leeren will. (War auch so geplant, wurde aber bisher noch nicht genutzt, deshalb.)
2) Ich lasse die Methode so, wie sie ist, indem ich das Objekt mit angebe. Muß ja dann auch sein, wenn es ein anderes Objekt ist, was übergeben wurde.
3) Ich finde mich erstmal damit ab, das es anders nicht klappt.
Wenn ich mal wieder viel Zeit und Muße habe, dann werde ich mich damit auseinandersetzen und wenn es dann zu einem Erfolgserlebnis kommt, werde ich euch hier teilhaben lassen daran.
Ansonsten kann ich mich nur nochmal für den Einsatz von eurer Seite bedanken und werde mal wieder im Untergrund verschwinden und zusehen, das mein Projekt voran kommt.
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
- Manfred
- Foren-Administrator
- Beiträge: 21191
- Registriert: Di, 29. Nov 2005 16:58
- Wohnort: Kreis Wesel
- Hat sich bedankt: 210 Mal
- Danksagung erhalten: 67 Mal
Eins muß ich noch kurz mitteilen:
BLANK(objekt:&(cField),.T.)
leert die Felder nicht, sondern läßt den Inhalt drin.
Ich denke mal es müßte ja das gleiche sein wie
BLANK(self:&(cField),.T.)
klar, weil die Funktion den leeren String zurückgibt und dann eben damit gearbeitet wird.
BLANK(objekt:&(cField),.T.)
leert die Felder nicht, sondern läßt den Inhalt drin.
Ich denke mal es müßte ja das gleiche sein wie
BLANK(self:&(cField),.T.)
klar, weil die Funktion den leeren String zurückgibt und dann eben damit gearbeitet wird.
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
- brandelh
- Foren-Moderator
- Beiträge: 15696
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 66 Mal
- Danksagung erhalten: 33 Mal
- Kontaktdaten:
Doch das ist der Fall !In der OOP soll es doch so sein, dass ich eine Klasse habe und davon evtl. andere erben. Also soll es so sein, wenn ich die Methoden und/oder Membervariablen der Superklasse nicht hidden sondern exported setze, alles vererbt wird und sichtbar sein sollte.
Wenn ich jetzt von der erbenden Klasse ein Objekt bilde und damit dann die Methode der Superklasse aufrufe, sollte doch alles zur Verfügung stehe, von oben nach unten usw.
Das scheint aber nicht der Fall zu sein,
Und wenn man die Grundlagen gelesen und verstanden hat, ist es auch gar nicht so schwer ... im nächsten Posting habe ich ein lauffähiges Beispielprogramm, dass das zeigt.
Code: Alles auswählen
class Hauptclasse
exported
VAR MyNr // diese ist in allen Methoden UND auch in anderem Programmcode aufrufbar !
VAR MeinDoppelgaenger // eigentlich auch überall sichtbar ...
protected
VAR MyClassProtect // diese ist in allen Methoden sichtbar, aber von außen geschützt.
hidden
VAR MyClassLocal // diese ist NUR in dieser Klasse sichtbar, nicht in abgeleiteten !
end class
method Hauptclasse:Init()
::MyNr := 0
::MeinDoppelgaenger := "Ich werde später ausgeschaltet"
::MyClassProtect := "Ich bin in allen Methoden sichtbar, auch abgeleitete"
::MyClassLocal := "Ich bin nur in Hauptclasse verwendbar !"
// keine Fehler hier, alles sichbar !
return self
Code: Alles auswählen
class MyOwnHauptclasse from Hauptclasse
VAR MeinDoppelgaenger // wird hier aber nochmal definiert, also überschrieben !!!!
end class
method MyOwnHauptclasse:IrgendEineMethode() // eigene Instanzvariablen werden NIE per Parameter übergeben !
::MyNr := 2 // natürlich geht das
? ::MyNr // und das
::MeinDoppelgaenger := 2 // die Var der eigenen Klasse wird überschrieben
? ::Hauptclasse:MeinDoppelgaenger // hier kommt nicht die 2 von eben.
::MyClassProtect := "Ich würde gerne" // KEIN Fehler, protected sind
in abgeleiteten Klassen sichtbar
::MyClassLocal := "du auch ?" // [color=red]FEHLER Membervariable zugriff nicht erlaubt ! [/color]
return self
Code: Alles auswählen
function myfunctionXYZ()
...
oObj := MyOwnHauptclasse():new():create()
oObj:MyNr := 1 // das ist OK, da exported
? oObj:MyNr // auch das geht
? oObj:MeinDoppelgaenger // der zeigt den Inhalt NUR von MyOwnHauptclasse()
? oObj:Hauptclasse:MeinDoppelgaenger // das ist der Inhalt der Superklasse Hauptclasse
oObj:MyClassProtect := "Ich würd ja gerne" [color=red]// Fehlermeldung Zugriff nicht erlaubt [/color]
oObj:MyClassLocal := "natürlich auch ein Fehler [color=red]// Fehlermeldung[/color]
1. Ich schreibe nur für mich und habe den Quellcode -> exported ist OK
2. Ich schreibe eine Bibliothek und gebe den Quellcode mit -> möglichst alles mit protected und hidden schützen, was ein Programmierer fälschlicherweise verwenden könnte, aber nur intern (innerhalb der Klasse genutzt werden soll). Exported sollte nur das sein was der Anwender damit anfangen soll. Da er aber den Quellcode hat, geht es auch anders.
3. Ich schreibe eine Methode gebe aber den Quellcode nicht weiter, oder es ist ein großes Project mit vielen Programmierern.
Hier darf nur noch exported sein, was unbedingt sein muss und das muss gut dokumentiert sein, alles andere muß geschützt werden. Auch deshalb, damit ein Variablenname - der zufällig gleich ist - nicht das Verhalten der Bibliothek ändert.
Ich empfehle dringend die Grundlagenkapitel (Grundlagen Programmieren / Grundlagen OOP) im Handbuch zu lesen, bevor man mit OOP anfängt, sonst kommt man auf keinen grünen Zweig.
Zuletzt geändert von brandelh am Do, 16. Mär 2006 23:16, insgesamt 1-mal geändert.
Gruß
Hubert
Hubert
- brandelh
- Foren-Moderator
- Beiträge: 15696
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 66 Mal
- Danksagung erhalten: 33 Mal
- Kontaktdaten:
Macro ist unschuldig - ::&(cFeld) ist erlaubt !
Hallo Manfred,
auch mich läßt es als nicht los, wenn ich ein grundsätzliches Problem sehe ...
Es liegt nicht am ::&(cFeld), das ist genauso erlaubt wie oObj:&(cFeld).
Es liegt auch nicht an Exported oder hidden, denn dann währe die Fehlermeldung eine andere ...
Bist du sicher, dass in dem Moment der Fehlermeldung auch der richtige Feldname in cFeld ist, d.H. dass auch wirklich eine solche Instanzvariable angelegt ist ?
Das kleine Testprogramm demonstriert:
1. Fehlermeldungen von protected und hidden Variablen bei unerlaubtem Zugriff. Hierzu einfach die * vor der Zeile löschen.
2. dass ::&(cFeld) := upper(::&(cFeld)) ein gültiger Ausdruck ist !
Es liegt nicht an dieser Zeile - zumindest nicht an der Syntax !
auch mich läßt es als nicht los, wenn ich ein grundsätzliches Problem sehe ...
Es liegt nicht am ::&(cFeld), das ist genauso erlaubt wie oObj:&(cFeld).
Es liegt auch nicht an Exported oder hidden, denn dann währe die Fehlermeldung eine andere ...
Bist du sicher, dass in dem Moment der Fehlermeldung auch der richtige Feldname in cFeld ist, d.H. dass auch wirklich eine solche Instanzvariable angelegt ist ?
Das kleine Testprogramm demonstriert:
1. Fehlermeldungen von protected und hidden Variablen bei unerlaubtem Zugriff. Hierzu einfach die * vor der Zeile löschen.
2. dass ::&(cFeld) := upper(::&(cFeld)) ein gültiger Ausdruck ist !
Es liegt nicht an dieser Zeile - zumindest nicht an der Syntax !
Code: Alles auswählen
procedure main()
local oObj, cFeld
? "Testprogramm"
oObj := MainClass():new():create()
oObj:MyNum ++ // warum soll das nicht gehen
? "oObj:MyNum: ",oObj:MyNum
? "oObj:MyString: ",oObj:MyString
? "oObj:MyFeld1: ",oObj:MyFeld1
? "oObj:MyFeld2: ",oObj:MyFeld2
// bei der nächsten Zeile knallts !
* ? "oObj:MyProtectedString: ",oObj:MyProtectedString
* ? "oObj:MyHiddenString: ",oObj:MyHiddenString
// Fehlermeldung Zugriff auf Membervariable nicht erlaubt !
cFeld := "MyFeld2"
? "Zugriff ü
Gruß
Hubert
Hubert
- Manfred
- Foren-Administrator
- Beiträge: 21191
- Registriert: Di, 29. Nov 2005 16:58
- Wohnort: Kreis Wesel
- Hat sich bedankt: 210 Mal
- Danksagung erhalten: 67 Mal
Hi Hubert,
ich habe folgendes gemacht:
Zu dem Zeitpunkt, als die Schleife das 1.Mal durchlaufen wurde, war die Membervar :id, die in der Superklasse steht im Leerungszustand durch Blank. Beim nächsten Durchlauf war es die :k_barcode, die in der geerbten Klasse steht, die den Fehler verursacht.
Wenn ich nun im Einzelschrittmodus das Programm abarbeite und mir dann eine Zeile vor dem Fehler das Objekt ansehe, oder aber über das Command Fester self:k_barcode aufrufe, dann wird mir der Wert, der bis dahin noch darin ist angezeigt. Der Objekt Manager zeigt mir komplett alle Membervar aus beiden Klassen an. Also kann man davon ausgehen, dass sie vorhanden sind. Ich habe keine Ahnung, warum die Laufzeitfehlermeldung kommt, es gäbe diese k_barcode nicht in diesem Objekt.
ich habe folgendes gemacht:
Zu dem Zeitpunkt, als die Schleife das 1.Mal durchlaufen wurde, war die Membervar :id, die in der Superklasse steht im Leerungszustand durch Blank. Beim nächsten Durchlauf war es die :k_barcode, die in der geerbten Klasse steht, die den Fehler verursacht.
Wenn ich nun im Einzelschrittmodus das Programm abarbeite und mir dann eine Zeile vor dem Fehler das Objekt ansehe, oder aber über das Command Fester self:k_barcode aufrufe, dann wird mir der Wert, der bis dahin noch darin ist angezeigt. Der Objekt Manager zeigt mir komplett alle Membervar aus beiden Klassen an. Also kann man davon ausgehen, dass sie vorhanden sind. Ich habe keine Ahnung, warum die Laufzeitfehlermeldung kommt, es gäbe diese k_barcode nicht in diesem Objekt.
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
- brandelh
- Foren-Moderator
- Beiträge: 15696
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 66 Mal
- Danksagung erhalten: 33 Mal
- Kontaktdaten:
Hallo Manfred,
schau dir mein Beispiel an, dort funktioniert es !
Das Einzige, was bei deinem anders ist (von der Menge der Variablen mal abgesehen), ist die Verwendung von CLASS vor VAR:
CLASS VAR cVerzeichnis,; // Klassenvariable
statt
VAR cVerzeichnis,; // normale Instanzvariable !
eine CLASS VAR ist keine normale INSTANZ-Variable. Ich kann zwar den Unterschied nicht erklären, da ich ihn selbst nicht richtig verstanden habe, aber normalerweise arbeitet man NICHT mit CLASS VAR sondern nur mit VAR !
Mein Beispiel mit VAR funktioniert, meine Druckerklasse funktioniert, viele Beispiele alle ohne CLASS VAR.
Deshalb - nach Entfernen meines Balkens vor dem Auge - denke ich sagen zu können, 'Schmeiß das CLASS vor dem VAR raus und alles geht'.
Ohne Garantie
schau dir mein Beispiel an, dort funktioniert es !
Das Einzige, was bei deinem anders ist (von der Menge der Variablen mal abgesehen), ist die Verwendung von CLASS vor VAR:
CLASS VAR cVerzeichnis,; // Klassenvariable
statt
VAR cVerzeichnis,; // normale Instanzvariable !
eine CLASS VAR ist keine normale INSTANZ-Variable. Ich kann zwar den Unterschied nicht erklären, da ich ihn selbst nicht richtig verstanden habe, aber normalerweise arbeitet man NICHT mit CLASS VAR sondern nur mit VAR !
Mein Beispiel mit VAR funktioniert, meine Druckerklasse funktioniert, viele Beispiele alle ohne CLASS VAR.
Deshalb - nach Entfernen meines Balkens vor dem Auge - denke ich sagen zu können, 'Schmeiß das CLASS vor dem VAR raus und alles geht'.
Ohne Garantie
Gruß
Hubert
Hubert
- Manfred
- Foren-Administrator
- Beiträge: 21191
- Registriert: Di, 29. Nov 2005 16:58
- Wohnort: Kreis Wesel
- Hat sich bedankt: 210 Mal
- Danksagung erhalten: 67 Mal
Hi Hubert,
im Moment habe ich leider nicht die Zeit es auszuprobieren, weil ich dazu zu viel umändern müßte.
Allerdings, hat die CLASS Var Angabe den Sinn und Zweck, eine Fehlermeldung zu vermeiden, die unweigerlich auftritt, wenn ich die Variable als normale VAR deklariere, aber dann in der CLASS METHOD initClass benutze.
CLASS METHOD initClass habe ich deshalb, damit ich nicht immer zur Instanzbildung extra die init Methode des Objektes aufrufen muß.
Also, es ist schon etwas verworren. (es wurde hier schon in einem Thread besprochen)
Eine Frage hätte ich allerdings noch: Du weißt, dass die CLASS VAR keine Mucken machen, sondern nur die normalen VAR des erzeugten Objektes?
im Moment habe ich leider nicht die Zeit es auszuprobieren, weil ich dazu zu viel umändern müßte.
Allerdings, hat die CLASS Var Angabe den Sinn und Zweck, eine Fehlermeldung zu vermeiden, die unweigerlich auftritt, wenn ich die Variable als normale VAR deklariere, aber dann in der CLASS METHOD initClass benutze.
CLASS METHOD initClass habe ich deshalb, damit ich nicht immer zur Instanzbildung extra die init Methode des Objektes aufrufen muß.
Also, es ist schon etwas verworren. (es wurde hier schon in einem Thread besprochen)
Eine Frage hätte ich allerdings noch: Du weißt, dass die CLASS VAR keine Mucken machen, sondern nur die normalen VAR des erzeugten Objektes?
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
- Manfred
- Foren-Administrator
- Beiträge: 21191
- Registriert: Di, 29. Nov 2005 16:58
- Wohnort: Kreis Wesel
- Hat sich bedankt: 210 Mal
- Danksagung erhalten: 67 Mal
ich werde mal sehen, ob ich in den nächsten Tagen etwas konstruiere, das ich Deinen Vorschlag mal teste. Das will ich jetzt auch noch wissen.
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
- brandelh
- Foren-Moderator
- Beiträge: 15696
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 66 Mal
- Danksagung erhalten: 33 Mal
- Kontaktdaten:
Hallo,
mein Beispiel zeigt, dass es nicht am Macro liegt.
Ich kann nur empfehlen ein einfaches Modell (z.B. die Erweiterung meines Beispieles) zu machen, was entweder das Problem einzukreisen hilft, oder aber funktioniert. In beiden Fällen wäre dir bei der Fehlersuche geholfen.
Manchmal sind Anwendungsprogramme einfach schon zu groß um solche Fehler zu finden.
mein Beispiel zeigt, dass es nicht am Macro liegt.
Ich kann nur empfehlen ein einfaches Modell (z.B. die Erweiterung meines Beispieles) zu machen, was entweder das Problem einzukreisen hilft, oder aber funktioniert. In beiden Fällen wäre dir bei der Fehlersuche geholfen.
Manchmal sind Anwendungsprogramme einfach schon zu groß um solche Fehler zu finden.
Gruß
Hubert
Hubert
- Manfred
- Foren-Administrator
- Beiträge: 21191
- Registriert: Di, 29. Nov 2005 16:58
- Wohnort: Kreis Wesel
- Hat sich bedankt: 210 Mal
- Danksagung erhalten: 67 Mal
Einen habe ich noch....
Also, ich habe nochmals den Ursprungszustand hergestellt, an dem mir der Fehler eigentlich aufgefallen ist. Damals und jetzt gab/gibt es keine CLASS davor.
Auch jetzt taucht der Fehler sofort auf, sobald eine Memvar angesprochen wird, die dem Objekt gehört und nicht der Superklasse.
So, jetzt gehe ich mal eben futtern und dann werde ich die Sache nochmals weiter anschauen.
Also bis gleich...
Also, ich habe nochmals den Ursprungszustand hergestellt, an dem mir der Fehler eigentlich aufgefallen ist. Damals und jetzt gab/gibt es keine CLASS davor.
Auch jetzt taucht der Fehler sofort auf, sobald eine Memvar angesprochen wird, die dem Objekt gehört und nicht der Superklasse.
So, jetzt gehe ich mal eben futtern und dann werde ich die Sache nochmals weiter anschauen.
Also bis gleich...
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!