Đến nội dung


Hình ảnh
- - - - -

Hỏi về hàm *error*


  • Please log in to reply
4 replies to this topic

#1 hellocadviet

hellocadviet

    biết vẽ line

  • Members
  • PipPip
  • 25 Bài viết
Điểm đánh giá: 2 (bình thường)

Đã gửi 09 August 2008 - 10:08 AM

Hỏi về hàm *error*
Có đoạn lisp như thế này:

(defun c:drawline () ;define function
(setq temperr *error*) ;store *error*
(setq *error* trap1) ;re-assign *error*
(setq oldecho (getvar "cmdecho")) ;store variables
(setq oldlayer (getvar "clayer"))
(setq oldsnap (getvar "osmode"))
(setvar "cmdecho" 0) ;set variables
(setvar "osmode" 32)
(command "undo" "m") ;undo mark
(setq pt1 (getpoint "\nPick First Point: ")) ;get points
(setq pt2 (getpoint pt1 "\nPick Second Point: "))
(command "LAYER" "M" "2" "") ;change layer
(command "Line" pt1 pt2 "") ;draw line
(setq pt3 (getpoint pt2 "\nPick Third Point: "));get 3rd point
(setvar "osmode" 0) ;switch off snap
(command "Line" pt2 pt3 "") ;draw line
(setvar "clayer" oldlayer) ;reset variables
(setvar "osmode" oldsnap)
(setvar "cmdecho" oldecho)
(setq *error* temperr) ;restore *error*
(princ)
)


(defun trap1 (errmsg) ;define function
(command "u" "b") ;undo back
(setvar "osmode" oldsnap) ;restore variables
(setvar "clayer" oldlayer)
(setvar "cmdecho" oldecho)
(setq *error* temperr) ;restore *error*
(prompt "\nResetting System Variables ") ;inform user
(princ)
)


(setq temperr *error*) ;store *error*
(setq *error* trap1) ;re-assign *error*


- Hàm *error* có đối số bắt buộc (*error* string) vậy tại sao ở ví dụ trên lại không có?
- Hàm (setq *error* trap1) được chạy ngay hay khi có lỗi thì mới chạy?
- Sau hàm setq thì đối số sau nó không được thực thi nhưng tại sao hàm *error* được gọi khi có lỗi xuất hiện (hàm trap1 được chạy).
- Lisp biên dịch tuần tự từng dòng một, vậy khi ta chạy đến dòng lệnh yêu cầu “Pick fist point:” chẳng hạn mà gây lỗi thì tại sao hàm *error* vẫn được gọi? (quay ngược trở lại phía trên).
- Khi xuất hiện lỗi thì cả hai hàm sau đều thực hiện?

(setq *error* trap1) (phần đầu)

(setq *error* temperr) (phần cuối)


Vậy những dòng lệnh sau bị thừa (vì trong hàm trap1 đã có)?

(setq *error* temperr)
(setvar "osmode" oldsnap) ;restore variables
(setvar "clayer" oldlayer)
(setvar "cmdecho" oldecho)
(setq *error* temperr)


Xin cảm ơn nhiều (đang bị cái hàm bắt lỗi error làm đau đầu quá)
  • 1

#2 ssg

ssg

    biết lệnh adcenter

  • Vip
  • PipPipPipPipPipPipPip
  • 1228 Bài viết
Điểm đánh giá: 1087 (rất tốt)

Đã gửi 09 August 2008 - 11:00 AM

...đang bị cái hàm bắt lỗi error làm đau đầu quá

Bạn vào đây chắc sẽ hết đau đầu!

http://www.cadviet.c...amp;#entry22008
  • 1

#3 hellocadviet

hellocadviet

    biết vẽ line

  • Members
  • PipPip
  • 25 Bài viết
Điểm đánh giá: 2 (bình thường)

Đã gửi 09 August 2008 - 01:02 PM

Cảm ơn bác. Trước khi mình hỏi ở thread này cũng đã đọc hết các thread nói về hàm *error* nhưng chưa có nói rõ về hàm này. Mong các bác giải thích hộ mình mấy câu hỏi mà mình thắc mắc bên trên với. Cảm ơn các bác.
  • 1

#4 ssg

ssg

    biết lệnh adcenter

  • Vip
  • PipPipPipPipPipPipPip
  • 1228 Bài viết
Điểm đánh giá: 1087 (rất tốt)

Đã gửi 09 August 2008 - 03:16 PM

Cảm ơn bác. Trước khi mình hỏi ở thread này cũng đã đọc hết các thread nói về hàm *error* nhưng chưa có nói rõ về hàm này. Mong các bác giải thích hộ mình mấy câu hỏi mà mình thắc mắc bên trên với. Cảm ơn các bác.

Bạn đã đọc bài của anh Hoành nhưng vẫn chưa thông? Ssg xin giải thích kỹ hơn chút:

1- *error* là hàm đặc biệt, đã được định nghĩa sẵn, gọi là hàm error chuẩn (AutoLISP standard error-handling function) . Bạn không quan tâm đến, nó vẫn tồn tại và âm thầm hoạt động cùng với Acad. Ví dụ, bạn nhập biểu thức sau:
Command: (setq x 1 y)
sẽ thấy thông báo: error: syntax error

Autodesk tạo *error* chuẩn như thế nào mình không biết, nhưng theo giải thích của họ, cái vỏ bề ngoài của nó tương đương với đoạn lisp sau:

(defun *error* (msg)
(princ "error: ")
(princ msg)
(princ)
)

Nếu xảy ra lỗi (hoặc user bấm ESC), Acad sẽ thực hiện các động tác:
- Gán kết quả kiểm tra lỗi cho biến msg. Trong ví dụ trên được hiểu là: (setq msg "syntax eror")
- Thực hiện hàm *error* với biến msg này (và kết quả cuối cùng như bạn đã thấy "error: syntax error")

2- *error* thuộc dạng "user-definable", nghĩa là bạn có thể tuỳ nghi sửa đổi theo ý đồ lập trình, phù hợp với một tình huống cụ thể nào đó. Tuy nhiên, khi xong việc, bạn phải trả lại *error* chuẩn để nó làm nhiệm vụ như thường lệ.

3- Phân tích đoạn code của bạn:

(setq temperr *error*) ;Lưu lại *error* chuẩn, gán cho biến temperr
(setq *error* trap1) ;Định nghĩa lại *error* theo hàm trap1

Kể từ thời điểm này, khi xảy ra lỗi hoặc user bấm ESC, hàm trap1 sẽ thực hiện thay cho *error* chuẩn. Trong trap1, bạn muốn làm gì tuỳ ý, chỉ có 1 yêu cầu duy nhất: phải có đối số là string (tương tự như *error* chuẩn), mặc dù có thể bạn không đả động gì đến đối số này trong code. Trong hàm trap1 của bạn, string đó chính là "errmsg"

Khi chạy chương trình, có 2 khả năng xảy ra:
a- Nếu không có lỗi, hàm C:drawline sẽ thực hiện thông suốt từ đầu đến cuối và sẽ trả lại *error* chuẩn bằng dòng: (setq *error* temperr)

b- Nếu có lỗi hoặc user bấm ESC giữa chừng, chương trình bị ngắt "ngang xương". Giả sử không có bẫy lỗi trap1, các biến osmode, clayer, cmdecho... sẽ không trả lại như trước được. Nhưng vì ta đã đặt trap1, toàn bộ các thao tác trong nó sẽ được thực hiện. Cụ thể, với trap1 là:
- Tái lập các biến osmode, clayer... như lúc đầu
- Trả lại *error* chuẩn cho Acad
- .... (những thao tác khác tuỳ ý bạn)

Hy vọng bạn thoả mãn với các giải thích trên.
  • 7

#5 cuongtk2

cuongtk2

    biết vẽ ellipse

  • Members
  • PipPip
  • 59 Bài viết
Điểm đánh giá: 20 (tàm tạm)

Đã gửi 09 August 2008 - 03:46 PM

Cảm ơn ssq, bài viết của bạn rất có chất lượng. "Bây giờ thì em đã hiểu Fugacar diệt trừ giun như thế nào".
  • 1