Name einer Instanzvariablen [erledigt]

Klassen, Objekte, Methoden, Instanzen

Moderator: Moderatoren

Name einer Instanzvariablen [erledigt]

Beitragvon 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.
Dieter
Rekursionen-Architekt
Rekursionen-Architekt
 
Beiträge: 198
Registriert: Do, 14. Aug 2008 14:59
Wohnort: Straelen

Re: Name einer Instanzvariablen

Beitragvon 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
georg
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
 
Beiträge: 1823
Registriert: Fr, 08. Feb 2008 22:29

Re: Name einer Instanzvariablen

Beitragvon 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.
Dieter
Rekursionen-Architekt
Rekursionen-Architekt
 
Beiträge: 198
Registriert: Do, 14. Aug 2008 14:59
Wohnort: Straelen

Re: Name einer Instanzvariablen

Beitragvon 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
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
 
Beiträge: 6708
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin

Re: Name einer Instanzvariablen

Beitragvon 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.
Dieter
Rekursionen-Architekt
Rekursionen-Architekt
 
Beiträge: 198
Registriert: Do, 14. Aug 2008 14:59
Wohnort: Straelen

Re: Name einer Instanzvariablen

Beitragvon 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
georg
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
 
Beiträge: 1823
Registriert: Fr, 08. Feb 2008 22:29

Re: Name einer Instanzvariablen

Beitragvon 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
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
 
Beiträge: 6708
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin

Re: Name einer Instanzvariablen

Beitragvon brandelh » Mo, 28. Apr 2014 16:22

eine Instanzvariable kann kein Objekt SEIN, nur eines als Inhalt haben.
Gruß
Hubert
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
 
Beiträge: 13390
Registriert: Mo, 23. Jan 2006 21:54
Wohnort: Germersheim

Re: Name einer Instanzvariablen

Beitragvon 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.
Dieter
Rekursionen-Architekt
Rekursionen-Architekt
 
Beiträge: 198
Registriert: Do, 14. Aug 2008 14:59
Wohnort: Straelen

Re: Name einer Instanzvariablen

Beitragvon 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
Benutzeravatar
AUGE_OHR
Marvin
Marvin
 
Beiträge: 10284
Registriert: Do, 16. Mär 2006 8:55
Wohnort: Hamburg

Re: Name einer Instanzvariablen

Beitragvon 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.
Dieter
Rekursionen-Architekt
Rekursionen-Architekt
 
Beiträge: 198
Registriert: Do, 14. Aug 2008 14:59
Wohnort: Straelen


Zurück zu OOP

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast