Вообще, java-библиотеки осваивают, как правило, именно на java. Традиционный цикл выглядит так:
- написать пример использования какой-нибудь функции;
- скомпилировать, исправить синтаксические ошибки;
- скомпилировать, убедиться, что ничего не работает;
- опять поправить использование функций в соответствии с документацией;
- скомпилировать, получить какой-то результат.
Недавно мне пришлось разбираться с библиотекой libsvm -- реализацией алгоритма классификации по методу машины опорных векторов. Оказалось, что clojure подходит для исследования возможностей java-библиотек гораздо лучше, чем сама java. Дело, конечно же, в repl-е. Удобство состоит в том, что выполнив какую-то часть вычислений, можно продолжать экспериментировать с результатами. Например, выполнив классификацию на первом тестовом наборе, можно тут же, не сходя с места, подправить определение тестового набора и запустить классификацию на другом и т.д. Процесс идет гораздо быстрее, потому что для исследования каждой отдельной функции библиотеки совсем не обязательно перезапускать весь цикл исправление-компиляция-выполнение.
Еще одна приятная возможность из библиотеки clojure-contrib -- функция show. Она показывает все методы, принадлежащие переданные ей сущности. Для использования show ее нужно импортировать: (use '[clojure.contrib.repl-utils :only (show)]). Выход функции выглядит так:
user=> (show 10)
=== public final java.lang.Integer ===
[ 0] static MAX_VALUE : int
[ 1] static MIN_VALUE : int
[ 2] static SIZE : int
[ 3] static TYPE : Class
[ 4] static bitCount : int (int)
[ 5] static decode : Integer (String)
[ 6] static getInteger : Integer (String)
[ 7] static getInteger : Integer (String,Integer)
[ 8] static getInteger : Integer (String,int)
[ 9] static highestOneBit : int (int)
[10] static lowestOneBit : int (int)
[11] static numberOfLeadingZeros : int (int)
[12] static numberOfTrailingZeros : int (int)
[13] static parseInt : int (String)
[14] static parseInt : int (String,int)
[15] static reverse : int (int)
[16] static reverseBytes : int (int)
[17] static rotateLeft : int (int,int)
[18] static rotateRight : int (int,int)
[19] static signum : int (int)
[20] static toBinaryString : String (int)
[21] static toHexString : String (int)
[22] static toOctalString : String (int)
[23] static toString : String (int)
[24] static toString : String (int,int)
[25] static valueOf : Integer (String)
...
Правда работает она пока что только в стабильной (1.2.0) ветке Clojure. В тестовой 1.3.0-alpha4 сваливается с ошибкой.
Хм, а я уже давно обнаружил, что аналогичные утверждения также верны и для изучения C-библиотек с помощь Common Lisp )
ОтветитьУдалитьО, прикольно!
ОтветитьУдалитьКстати, как твой Mongrel2 + CL? Есть уже что-нибудь, чтоб можно скачать и пощупать? Я пробовал установить, как написано на их хомсайте, но не осилил зависимости...
@Dmitry
ОтветитьУдалитьНа Mongrel2 я наступаю набегам ) После последнего я смог запустить локальную версию lisper.ru на основе Mongrel2 без Hunchentoot. Правда с тем ограничением, что вся обработка идёт в однопоточном режиме, плюс оверхед большой (на копирование памяти туда/сюда).
Mongrel2 для меня это сейчас работа на перспективу, так что я не форсирую, а доступного времени мало, ибо из-за скудности имеющихся библиотек очень много более актуальных задач (
Кстати, сам Mongrel2 ставится то тривиально (make && make install), но он требует свежие версии используемых библиотек, что на каком-нибудь Debian может оказаться не очень удобным. Ну да у меня Gentoo, поэтому никаких проблем не было.
Скачать/пощупать можно попробовать, но это требует некоторых усилий и сопровождения с моей стороны.
jruby именно для этого ещё удобнее
ОтветитьУдалитьА как там repl интегрируется с текстовым редактором? С тем же удобством, что emacs/slime? И еще, как там доступ к java-типам? Насколько он прост?
ОтветитьУдалитьruby-1.9.2-p0 > java.lang.Integer.methods.sort
ОтветитьУдалить=> ["<", "<=", "<=>", "==", "===", "=~", ">", ">=", "[]", "__id__", "__jtrap", "__send__", "allocate", "ancestors", "autoload", "autoload?", "bitCount", "bitCount__method", "bit_count", "bit_count__method", "class", "class_eval", ...
Тут он конечно подмешивает ruby-specific methods.
ruby-1.9.2-p0 > java.lang.Integer.methods.grep /get/
=> ["getInteger", "get_integer", "get_integer__method", "getInteger__method", "const_get", "instance_variable_get"]
Если подскажете подобное в clojure repl буду очень признателен потому что часто необходимо.
Я Emacs к большому сожалению не владею, вроде там есть ruby mode, насколько он хорош не знаю.
Ну так я же написал, там есть функция show, которая выводит все методы для объекта. В статье -- перечислены первые 26 методов класса Integer; примесей вроде никаких нету. Впрочем, не это самое главное, Intellisence худо-бедно умеют все IDE. Но вот интеграции с нормальным repl-ом я еще нигде не видел, кроме emacs+slime. Хотя Eclipse и Netbeans, похоже, идут в этом направлении.
ОтветитьУдалитьshow *печатает* методы объекта. .methods в руби возвращает массив имён методов. У рубиевского Array есть такие удобные функции как например sort и grep
ОтветитьУдалитьМне это помогает в репл посмотреть какие например get методы есть у java класса
Посмотрел (source show), переделаю чтобы возвращал sequence :)
ОтветитьУдалить