Chuyển đến nội dung
Diễn đàn CADViet
Đăng nhập để thực hiện theo  
hellocadviet

Hỏi về hàm *error*

Các bài được khuyến nghị

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

  • Vote tăng 1

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

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.

  • Vote tăng 1

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác
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.

  • Vote tăng 7

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Tạo một tài khoản hoặc đăng nhập để nhận xét

Bạn cần phải là một thành viên để lại một bình luận

Tạo tài khoản

Đăng ký một tài khoản mới trong cộng đồng của chúng tôi. Điều đó dễ mà.

Đăng ký tài khoản mới

Đăng nhập

Bạn có sẵn sàng để tạo một tài khoản ? Đăng nhập tại đây.

Đăng nhập ngay
Đăng nhập để thực hiện theo  

×