Ich habe eine Reihe von Klassen erhalten, die eine Nachricht darstellen, die behandelt werden muss. Es gibt jedoch nur eine begrenzte Anzahl von offenen Stellen für Handler. Daher muss jeder "Dispatch" eines Handlers, der ein Nachrichtenobjekt behandelt, zuerst prüfen, ob ein freier Platz vorhanden ist.Wie man die Codeverdoppelung unter Verwendung der Methodenkombination reduziert, aber mögliche frühe Rückkehr behält
Wenn es -> Versand ist.
Wenn gibt es nicht -> Versand nicht an und bringt Nachricht
Da dieser Teil des Codes entspricht, wird das gleiche in jedem Versandweg sein ich es dachte, am besten wäre, die Methode Kombination Anlage zu verwenden, um durchzusetzen, dass , aber ich kann nicht herausfinden, wie.
In meinem aktuellen Codebasis habe ich versucht, eine verwenden: vor Methode, aber anscheinend kann man nicht Rückkehr in einem solchen Kontext verwenden:
(defclass message() ((msg :initarg :msg :reader msg)))
(defclass message-ext (message)
((univ-time :initarg :univ-time :reader univ-time)))
(defparameter *open-handler* nil)
(defgeneric handle (message)
(:documentation "handle the given message appropriately"))
(defmethod handle :before ((message message))
(when (> (length *open-handler*) 1)
(return :full)))
(defmethod handle ((message message))
(push (FORMAT nil "dispatched handler") *open-handler*))
(defmethod handle ((message-ext message-ext))
(push (FORMAT nil "dispatched ext handler") *open-handler*))
(handle (make-instance 'message :msg "allemeineentchen"))
(handle (make-instance 'message-ext
:msg "rowrowrowyourboat"
:univ-time (get-universal-time)))
(handle (make-instance 'message-ext
:msg "gentlydownthestreet"
:univ-time (get-universal-time)))
Execution of a form compiled with errors.
Form:
(RETURN-FROM NIL FULL)
Compile-time error:
return for unknown block: NIL
[Condition of type SB-INT:COMPILED-PROGRAM-ERROR]
Restarts:
0: [RETRY] Retry SLIME interactive evaluation request.
1: [*ABORT] Return to SLIME's top level.
2: [TERMINATE-THREAD] Terminate this thread (#<THREAD "worker" RUNNING {100594F743}>)
Backtrace:
0: ((SB-PCL::FAST-METHOD HANDLE :BEFORE (MESSAGE)) #<unavailable argument> #<unavailable argument> #<unavailable argument>)
1: ((SB-PCL::EMF HANDLE) #<unavailable argument> #<unavailable argument> #<MESSAGE-EXT {1005961733}>)
2: (SB-INT:SIMPLE-EVAL-IN-LEXENV (HANDLE (MAKE-INSTANCE 'MESSAGE-EXT :MSG "gentlydownthestreet" :UNIV-TIME (GET-UNIVERSAL-TIME))) #<NULL-LEXENV>)
3: (EVAL (HANDLE (MAKE-INSTANCE 'MESSAGE-EXT :MSG "gentlydownthestreet" :UNIV-TIME (GET-UNIVERSAL-TIME))))
4: ((LAMBDA() :IN SWANK:INTERACTIVE-EVAL))
Ist dieser Ansatz sogar gesund, und wenn ja, wie kann ich es tun in eine funktionierende Mode? (Ich habe schon versucht return-from
mit dem gleichen Ergebnis)