Autor Thema: Kann sich eine Klasseinstanz selbst zerstören?  (Gelesen 4320 mal)

Offline khing

  • Aktives Mitglied
  • ***
  • Beiträge: 110
  • Geschlecht: Männlich
Kann sich eine Klasseinstanz selbst zerstören?
« am: 25.11.14 - 12:32:40 »
Hallo,

im Moment stehe ich vor folgender Problematik. Ich erstelle eine neue Instanz meiner Klasse mit einem String als Parameter. Mit diesem String (UNID) hole ich mir ein Dokument, wo weitere Informationen drin stehen. Versehentlich habe ich nun die NoteID und nicht die UNID übergeben und bin in eine Endlosschleife rein gelaufen.  :-\ Komischerweise wirft Getdocumentbyunid gleich einen richtigen Error, sodass mein ErrorHandler anspringt....
So weit ist alles noch OK, weil auch das Delete der Instanz ausgeführt wird aber danach noch lange nicht das Objekt zerstört ist. Danach folgt der Aufruf einer Funktion dieser Instanz und nun hagelt es nur noch Fehler.  ::)

Sicherlich kann ich nun in den öffentlichen Funktionen Schutzmechanismen einbauen aber geht das nicht einfacher, dass ich z. B. diese Instanz einfach sich selbst zerstören lasse? Habt ihr da Lösungsansätze?

Gruß Kristian
"Notes kann alles außer Kaffee kochen!"

Offline pram

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 1.169
  • Geschlecht: Männlich
    • Foconis Object Framework
Re: Kann sich eine Klasseinstanz selbst zerstören?
« Antwort #1 am: 25.11.14 - 12:48:24 »
Ein "delete me" funktioniert soweit ich weiß nicht, was aber geht ist
Code
dim this
set this = me
delete this
Danach ist die Klasse "zerstört" und es hagelt dann halt andere Fehler.

Meiner Meinung nach ist das aber auch keine optimale Lösung, ich denke dass dein ErrorHandler nicht korrekt ist. Wenn die Klasse nicht richtig initialisiert werden konnte, dann darf halt nicht weiter gemacht werden.

LG Roland
Roland Praml

IBM Certified Application Developer - Lotus Notes and Domino 8
Ich verwende das Foconis Object Framework

Offline khing

  • Aktives Mitglied
  • ***
  • Beiträge: 110
  • Geschlecht: Männlich
Re: Kann sich eine Klasseinstanz selbst zerstören?
« Antwort #2 am: 25.11.14 - 15:07:52 »
Hallo Roland,

perfekt! Das ist es, was ich gesucht habe. "Delete Me" hatte ich auch schon probiert und das ging nicht.
Mein Problem ist anscheinend, dass ich noch in Sub New bin und dort mein Errorhandler nicht aussteigt.

Gruß Kristian
"Notes kann alles außer Kaffee kochen!"

Offline Tode

  • Moderatoren
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 6.870
  • Geschlecht: Männlich
  • Geht nicht, gibt's (fast) nicht... *g*
Re: Kann sich eine Klasseinstanz selbst zerstören?
« Antwort #3 am: 25.11.14 - 15:15:06 »
Dann solltest Du aber dringend Deinen ErrorHandler überarbeiten. Ein sauberer ErrorHandler gibt an die übergeordnete Funktion zurück: "He, da ist ein Fehler passiert"... Egal wie er das tut, aber danach weiss die "Calling Sub", dass sie nicht weitermachen muss, oder eben Ihrerseits den aufgetretenen Fehler handeln... oder eben auch wieder nach oben durchreichen...

Gruss
Torsten (Tode)

P.S.: Da mein Nickname immer mal wieder für Verwirrung sorgt: Tode hat NICHTS mit Tod zu tun. So klingt es einfach, wenn ein 2- Jähriger versucht "Torsten" zu sagen... das klingt dann so: "Tooode" (langes O, das r, s und n werden verschluckt, das t wird zum badischen d)

Offline khing

  • Aktives Mitglied
  • ***
  • Beiträge: 110
  • Geschlecht: Männlich
