Name einer Instanzvariablen [erledigt]

Klassen, Objekte, Methoden, Instanzen

Moderator: Moderatoren

Antworten
Dieter
Rekursionen-Architekt
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]

Beitrag von Dieter »

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.
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.
georg
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2823
Registriert: Fr, 08. Feb 2008 21:29
Hat sich bedankt: 95 Mal
Danksagung erhalten: 13 Mal

Re: Name einer Instanzvariablen

Beitrag von georg »

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 ...

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.)
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.

Code: Alles auswählen

oXbp:className()
wird funktionieren.
Liebe Grüsse aus der Eifel,

Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
Dieter
Rekursionen-Architekt
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

Beitrag von Dieter »

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.
Viele Grüße

Dieter

Was man nicht versteht, besitzt man nicht.
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9345
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 100 Mal
Danksagung erhalten: 359 Mal
Kontaktdaten:

Re: Name einer Instanzvariablen

Beitrag von Tom »

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
Dieter
Rekursionen-Architekt
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

Beitrag von Dieter »

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.
Viele Grüße

Dieter

Was man nicht versteht, besitzt man nicht.
georg
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2823
Registriert: Fr, 08. Feb 2008 21:29
Hat sich bedankt: 95 Mal
Danksagung erhalten: 13 Mal

Re: Name einer Instanzvariablen

Beitrag von georg »

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).
Liebe Grüsse aus der Eifel,

Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9345
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 100 Mal
Danksagung erhalten: 359 Mal
Kontaktdaten:

Re: Name einer Instanzvariablen

Beitrag von Tom »

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
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15689
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Name einer Instanzvariablen

Beitrag von brandelh »

eine Instanzvariable kann kein Objekt SEIN, nur eines als Inhalt haben.
Gruß
Hubert
Dieter
Rekursionen-Architekt
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

Beitrag von Dieter »

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

Code: Alles auswählen

oDlg:vorname := DKSleText():new()
oDlg:label2eingabe:addItem(1,oDlg:vorname,"adr->vorname") 
In ::addItem passiert unter anderem folgendes:

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
Eine Speicherklasse sollte vorher an alle Sle- und Mle-Klassen weiter vererbt werden.

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
Vielen Dank für die vielen Hinweise.
Viele Grüße

Dieter

Was man nicht versteht, besitzt man nicht.
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12903
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 44 Mal

Re: Name einer Instanzvariablen

Beitrag von AUGE_OHR »

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
es handelt sich um ein 2-Dim Array !

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
Dieter
Rekursionen-Architekt
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

Beitrag von Dieter »

Hallo Jimmy,

du schreibst:
es handelt sich um ein 2-Dim Array !
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!
Viele Grüße

Dieter

Was man nicht versteht, besitzt man nicht.
Antworten