common-lispqualifiersmultimethod

Stopping the method from calling :after


Say I have a code setup like the one below

(defgeneric move (ship destination))

(defmethod move (ship destination)
  ;; do some fuel calculation here
)

(defmethod move :after ((ship ship) (dest station))
  ;; do things specific to landing on a station here
)

(defmethod move :after ((ship ship) (dest planet))
 ;; do things specific to landing on a planet here
)

Let's now say I want to move my space ship to a station, but the fuel calculation results in a negative amount of fuel on the ship (i.e. there's not enough for the trip).

Is there then a way for me to prevent the :after qualifier from getting called without necessarily signalling an error condition?

If I don't stop the call, the ship will be moved to the new location without any fuel getting subtracted, which essentially breaks the game.


Solution

  • You can put the fuel calculation in an :AROUND method and turn the two :AFTER methods into primary methods. :AROUND methods must use CALL-NEXT-METHOD manually to call the primary method, so you can do something like (when (sufficient-fuel) (call-next-method)) to only call it when there is enough fuel.