Das Forentreffen 2018 findet am 20./21. April in Dresden statt. Weitere Infos hier
Anmeldungen zum Forentreffen 2018 sind auf der Anmeldeseite möglich
Zur Homepage des Deutschsprachige Xbase-Entwickler e. V.
Xbase++-Wiki des Deutschsprachige Xbase-Entwickler e. V.

Name einer Instanzvariablen [erledigt]

Klassen, Objekte, Methoden, Instanzen

Moderator: Moderatoren

Antworten
Dieter
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 198
Registriert: Do, 14. Aug 2008 14:59
Wohnort: Straelen

Name einer Instanzvariablen [erledigt]

Beitrag von Dieter » So, 27. Apr 2014 10:54

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: 1951
Registriert: Fr, 08. Feb 2008 21:29

Re: Name einer Instanzvariablen

Beitrag von georg » So, 27. Apr 2014 12:46

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

Dieter
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 198
Registriert: Do, 14. Aug 2008 14:59
Wohnort: Straelen

Re: Name einer Instanzvariablen

Beitrag von Dieter » Mo, 28. Apr 2014 10:27

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: 6828
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Kontaktdaten:

Re: Name einer Instanzvariablen

Beitrag von Tom » Mo, 28. Apr 2014 10:45

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: 198
Registriert: Do, 14. Aug 2008 14:59
Wohnort: Straelen

Re: Name einer Instanzvariablen

Beitrag von Dieter » Mo, 28. Apr 2014 13:09

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: 1951
Registriert: Fr, 08. Feb 2008 21:29

Re: Name einer Instanzvariablen

Beitrag von georg » Mo, 28. Apr 2014 13:15

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

Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 6828
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Kontaktdaten:

Re: Name einer Instanzvariablen

Beitrag von Tom » Mo, 28. Apr 2014 13:18

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: 13811
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Kontaktdaten:

Re: Name einer Instanzvariablen

Beitrag von brandelh » Mo, 28. Apr 2014 16:22

eine Instanzvariable kann kein Objekt SEIN, nur eines als Inhalt haben.
Gruß
Hubert

Dieter
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 198
Registriert: Do, 14. Aug 2008 14:59
Wohnort: Straelen

Re: Name einer Instanzvariablen

Beitrag von Dieter » Mi, 30. Apr 2014 0:51

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: 10654
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg

Re: Name einer Instanzvariablen

Beitrag von AUGE_OHR » Mi, 30. Apr 2014 15:03

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: 198
Registriert: Do, 14. Aug 2008 14:59
Wohnort: Straelen

Re: Name einer Instanzvariablen

Beitrag von Dieter » Mi, 30. Apr 2014 17:58

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