Name einer Instanzvariablen [erledigt]
Moderator: Moderatoren
-
- Rekursionen-Architekt
- Beiträge: 237
- Registriert: Do, 14. Aug 2008 14:59
- Wohnort: Straelen
- Hat sich bedankt: 2 Mal
- Danksagung erhalten: 3 Mal
Name einer Instanzvariablen [erledigt]
Hallo,
Wenn ich eine Kasseninstanzvariable in der Form obj := meineKlasse:meineInstanzvariable habe, dann bekomme ich über obj:classname den String "meineKlasse" zurückgeliefert. Gibt es eine Möglichkeit auch den String "meineInstanzvariable" zu erhalten? In xbase habe ich bisher keine zugehörige Methode gefunden.
Wenn ich eine Kasseninstanzvariable in der Form obj := meineKlasse:meineInstanzvariable habe, dann bekomme ich über obj:classname den String "meineKlasse" zurückgeliefert. Gibt es eine Möglichkeit auch den String "meineInstanzvariable" zu erhalten? In xbase habe ich bisher keine zugehörige Methode gefunden.
Zuletzt geändert von Dieter am Mi, 30. Apr 2014 17:59, insgesamt 1-mal geändert.
Viele Grüße
Dieter
Was man nicht versteht, besitzt man nicht.
Dieter
Was man nicht versteht, besitzt man nicht.
-
- Der Entwickler von "Deep Thought"
- Beiträge: 2832
- Registriert: Fr, 08. Feb 2008 21:29
- Hat sich bedankt: 98 Mal
- Danksagung erhalten: 13 Mal
Re: Name einer Instanzvariablen
Hallo, Dieter -
schau doch mal in der Xbase++ Dokumentation unter Klassenreferenz bei Text- und GUI-Klassen die Klasse Abstract() an. :className() ist eine von Abstract() abgeleitete Methode.
Allerdings verstehe ich Deinen Ansatz nicht ...
In meinem Beispiel wird das Programm bei der Zuweisung zu cTest abbrechen, denn obj enthält kein Objekt, sondern einen String, und der hat keine Methode :className().
Du bekommst nur dann keinen Fehler in Deinem Programm, wenn Du :meineInstanzvariable ein Objekt zugewiesen hast, aber dann bekommst Du den Klassennamen dieses Objekts, und nicht den von meineKlasse.
wird funktionieren.
schau doch mal in der Xbase++ Dokumentation unter Klassenreferenz bei Text- und GUI-Klassen die Klasse Abstract() an. :className() ist eine von Abstract() abgeleitete Methode.
Allerdings verstehe ich Deinen Ansatz nicht ...
Code: Alles auswählen
FUNCTION Main()
Local aPos, aSize
Local cTest
Local oXbp, obj
aPos := {10, 10}
aSize := {120, 30}
oXbp := XbpPushButton():new(, , aPos, aSize)
oXbp:caption := "Test"
oXbp:create()
obj := oXbp:caption
cTest := obj:className()
RETURN (.T.)
FUNCTION AppSys()
RETURN (.T.)
Du bekommst nur dann keinen Fehler in Deinem Programm, wenn Du :meineInstanzvariable ein Objekt zugewiesen hast, aber dann bekommst Du den Klassennamen dieses Objekts, und nicht den von meineKlasse.
Code: Alles auswählen
oXbp:className()
Liebe Grüsse aus der Eifel,
Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
-
- Rekursionen-Architekt
- Beiträge: 237
- Registriert: Do, 14. Aug 2008 14:59
- Wohnort: Straelen
- Hat sich bedankt: 2 Mal
- Danksagung erhalten: 3 Mal
Re: Name einer Instanzvariablen
Hallo Georg,
ich gebe dir Recht, dass bei einer Instanzvariable :caption, die nur eine String enthalten kann, es nicht sehr spannend ist, den String "caption" zu erhalten. Spannend wird es meiner Meinung nach, wenn die Instanzvariable selbst ein Objekt ist und der Name des Objektes in einer Klassenmethode weiter benötigt wird. Alle XbpParts werden in der Childlist ihres Parents mit dem Klassennamen und der Position in dem Childlist-Array referenziert.
Beispiel : {SleText, SleText, SleNum, SleText}
Bei Verwendung von Classcode repräsentiert das 1. Element dieser Childlist die Instanzvariable meineKlasse:sle1 und das 2. Element die Instanzvariable meineKlasse:sle2.
Ich suche also eine Methode oder Funktion, die "sle2" zurückliefert, wenn ich die Instanzvariable Z. B. über childlist[2] oder in der Form obj:=oxbp:Sle2 übergebe.
ich gebe dir Recht, dass bei einer Instanzvariable :caption, die nur eine String enthalten kann, es nicht sehr spannend ist, den String "caption" zu erhalten. Spannend wird es meiner Meinung nach, wenn die Instanzvariable selbst ein Objekt ist und der Name des Objektes in einer Klassenmethode weiter benötigt wird. Alle XbpParts werden in der Childlist ihres Parents mit dem Klassennamen und der Position in dem Childlist-Array referenziert.
Beispiel : {SleText, SleText, SleNum, SleText}
Bei Verwendung von Classcode repräsentiert das 1. Element dieser Childlist die Instanzvariable meineKlasse:sle1 und das 2. Element die Instanzvariable meineKlasse:sle2.
Ich suche also eine Methode oder Funktion, die "sle2" zurückliefert, wenn ich die Instanzvariable Z. B. über childlist[2] oder in der Form obj:=oxbp:Sle2 übergebe.
Viele Grüße
Dieter
Was man nicht versteht, besitzt man nicht.
Dieter
Was man nicht versteht, besitzt man nicht.
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9394
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 104 Mal
- Danksagung erhalten: 364 Mal
- Kontaktdaten:
Re: Name einer Instanzvariablen
o:ClassDescribe() liefert ein Array mit allen gewünschten Informationen zurück. Wie bei "Symbolinfo" kann man das im Bedarfsfall eingrenzen. Definitionen hierfür in CLASS.CH.
Herzlich,
Tom
Tom
-
- Rekursionen-Architekt
- Beiträge: 237
- Registriert: Do, 14. Aug 2008 14:59
- Wohnort: Straelen
- Hat sich bedankt: 2 Mal
- Danksagung erhalten: 3 Mal
Re: Name einer Instanzvariablen
Hallo Tom,
ich habe mir :classdescribe() nochmals angesehen und sehe aber keine Möglichkeit , wie man hier eine Methode schreiben könnte, die bei Objektübergabe den Instanzvariablennamen liefert.
Ich kann lediglich die Position meiner Instanzvariablen im Rückgabe-Array von classDescribe() ermitteln.
ASCAN(odlg:classdescribe(3) , {|a| a[1]=="sle1eingabe"}) liefert z.B. 97
ASCAN(odlg:classdescribe(3) , {|a| a[1]=="sle2eingabe"}) liefert z.B. 123
Dass ich Instanzvariablen ::sle1eingabe oder ::sle2eingabe in meiner Klasse habe, das weiß ich natürlich immer.
Was ich suche sollte wie folgt funktionieren:
METHOD meineKlasse:getVarname(obj)
...
...
RETURN cVarname
Leider sind da nur die Pünktchen ... und keine Lösung in Sicht.
Ich möchte in Zukunft die sle-Instanzvariablen und die Datenbankfelder gleich benennen und die zugehörigen Speicher-, Plausi- und Undo-Methoden vereinheitlichen.
ich habe mir :classdescribe() nochmals angesehen und sehe aber keine Möglichkeit , wie man hier eine Methode schreiben könnte, die bei Objektübergabe den Instanzvariablennamen liefert.
Ich kann lediglich die Position meiner Instanzvariablen im Rückgabe-Array von classDescribe() ermitteln.
ASCAN(odlg:classdescribe(3) , {|a| a[1]=="sle1eingabe"}) liefert z.B. 97
ASCAN(odlg:classdescribe(3) , {|a| a[1]=="sle2eingabe"}) liefert z.B. 123
Dass ich Instanzvariablen ::sle1eingabe oder ::sle2eingabe in meiner Klasse habe, das weiß ich natürlich immer.
Was ich suche sollte wie folgt funktionieren:
METHOD meineKlasse:getVarname(obj)
...
...
RETURN cVarname
Leider sind da nur die Pünktchen ... und keine Lösung in Sicht.
Ich möchte in Zukunft die sle-Instanzvariablen und die Datenbankfelder gleich benennen und die zugehörigen Speicher-, Plausi- und Undo-Methoden vereinheitlichen.
Viele Grüße
Dieter
Was man nicht versteht, besitzt man nicht.
Dieter
Was man nicht versteht, besitzt man nicht.
-
- Der Entwickler von "Deep Thought"
- Beiträge: 2832
- Registriert: Fr, 08. Feb 2008 21:29
- Hat sich bedankt: 98 Mal
- Danksagung erhalten: 13 Mal
Re: Name einer Instanzvariablen
Hallo, Dieter -
Du kannst den Namen einer Instanzvariablen nicht aus der Variablen selbst ableiten.
Wenn die Instanzvariable ein Objekt enthält, dann kannst Du den Klassennamen des Objektes ermitteln, da es sich um ein Objekt handelt. Eine Instanzvariable an sich ist aber kein Objekt (da kannst Du mit :className() ran), sondern eine Variable.
Du kannst (theoretisch) mittels :classDescribe() die Namen der Instanzvariablen laden und diese in einem Loop auslesen und mit dem Inhalt der Instanzvariablen vergleichen. Wenn oObj und Inhalt übereinstimmen, besteht, die Möglichkeit, dass Du den gewünschten Namen gefunden hast (sofern nicht eine andere Instanzvariable den gleichen Inhalt hat).
Du kannst den Namen einer Instanzvariablen nicht aus der Variablen selbst ableiten.
Wenn die Instanzvariable ein Objekt enthält, dann kannst Du den Klassennamen des Objektes ermitteln, da es sich um ein Objekt handelt. Eine Instanzvariable an sich ist aber kein Objekt (da kannst Du mit :className() ran), sondern eine Variable.
Du kannst (theoretisch) mittels :classDescribe() die Namen der Instanzvariablen laden und diese in einem Loop auslesen und mit dem Inhalt der Instanzvariablen vergleichen. Wenn oObj und Inhalt übereinstimmen, besteht, die Möglichkeit, dass Du den gewünschten Namen gefunden hast (sofern nicht eine andere Instanzvariable den gleichen Inhalt hat).
Liebe Grüsse aus der Eifel,
Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9394
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 104 Mal
- Danksagung erhalten: 364 Mal
- Kontaktdaten:
Re: Name einer Instanzvariablen
Ich verstehe, um ehrlich zu sein, nicht ganz, worauf Du hinauswillst. Aber vielleicht wäre Dir mit einer zusätzlichen Instanzvariablen (Array?) geholfen, die die konkreten Namen aller fraglichen Instanzvariablen enthält?
Herzlich,
Tom
Tom
- brandelh
- Foren-Moderator
- Beiträge: 15707
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 71 Mal
- Danksagung erhalten: 38 Mal
- Kontaktdaten:
Re: Name einer Instanzvariablen
eine Instanzvariable kann kein Objekt SEIN, nur eines als Inhalt haben.
Gruß
Hubert
Hubert
-
- Rekursionen-Architekt
- Beiträge: 237
- Registriert: Do, 14. Aug 2008 14:59
- Wohnort: Straelen
- Hat sich bedankt: 2 Mal
- Danksagung erhalten: 3 Mal
Re: Name einer Instanzvariablen
Hallo,
ich sehe dank eurer berechtigten Hinweise mittlerweile ein, dass ich um eine zusätzliche Instanzvariable :fieldname nicht herum komme.
Dass man zweimal einen fast identischen Variablennamen in eine Codezeile schreiben muß, hat mich etwas übermütig werden lassen.
Folgender Code erzeugt ein neues Control unter Einbeziehung der Instanzvariable ::vorname und der Field-Variablen adr->vorname
In ::addItem passiert unter anderem folgendes:
Eine Speicherklasse sollte vorher an alle Sle- und Mle-Klassen weiter vererbt werden.
Vielen Dank für die vielen Hinweise.
ich sehe dank eurer berechtigten Hinweise mittlerweile ein, dass ich um eine zusätzliche Instanzvariable :fieldname nicht herum komme.
Dass man zweimal einen fast identischen Variablennamen in eine Codezeile schreiben muß, hat mich etwas übermütig werden lassen.
Folgender Code erzeugt ein neues Control unter Einbeziehung der Instanzvariable ::vorname und der Field-Variablen adr->vorname
Code: Alles auswählen
oDlg:vorname := DKSleText():new()
oDlg:label2eingabe:addItem(1,oDlg:vorname,"adr->vorname")
Code: Alles auswählen
IF !EMPTY(cFieldname)
oXbp:fieldname := cFieldname
oXbp:killinputFocus := {|| oXbp:speichern(cFieldname,LSHARED)}
ENDIF
IF oXbp:isderivedFrom("XBPSLE") .OR. oXbp:isderivedFrom("XBPMLE")
AADD(self:setParent():editControls, oXbp)
ENDIF
Code: Alles auswählen
CLASS speichern
EXPORTED:
VAR fieldname
METHOD speichern
ENDCLASS
METHOD speichern:speichern(cAliasFeld,lShared)
LOCAL cAliasAlt, nPos, i, lFlagData, lFlag:= FALSE
LOCAL cAlias, cFeld, oXbp:=self
IF !oXbp:changed .OR. EMPTY(cAliasFeld)
RETURN
ENDIF
DEFAULT lshared TO LSHARED
lFlagData := IF(ASCAN(symbolInfo(SYMBOL_CLASSFUNC),"DATA")>0,.t.,.f.) // wenn die Methode :DATA() im Klassencode enthalten
//cAliasFeld := self:fieldname //hier nicht
i:=AT("->",cAliasFeld)
cAlias := SUBSTR(cAliasFeld,1,i-1)
cFeld := SUBSTR(cAliasFeld,i+2)
cAliasAlt:= ALIAS()
DBSelectArea(cAlias)
nPos := FieldPos(cFeld)
IF lShared
FOR i := 1 TO 50
IF RLOCK()
lFlag := TRUE
LOOP
ENDIF
SLEEP(10)
NEXT
IF !lFlag
MsgBox("Speichern in "+cALIAS+" zur Zeit nicht möglich !","Achtung" )
RETURN
ENDIF
ENDIF
IF lFlagData
FieldPut(nPos,self:Data())
ELSE
FieldPut(nPos,self:getData())
ENDIF
IF lShared
UNLOCK
ENDIF
RETURN
Viele Grüße
Dieter
Was man nicht versteht, besitzt man nicht.
Dieter
Was man nicht versteht, besitzt man nicht.
- AUGE_OHR
- Marvin
- Beiträge: 12913
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 46 Mal
Re: Name einer Instanzvariablen
es handelt sich um ein 2-Dim Array !Dieter hat geschrieben:Ich kann lediglich die Position meiner Instanzvariablen im Rückgabe-Array von classDescribe() ermitteln.
ASCAN(odlg:classdescribe(3) , {|a| a[1]=="sle1eingabe"}) liefert z.B. 97
ASCAN(odlg:classdescribe(3) , {|a| a[1]=="sle2eingabe"}) liefert z.B. 123
Code: Alles auswählen
#include "Class.ch"
#pragma Library( "XppUi2.lib" )
#define CRLF CHR(13)+CHR(10)
PROCEDURE Main
LOCAL oXbp
LOCAL oBrowse
oXbp := XbpDialog():new( AppDesktop(),, {10,10}, {200,200} )
oXbp:create()
oBrowse := MyBrowse():new( oXbp:DrawingArea):create()
SET ALTERNATE TO Dialog.txt
SET ALTERNATE ON
oBrowse:ShowClass()
RETURN
CLASS MyBrowse FROM XbpBrowse
EXPORTED:
INLINE METHOD ShowClass()
InsObject2(::XbpBrowse)
RETURN NIL
ENDCLASS
PROCEDURE InsObject2(oObj)
LOCAL aItem
LOCAL i,iMax
LOCAL j,jMax
LOCAL cName
LOCAL cAttr
LOCAL bSaveError, oError
bSaveError := ErrorBlock()
?"***************************************************************************"
? oObj:className()+CRLF+CRLF
?"***************************************************************************"
aItem := oObj:classDescribe(,CLASS_HIDDEN)
iMax := LEN(aItem)
FOR i := 1 TO iMax
jMax := LEN(aItem[i])
DO CASE
CASE i = CLASS_DESCR_CLASSNAME
? "CLASS_DESCR_CLASSNAME"
? Var2Char(aItem[i])+CRLF
CASE i = CLASS_DESCR_SUPERCLASSES
? "CLASS_DESCR_SUPERCLASSES"
FOR j := 1 TO jMax
? Var2Char(aItem[i][j])
NEXT
? CRLF
CASE i = CLASS_DESCR_MEMBERS
? "CLASS_DESCR_MEMBERS"
ASort( aItem[i] ,,,{|x,y| Upper( x[CLASS_MEMBER_NAME] ) < ;
Upper( y[CLASS_MEMBER_NAME] ) } )
FOR j := 1 TO jMax
DO CASE
CASE aItem[i][j][CLASS_MEMBER_ATTR] == VAR_ASSIGN_HIDDEN
cAttr := "H"
CASE aItem[i][j][CLASS_MEMBER_ATTR] == VAR_ASSIGN_PROTECTED
cAttr := "P"
CASE aItem[i][j][CLASS_MEMBER_ATTR] == VAR_ASSIGN_EXPORTED
cAttr := "X"
OTHERWISE
cAttr := Var2Char(aItem[i][j][CLASS_MEMBER_ATTR])
ENDCASE
cName := Var2Char(aItem[i][j][CLASS_MEMBER_NAME])
? cAttr,cName
ErrorBlock( {|e| Break(e)} )
BEGIN SEQUENCE // Index-Daten holen
?? " "
?? oObj:&(cName)
RECOVER USING oError
ErrorBlock( bSaveError )
?? " ***"
END SEQUENCE
ErrorBlock( bSaveError ) // Alten Fehler-Codeblock
NEXT
? CRLF
CASE i = CLASS_DESCR_METHODS
? "CLASS_DESCR_METHODS"
ASort( aItem[i] ,,,{|x,y| Upper( x[CLASS_METHOD_NAME] ) < ;
Upper( y[CLASS_METHOD_NAME] ) } )
FOR j := 1 TO jMax
DO CASE
CASE aItem[i][j][CLASS_METHOD_ATTR] == VAR_ASSIGN_HIDDEN
cAttr := "H"
CASE aItem[i][j][CLASS_METHOD_ATTR] == VAR_ASSIGN_PROTECTED
cAttr := "P"
CASE aItem[i][j][CLASS_METHOD_ATTR] == VAR_ASSIGN_EXPORTED
cAttr := "X"
OTHERWISE
cAttr := Var2Char(aItem[i][j][CLASS_METHOD_ATTR] )
ENDCASE
cName := Var2Char(aItem[i][j][CLASS_METHOD_NAME] )
? cAttr,cName
NEXT
? CRLF
ENDCASE
NEXT
RETURN
*
*eof
*
gruss by OHR
Jimmy
Jimmy
-
- Rekursionen-Architekt
- Beiträge: 237
- Registriert: Do, 14. Aug 2008 14:59
- Wohnort: Straelen
- Hat sich bedankt: 2 Mal
- Danksagung erhalten: 3 Mal
Re: Name einer Instanzvariablen
Hallo Jimmy,
du schreibst:
du schreibst:
Das ist mir schon klar. Hilft aber überhaupt nicht, da in der Instanzvariable nur ein Zeiger auf ein Objekt gespeichert wird, welches somit nicht weiß, das es eine Instanzvariable gibt, die den Zeiger auf sich selbst enthält. Der Name der Instanzvariablen ist somit aus dem Objekt nicht ableitbar. Ich bitte deshalb meine blödsinnige Fragestellung in meinem Posting zu entschuldigen!es handelt sich um ein 2-Dim Array !
Viele Grüße
Dieter
Was man nicht versteht, besitzt man nicht.
Dieter
Was man nicht versteht, besitzt man nicht.