Re: Kann sich eine Klasseinstanz selbst zerstören?
« Antwort #4 am: 25.11.14 - 15:41:05 »
Ja, da liegt anscheinend mein Problem. Ich hatte schon die ganze Zeit so meine Vermutung, dass der nicht richtig arbeitet.

Ich habe eine eigene ErrorHandler-Klasse, die an die aktuellen Klasse "MailMonitor" vererbt wird. In der Klasse MailMonitor habe ich die Sub "logError" der ErrorHandler-Klasse überschrieben (damit ich ein Errorlogging im MailMonitor noch schreiben kann) und erst zum Ende rufe ich "Call Basis..logError(Errorstring)" auf.

Also vereinfacht so:
Code
Public Class ErrorHandler
...
   Public Sub logError(Errorstring)
       'Verarbeitet hier grundlegende Fehler
   End Sub
...
End Class

Public Class Basis As ErrorHandler
...
End Class

Public Class MailMonitor As Basis

   Private Sub logError(ErrorString)
      'Schreibe Infos für MailMonitor weg
      ...
      'Aufruf der Sub aus Mutterklasse
      Call Basis..logError(Errorstring)
   End Sub

End Class

Kann das daran liegen? Es geht auch Call Errorhandler..logError(Errorstring) und da bin ich mir nicht sicher  :-\
"Notes kann alles außer Kaffee kochen!"

Offline koehlerbv

  • Moderator
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 20.460
  • Geschlecht: Männlich
Re: Kann sich eine Klasseinstanz selbst zerstören?
« Antwort #5 am: 25.11.14 - 15:43:32 »
... oder eben auch wieder nach oben durchreichen...
UND merken, wann das Ende der Fahnenstange erreicht ist  ;D

@Kristian: Der Kern ist aber gerade das "verarbeitet hier ..." - was passiert da? Wie erfährt wer von ausserhalb, ob und was da schlimmes passiert ist?

Bernhard

Offline khing

  • Aktives Mitglied
  • ***
  • Beiträge: 110
  • Geschlecht: Männlich
Re: Kann sich eine Klasseinstanz selbst zerstören?
« Antwort #6 am: 25.11.14 - 15:55:01 »
Sorry, das habe ich natürlich vergessen Bernhard. Sonst funktioniert diese Klasse/Sub ganz normal - also stopt die aktuellen Ausführungen.

Code
Public Sub logError(ErrorString)
On Error GoTo errHandler
Dim i As Integer
Dim max As Integer
		Dim vCurrChar As String*1		
		max = Len(Me.vLogToMedium)
		
		Call Me.InitErrorFullOutput()
		
		For i=0 To max-1
			vCurrChar = Mid(Me.LogToMedium, i+1 ,1)
			Select Case (vCurrChar)
			Case CStr(ErrorHandler_LogTo_CentralLogDB): 	LogTo_CentralLogDB(ErrorString)
			Case CStr(ErrorHandler_LogTo_DialogFull): 		logToDialogFull(ErrorString)
			Case CStr(ErrorHandler_LogTo_DialogSimple): 	logToDialogSimple(Errorstring)
			Case CStr(ErrorHandler_LogTo_StatusBar): 		logToStatusBar(Errorstring)
			Case Else: Print "lsCl_Global:logError VLogToMedium Type noch nicht definiert"
		End Select
		Next
		
Ende:
	Exit Sub
errHandler:
	Me.logToDialogSimple("Library: lsCL_Global -- Sub: logError -- Returntype:  -- Sub/Function: " & CrLF & vInitErrorFullOutput)
	Resume Ende
End Sub

In LogTo_CentralLogDB(ErrorString) wird der Fehler einfach an eine Funktion weitergegeben, die die Fehler in eine zentrale Db schriebt (das passiert auch im o. g. Fall). logToDialogSimple(Errorstring)gibt zum Beispiel nur eine MessageBox aus. Wie gesagt, funtkioniert das im Normalfall aber nur nicht, wenn ich die Sub logError überschreibe....
"Notes kann alles außer Kaffee kochen!"

Offline Tode

  • Moderatoren
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 6.870
  • Geschlecht: Männlich
  • Geht nicht, gibt's (fast) nicht... *g*
