2013-04-10 9 views
8

Tôi cần bằng cách nào đó gắn thẻ các chức năng Clojure nhất định là "đặc biệt" để mã Java có thể nhận ra chúng như vậy bằng cách sử dụng sự phản chiếu. Tôi đã cố gắng thêm chú thích vào một hàm, nhưng dường như nó không được hỗ trợ. Tôi đã cố gắng để reify một giao diện mở rộng IFn (để mã Java có thể nhận ra đối tượng hàm), nhưng điều đó không tốt bởi vì Clojure không trực tiếp sử dụng phương thức được sửa đổi như mã thực hiện invoke, mà là một cuộc gọi gián tiếp đến Afunction đối tượng thực sự đang triển khai phương thức (tôi cần gắn thẻ phương thức invoke thực tế với mã chức năng thực tế).Làm cách nào để gắn thẻ chức năng Clojure để tôi có thể nhận ra nó với sự phản chiếu Java

Bất kỳ ý tưởng nào?

EDIT: thậm chí gắn thẻ theo cách có thể được truy cập bằng thư viện ASM (thay vì phản chiếu thông thường) sẽ ổn, nhưng tôi cần bằng cách nào đó gắn thẻ đối tượng AFunction thực tế hoặc phương thức invoke. Ngoài ra, tôi không thể truy cập đối tượng thực tế AFunction - Tôi cần thẻ hiển thị trên lớp.

Trả lời

3

Bạn có thể sử dụng clojure tính năng siêu dữ liệu cho phép dữ liệu meta (bản đồ) được gắn vào bất kỳ đối tượng mà thực hiện IMeta giao diện (mà hóa ra là mọi đối tượng như IObj kéo dài IMeta và mọi đối tượng mở rộng IObj)

Hiện có 2 tùy chọn.

1) Bạn có thể đính kèm các dữ liệu meta để một var (các điểm var đến đối tượng IFN thực tế)

(defn hello {:name "hello"} [] 10) 

và đứng về phía Java bạn có được giữ của var hello và sử dụng phương pháp IMeta để có được siêu dữ liệu và phát hiện xem liệu dữ liệu meta cụ thể của bạn có ở đó hay không. Vấn đề với điều này có thể là mã Java của bạn truy cập/xử lý các đối tượng IFn trực tiếp thay vì các vars của chúng (ví dụ: các hàm ẩn danh), để giải quyết điều này, hãy thử tùy chọn thứ 2.

2) Gắn dữ liệu meta để các đối tượng chức năng chính:

(def hello (with-meta (fn [] 10) {:name "hello"})) 

Bạn không thể sử dụng defn như đính kèm dữ liệu meta vào var. Mã mẫu ở trên đính kèm dữ liệu meta vào chính đối tượng hàm. Ở phía Java, gõ đối tượng hàm vào IMeta và thực hiện kiểm tra. Đoạn mã trên có thể được thực hiện nhiều hơn một chút defn likish với sự giúp đỡ của một vĩ mô mà là trái như một bài tập :)

+0

Cảm ơn! Thật không may, tôi thậm chí không có quyền truy cập vào chính đối tượng IFn - chỉ cho lớp của nó. Tôi cần phải bằng cách nào đó gắn thẻ lớp học (tôi thậm chí không cần đính kèm bất kỳ thông tin cụ thể nào, chỉ là một cách để xác định xem lớp học có "được đánh dấu" bằng cách nào đó) không. Tôi nghĩ rằng gắn thẻ nó bằng cách có phương pháp gọi xác định rằng nó ném một ngoại lệ kiểm tra nổi tiếng, nhưng không có cách nào mà tôi biết làm điều đó từ Clojure. – pron

+0

Bạn có thể cung cấp một số mã mẫu của clojure và java để cho thấy lớp học từ clojure được tạo ra và truy cập từ Java như thế nào sẽ làm cho câu hỏi rõ ràng hơn – Ankur

+0

Tôi sử dụng JavaAgent để thiết lập một số lớp. Tôi được thông báo khi một lớp mới được tải. Tôi muốn bằng cách nào đó gắn thẻ một hàm Clojure để tôi biết nếu nó đòi hỏi thiết bị đo đạc. – pron

0

Nó chỉ ra rằng nếu bạn gửi kèm theo các cơ quan chức năng với một tuyên bố let chứa một định nghĩa địa phương, mà tên biến sẽ xuất hiện trong bảng địa phương của phương thức trong tệp lớp. Một chút rườm rà, mặc dù. Vẫn đang tìm kiếm một cách tốt hơn.