2011-05-04 31 views
11

Tôi nhận ra rằng một phần nhất định của mã của tôi bao gồm các nhóm phương pháp trông tương tự (như tôi có nhiều bộ ba: một hàm trợ giúp được gọi bởi hai hàm khác dành cho lập trình viên). Tôi đang cố gắng để viết một macro sẽ xác định ba chức năng cho tôi để tất cả tôi cần làm là gọi macro. Nhưng nỗ lực của tôi dẫn đến defuns và chức năng cuộc gọi đã trích dẫn chuỗi thay vì tên được tạo ra như là biểu tượng mới. Tôi đang làm gì sai?lisp chung: làm thế nào macro có thể xác định các phương thức/macro khác bằng tên được tạo theo chương trình?

Ví dụ (mã không chính xác)

(defmacro def-trio (base-name) 
    (let 
    ((helper-name (format nil "helper-~a" base-name)) 
    (method-1 (format nil "~a-1" base-name)) 
    (method-2 (format nil "~a-2" base-name))) 
    `(progn 
      (defun ,helper-name() 'helper-called) 
      (defun ,method-1() (,helper-name) '1-called) 
      (defun ,method-2() (,helper-name) '2-called)))) 

Bây giờ sau xảy ra:

(def-trio my-trio) 

==>

(PROGN (DEFUN "helper-MY-TRIO"() 'HELPER-CALLED) 
     (DEFUN "MY-TRIO-1"() ("helper-MY-TRIO") '1-CALLED) 
     (DEFUN "MY-TRIO-2"() ("helper-MY-TRIO") '2-CALLED)) 

Ngoài ra, sau khi tôi học cách để làm việc này, là có thêm gotcha nếu tôi có macro này xác định các macro khác thay vì các chức năng khác? Tôi đọc How do I write a macro-defining macro in common lisp nhưng tôi nghĩ câu hỏi của tôi hơi khác một chút vì tôi hỏi về các biểu tượng/tên được tạo lập trình. Tôi đang mở để được sửa chữa mặc dù :) Cảm ơn!

+0

Vui lòng gửi câu hỏi 'macro xác định các macro khác' làm bài đăng riêng biệt vì nó không liên quan chặt chẽ. –

Trả lời

5

Sử dụng INTERN để biến các chuỗi tên chức năng được tạo thành ký hiệu.

7

Hãy thử điều này:

 
(defmacro def-trio (base-name)           ; changes: 
    (let*                ; 3. 
    ((package (symbol-package base-name))        ; 2. 
    (helper-name (intern (format nil "HELPER-~a" base-name)package)) ; 1. 4. 
    (method-1 (intern (format nil "~a-1" base-name) package))   ; 1. 
    (method-2 (intern (format nil "~a-2" base-name) package)))  ; 1. 
    `(progn 
      (defun ,helper-name() 'helper-called) 
      (defun ,method-1() (,helper-name) '1-called) 
      (defun ,method-2() (,helper-name) '2-called)))) 

Những thay đổi sau đây đã được thực hiện để định nghĩa ban đầu của bạn - sự thay đổi đầu tiên là quan trọng nhất:

  1. thực tập nội trú mỗi tên biểu tượng tính vào gói tương tự như tên cơ sở sử dụng (intern ... package).
  2. Giới thiệu biến số package được gắn với gói biểu tượng base-name được cung cấp.
  3. Đã thay đổi let thành let* để cho phép biến mới được giới thiệu package được tham chiếu trong các biến tiếp theo.
  4. Thay đổi tiền tố của phương thức trợ giúp thành chữ hoa để khớp với quy ước cho ký hiệu Lisp bình thường.
+0

Cảm ơn sự trợ giúp chi tiết! Tôi đã nhận được một cái gì đó làm việc ngay trước khi bạn đăng nhưng mã của tôi không rõ ràng về những gói để sử dụng cho các cuộc gọi thực tập. – nil

Các vấn đề liên quan