Re: Kann sich eine Klasseinstanz selbst zerstören?
« Antwort #7 am: 25.11.14 - 16:02:24 »
Du machst aber ein "Resume"... und damit ist der Error "gegessen" und die aufrufende Funktion / Sub bekommt nie mit, dass da ein Fehler passiert ist...
Gruss
Torsten (Tode)

P.S.: Da mein Nickname immer mal wieder für Verwirrung sorgt: Tode hat NICHTS mit Tod zu tun. So klingt es einfach, wenn ein 2- Jähriger versucht "Torsten" zu sagen... das klingt dann so: "Tooode" (langes O, das r, s und n werden verschluckt, das t wird zum badischen d)

Offline khing

  • Aktives Mitglied
  • ***
  • Beiträge: 110
  • Geschlecht: Männlich
Re: Kann sich eine Klasseinstanz selbst zerstören?
« Antwort #8 am: 25.11.14 - 16:07:28 »
 ???
Aber doch ein "Resume Ende" und da geht es zum Exit Sub
Ich bin verwirrt, wie sollte das sonst gehen?
"Notes kann alles außer Kaffee kochen!"

Offline flaite

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 2.966
    • mein del.icio.us
Re: Kann sich eine Klasseinstanz selbst zerstören?
« Antwort #9 am: 25.11.14 - 16:46:54 »
Du verstößt gegen gleich einige grundlegende OO Designprinzipien.
Z.B. http://de.wikipedia.org/wiki/Komposition_an_Stelle_von_Vererbung

Die Idee eine komplexe Vererbungshierarchie zu bauen, in der jede Klasse auch irgendwie ein Errorhandler und eine nicht näher spezifizierte "Basis" liegt zwar erstmal nahe, ist aber immer eine schlechte Idee.

Versuch das erstmal ein wenig zu vereinfachen und schau dann, wo der Fehler liegt.

Ich vermute ohne jede Ironie, dass dieser Fehler sehr interessant ist, bin aber als LotusScript Programmierer nicht mehr fit genug, um zu sagen, was da passiert.

Warum garbage-collectest Du das Objekt selber (dieses delete this), wenn die LotusScript Umgebung selbst einen garbage collector bereitstellt  ???
Wenn Du im Ablauf des codes auf ein garbage-collectete Dokument zugreifst, kann nur Unsinn herauskommen. Der Bezeichner der Instanz zeigt dann auf eine Referenz im Speicher, die eigentlich nicht mehr vorhanden ist.





Ich stimm nicht mit allen überein, aber mit vielen und sowieso unterhaltsam -> https://www.youtube.com/channel/UCr9qCdqXLm2SU0BIs6d_68Q

---

Aquí no se respeta ni la ley de la selva.
(Hier respektiert man nicht einmal das Gesetz des Dschungels)

Nicanor Parra, San Fabian, Región del Bio Bio, República de Chile

Offline flaite

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 2.966
    • mein del.icio.us
Re: Kann sich eine Klasseinstanz selbst zerstören?
« Antwort #10 am: 26.11.14 - 07:39:44 »
Du machst aber ein "Resume"... und damit ist der Error "gegessen" und die aufrufende Funktion / Sub bekommt nie mit, dass da ein Fehler passiert ist...
Richtig. Mach Dir einfach in Base.logError(...) einen Breakpoint hinter dem Aufruf von ErrorHandler.logError(...)

Ausserdem sollte ein Konstruktor dafür da sein, eine Instanz in einen gerade brauchbaren Zustand zu bringen.
Faustregel: Möglichst wenig Code in Konstruktor.

Errorhandling wird nicht dadurch besser, dass Du es über 3 Methoden verteilst, die sich dann gegenseitig aufrufen. Das sieht zwar erstmal nett aus, verkompliziert aber in der realen Welt den code.
Eine Methode sollte nie gleichzeitig eine Exception loggen UND sie an eine weitere Methode weiterleiten. Immer eins von beiden.

Wenn Du genau darüber nachdenkst, kann so ein code eigentlich nur auf 2 Arten auf einen Error reagieren:
1. Der Anwendungsentwickler kann einen Weg finden, um den Ablauf trotzdem weiterzuführen.
2. Man gibt unterschiedliche Nachrichten an die Administratoren (loggen) und an den Anwender (Messagebox: Something went wrong).

