2013-04-10 8 views
8

Potrzebuję w jakiś sposób oznaczyć pewne funkcje Clojure jako "specjalne", aby kod Java mógł je rozpoznać jako takie za pomocą odbicia. Próbowałem dodać adnotację do funkcji, ale najwyraźniej to nie jest obsługiwane. Próbowałem do reify interfejsu rozszerzającego IFn (tak, aby kod Java mógł rozpoznać obiekt funkcji), ale to nie jest dobre, ponieważ Clojure nie używa bezpośrednio reifikowanej metody jako kod implementujący invoke, ale raczej pośrednie wywołanie do Afunction obiekt, który faktycznie implementuje metodę (muszę oznaczyć rzeczywistą metodę invoke z faktycznym kodem funkcji).Jak oznaczyć funkcję Clojure tak, aby móc ją rozpoznać po odbiciu Java

Wszelkie pomysły?

EDYCJA: nawet tagowanie w sposób, w jaki można uzyskać dostęp z biblioteki ASM (zamiast regularnego odbicia) byłoby w porządku, ale muszę jakoś oznaczyć rzeczywisty obiekt AFunction lub metodę invoke. Ponadto nie mogę uzyskać dostępu do rzeczywistego obiektu AFunction - potrzebuję tagu, aby był widoczny na klasie.

Odpowiedz

3

Można użyć Clojure funkcję meta-danych, który pozwala meta danych (mapa) być dołączone do dowolnego obiektu, który implementuje IMeta interfejs (który okazuje się być każdy przedmiot jako IObj rozciąga IMeta a każdy obiekt przedłużyć IObj)

Teraz są 2 opcje.

1) Możesz dołączyć dane meta do var (punktach var do rzeczywistego obiektu IFN)

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

i na stronie Java Ci zdobyć var ​​Witam i stosowanie metod IMeta aby uzyskać meta-danych i wykryj, czy istnieją tam określone dane meta. Problem może dotyczyć tego, że twój kod Java uzyskuje dostęp/obsługuje obiekty IFn bezpośrednio, a nie ich vary (np. Funkcje anonimowe), aby rozwiązać ten problem, wypróbuj drugą opcję.

2) Dołączyć dane meta do samego obiektu funkcji:

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

Nie można używać defn jak dołączyć dane meta do var. Powyższy przykładowy kod dołącza metadane do samego obiektu funkcji. Po stronie Java, typecase obiektu funkcji do IMeta i wykonaj kontrolę. Powyższy kod może być nieco bardziej defn podobny przy pomocy makra, który jest pozostawiony jako ćwiczenie :)

+0

Dzięki! Niestety, nie mam nawet dostępu do samego obiektu IFn - tylko do jego klasy. Muszę jakoś oznaczyć klasę (nie muszę nawet dołączać żadnych konkretnych informacji, tylko sposób, aby ustalić, czy klasa jest "zaznaczona" w jakiś sposób). Pomyślałem o oznaczeniu go za pomocą metody invoke, która określa, że ​​generuje dobrze znany sprawdzony wyjątek, ale nie ma sposobu, aby to zrobić z Clojure. – pron

+0

Czy możesz podać przykładowy kod clojure i java, aby pokazać, w jaki sposób klasa z clojure jest tworzona i dostępna z poziomu Javy, co sprawiłoby, że pytanie byłoby bardziej zrozumiałe. – Ankur

+0

Używam narzędzia JavaAgent do obsługi niektórych klas. Otrzymuję powiadomienie o załadowaniu nowej klasy. Chciałbym w jakiś sposób oznaczyć funkcję Clojure tak, że będę wiedział, czy wymaga to oprzyrządowania. – pron

0

Okazuje się, że jeśli załączysz treść funkcji za pomocą instrukcji let zawierającej definicję lokalną, to nazwa zmiennej pojawi się w lokalnej tabeli metody w pliku klasy. Nieco kłopotliwe. Wciąż szukam lepszego sposobu.

Powiązane problemy