2016-08-18 6 views
2

가 내린 후, 나는 이제 지금은 역에 내 우주선을 이동하려는 가정 해 봅시다호출하는 방법을 중지 :

(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 
) 

아래와 같은 코드 설정을 가지고 있지만 부정적인 양의 연료 계산 결과 배의 연료가 부족합니다 (예 : 여행에 충분하지 않음).

:after 한정자가 반드시 오류 조건을 알리지 않고 호출되는 것을 방지 할 수있는 방법이 있습니까?

내가 통화를 중지하지 않으면 연료는 빼지 않고 우주선이 새로운 위치로 이동하게되어 본질적으로 게임이 중단됩니다.

+0

아마도 연료 계산을': AROUND' 방법으로 옮기고': AFTER' 두 가지 방법을 기본 방법으로 바꾸어야합니다. – jkiiski

+0

@jkiiski 어떻게하면 기본 메서드가 호출되지 않게 할 수 있습니까? –

+0

그냥 전화하지 마세요. ': AROUND' 메소드는'CALL-NEXT-METHOD'를 수동으로 호출하여 기본 메소드를 호출해야하므로'(when-enough-fuel) (call-next-method)'와 같은 것을 사용할 수 있습니다. – jkiiski

답변

4

:AROUND 방법으로 연료 계산을 입력하고 두 개의 메소드를 기본 방법으로 변환 할 수 있습니다. :AROUND 메서드는 기본 메서드를 호출하기 위해 CALL-NEXT-METHOD을 수동으로 사용해야하므로 충분한 연료가있을 때만 호출하려면 (when (sufficient-fuel) (call-next-method))과 같은 작업을 수행 할 수 있습니다.

2

조건은 반드시 오류 일 필요는 없습니다. 오류는 특정한 조건입니다. 정상적인 프로그램 실행은 어떤 형태의 개입없이 올바르게 수행 될 수 없습니다.. 상태 시스템은 다른 상황의 경우에도 사용할 수 있습니다.

로컬 Lisp에도 비 로컬 컨트롤 전송을 위해 catchthrow이 있습니다. throwcatch, 동적 범위 범위 내에서 특정 catch 태그을 사용하여 캐치됩니다.

외부 :around 방법은 exit-move 태그에 대한 이탈 캐처를 설정합니다. 기본 방법 등

(defmethod move :around (ship destination) 
    (catch 'exit-move (call-next-method))) 

내측 방법은 우측 캐치 태그 exit-move으로 throw를 이용하여, 상기 catch에 제어를 전송할 수있다. 기본 방법은 항상 안에 주위에 을 사용하므로 캐치 태그 을 항상 throw 가능하게 만듭니다.

(defmethod move (ship destination) 
    (print (list :primary ship destination)) 
    (when (thing-happened-p) 
    (throw 'exit-move nil)))