Fall 2 ist wesentlich häufiger. Die Entwickler der Sprache Java führten sogenannte Checked Exceptions ein, die Anwendungsentwickler dazu bringen sollten, Punkt 1. Lösungen zu finden. Das ist aber meistens gar nicht möglich. Die Entwickler der Sprache führten checked Exceptions an Stellen ein, an denen sie völlig fehl am Platz sind.
Vereinfachtes Beispiel: Z.B. gibt es eine Checked Exceptions bei FileHandle.close(...) [heisst in der Klassenbibliothek nicht Filehandle, aber das ist vielleicht verständlicher]. Aber wie soll der Programmierer reagieren, wenn der code, den FileHandle nicht schliessen kann? Höchstens vielleicht noch 10 mal versuchen, aber das hilft in aller Regel auch nicht.
Brian Götz, einer der Mitentwickler der Sprache, sagt heute, dass die damals eigentlich nicht wussten, was sie taten.

Mehr code für Error-Handling heisst nicht unbedingt besseres Error-Handling. Das Gegenteil ist viel häufiger der Fall.
Ich stimm nicht mit allen überein, aber mit vielen und sowieso unterhaltsam -> https://www.youtube.com/channel/UCr9qCdqXLm2SU0BIs6d_68Q

---

Aquí no se respeta ni la ley de la selva.
(Hier respektiert man nicht einmal das Gesetz des Dschungels)

Nicanor Parra, San Fabian, Región del Bio Bio, República de Chile

Offline flaite

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 2.966
    • mein del.icio.us
Re: Kann sich eine Klasseinstanz selbst zerstören?
« Antwort #11 am: 26.11.14 - 08:26:04 »
Refactoring im Flaite Stil:

Du erzeugst eine Hierarchie für deine ErrorLogger

Code
Public Class SimpleErrorHandler
...
   Public Sub logError(Errorstring)
       Print "lsCl_Global:logError VLogToMedium Type noch nicht definiert"
   End Sub
...
End Class

Public Class SimpleErrorHandler

   Public Sub logError(Errorstring)
       Print "lsCl_Global:logError VLogToMedium Type noch nicht definiert"
   End Sub
End Class

Class DialogFullErrorHandler as SimpleError
  Public Sub logError(Errorstring)
       ' Code in logToDialogFull(ErrorString) hier rein copy&pasten
   End Sub

End Class
analog mit Log to central db, etc. verfahren.

Den verwendeten Errorhandler initialisierst Du im Konstruktor von MailMonitor
Code
Class MailMonitor
 Dim errorHandler as SimpleErrorHandler ' favour composition over inheritance (try google)
 Dim unid as String

   Public Sub New(vErrorHandler As ErrorHandler, String vUnid)
      errorHandler = vErrorHandler
      unid = vUnid  ' reicht aus als "reasonable minimal initial state"
   end sub     

   Public Sub doStuff() 
      onError goto ErrorHandler
      Dim doc as Document
      doc = db.getDocumentByUnid(unid)
      
      exit sub
      ErrorHandler: 
      me.errorHandler("Fehler in Methode doStuff von Klasse"....  
   end doStuff


So die Richtung. Dein ErrorHandler wäre in einer spezialisierten Klasse, die per Komposition in deinen sonstigen Code eingefügt wird. Sehr vermutlich machst Du das besser mit einfachen Subroutinen und verzichtest auf Klassen.

Wie gesagt: Möglicherweise überschätzt Du die Macht von OO und nutzt sie so, dass Du dir selbst in den Fuß schiesst.
Ich stimm nicht mit allen überein, aber mit vielen und sowieso unterhaltsam -> https://www.youtube.com/channel/UCr9qCdqXLm2SU0BIs6d_68Q

---

Aquí no se respeta ni la ley de la selva.
(Hier respektiert man nicht einmal das Gesetz des Dschungels)

Nicanor Parra, San Fabian, Región del Bio Bio, República de Chile

Offline khing

  • Aktives Mitglied
  • ***
  • Beiträge: 110
  • Geschlecht: Männlich
Re: Kann sich eine Klasseinstanz selbst zerstören?
« Antwort #12 am: 26.11.14 - 10:12:29 »
So, jetzt bin ich völlig vom LS verwirrt  :-\
Baue ich in der Sub New keinen "On Error Goto ..." ein, dann wird der Fehler an den aufrufenden Agenten zurückgegeben und die Klasse wird wie erwartet zerstört. Soweit logisch...
Baue ich aber nur ein "On Error Goto Ende" ein (wobei Ende einfach Exit Sub beinhaltet), dann führt der Fehler nicht zur Zerstörung der Klasse... Das ist doch nicht normal oder??? Da ist doch kein Resume vorhanden und somit darf der Fehler doch nicht gehandelt sein?!?!?!  ??? ??? ???

@flaite: Danke für die vielen Infos und natürlich hast du recht mit den Grundlagen. Auf meinen unteren Ebenen habe ich das auch so umgesetzt, nur wollte ich aus "Bequemlichkeit" mit einmal die gesamten Mutter-Klassen und Funktionen zur Verfügung haben. Sicherlich muss ich mein Klassenmodell noch einmal überdenken....
"Notes kann alles außer Kaffee kochen!"

Offline Tode

  • Moderatoren
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 6.870
  • Geschlecht: Männlich
  • Geht nicht, gibt's (fast) nicht... *g*
Re: Kann sich eine Klasseinstanz selbst zerstören?
« Antwort #13 am: 26.11.14 - 10:26:24 »
Auszug aus der Hilfe:
Zitat
GoTo  label

Specifies that when the error occurs, execution continues with an error-handling routine that begins at label. The error is considered handled.

Das heisst: Deine ErrorRoutine muss ENTWEDER den Error erneut werfen, das sieht dann so aus:

Code
ErrorHandler:
    Error Error, err

ODER einen "anderen" error provozieren, indem Du ihn eben nicht handelst:
Code
ErrorHandler:
End Sub

Im zweiten Fall bekommst Du allerdings in der aufrufenden Sub / Function den Error "No Resume" und nicht den ursprünglich aufgetretenen Fehler, den musst Du Dir schon vorher merken...

ErrorHandling ist eine sehr komplexe Sache, wenn man es richtig machen will. In unserer eigenen ErrorHandling- Routine steckt mindestens eine Mannwoche an Arbeit / Finetuning von zwei erfahrenen Notes- Entwicklern... Wir haben aber auch Stacktraces, konfigurierbares Handling (Error Message an/aus (minimal oder ausführlich), Errormail an/aus, Reporting in Dokument an/aus, und auch Besonderheiten wie "NotesUIDocument.Refresh" triggert "QueryRecalc", beide sind aber in einem völlig anderen Script- Kontext, und damit geht der Stacktrace kaputt)...
« Letzte Änderung: 26.11.14 - 10:32:37 von Tode »
Gruss
Torsten (Tode)

P.S.: Da mein Nickname immer mal wieder für Verwirrung sorgt: Tode hat NICHTS mit Tod zu tun. So klingt es einfach, wenn ein 2- Jähriger versucht "Torsten" zu sagen... das klingt dann so: "Tooode" (langes O, das r, s und n werden verschluckt, das t wird zum badischen d)

Offline khing

  • Aktives Mitglied
  • ***
  • Beiträge: 110
  • Geschlecht: Männlich
Re: Kann sich eine Klasseinstanz selbst zerstören?
« Antwort #14 am: 26.11.14 - 13:33:45 »
Vielen Dank Torsten, genau das ist es.  :D So ein ähnliches Errorhandling habe ich auch gebaut.
Den Fehler noch einmal zu werfen hat mir die Klasse ganz schön hart unter den Händen weggezogen aber wenn ich einen eigenen Fehler werfe, dann gibt er es schön sauber an den Agenten zurück und führt auch das Delete aus. Das werde ich noch überall einbauen müssen ...  :o

Bugfreie Restwoche euch allen  ;)
"Notes kann alles außer Kaffee kochen!"

 

Impressum Atnotes.de  -  Powered by Syslords Solutions  -  Datenschutz