← Архив: Обсуждение проекта

Перевод статьи про пакеты.

Author: · 26.06.2012 16:24
· original author: dmitrys99
Перевел статью Edi Weitz про пакеты. Перевод здесь.
Мне объяснение показалось очень полезным.
Дмитрий.
· original author: LinkFly
Переводы это хорошо, будет куда посылать новичков:)
· original author: lithp
В CLTL2 очень хорошее обьяснение.
· original author: michael.filonenko
Отлично, спасибо. А может ещё на тутошнюю вики?
Но лично моё мнение, что статья немного устарела и, к сожалению, не отвечает на главный вопрос начинающего лиспера, который чаще звучит так:
"Как всё свое творчество из репла/лисп файла запихнуть в библиотеку и опубликовать в квиклиспе." Ну то есть пошагово, как хелловорлды на всяких явах обсасывают.
maxidler с хабра несколько прав. Всё богатство красок кл сразу лучше показывать, так как никто не верит или говорит, что не нужно.
· original author: dmitrys99
Статья не устарела в смысле описания сущностей и различий между ними.
Про Quicklisp прошу уточнить, о чем идет речь: о том, чтобы опубликоваться на quicklisp.org или о том, чтобы грузить систему с помощью (ql:quickload ...)? Если о первом, то я не знаю, как это делается :)
А если о втором, то да, это можно расписать, правда, пока непонятно, где для этого время выкроить.
Насчет wiki, ну да, наверное надо разместить. Опять же, время появится, опубликую.
· original author: michael.filonenko
Вот жеш. В прошлый раз хотел сказать, что всё богатство коммон лиспа лучше сразу НЕ показывать.
Сущности модулей вроде как устарели, можно выкинуть без потери смысловой нагрузки.
Касаемо всей статьи, я имеел ввиду, что для маркетинговых целей, а тем более для хабраудитории, было бы неплохо что-то вроде.
Итак у вас есть всякие переменные и функции в репле или лисп файле:
(defvar *who* "world")
(defun greetings ()
  (format t "Hello, ~a" *who*)
)

а) Заверните это всё хозяйство в пространство имён. В коммон лиспе это называется пакет. Далее встречая слово пакет нужно думать о пространстве имён. Итак:
1. Создайте, если ещё не создан файл utils.lisp.
2. Сперва определите пакет с помощью defpackage. Импортируйте в него стандартный пакет common-lisp. Экспортируйте из него переменные и функции. Кстати в коммон лиспах переменные и функции адресуются с помощью символов. В нашем случае должно получится так:
(defpackage utils
  (:use common-lisp)
  (:export *who* greetings)
)

3. Затем перейдите в этот пакет командой in-package:
(in-package utils)
4. А затем уже разместите всё своё хозяйство:
(defvar *who* "world")
(defun greetings ()
  (format t "Hello, ~a" *who*)
)

б) Теперь необходимо сообщить коммон лиспу о том, как всё это загрузить. Есть много способов, бла-бла-бла. Единственно мейнстримный asdf. Все его используют, все довольны. Следующий шаг создание пакета (в коммон лиспе это называется asdf система). Теперь всегда встречая слово система, думайте о готовой к использованию библиотеке:
1. Для этого создаётся файл utils.asd, и в нём с помощью макроса asdf:defsystem перечисляются коммон лисповые системы:
(asdf:defsystem utils
  :licence "MIT"
  :version "1.0.0"
  :author "Your Name <yourname@email.com>"
  :depends-on ()
  :components ((:file "utils.lisp"))
  :description "Small library."
)

Как вы заметили в этот макрос передаются всякие списки. Первый важный :depends-on содержит другие asdf-cистемы, от которых зависит данная система. Все живое в мире друг от друга зависит, также и коммон лисповые системы могут друг от друга зависеть. Этот список для библиотеки cl-portaudio, которая позволяет играть/записывать звук в коммон лиспе выглядит так:
:depends-on (:cffi :ffa)
Далее идёт еще более хитрый параметр :components. В нем перечисляются а) модули (или же просто группы файлов, которые, например в одной папке лежат) б) эти самые файлы в) кого за кем грузить (или порядок загрузки файлов, или же зависимости между файлами). с) ещё пару параметров, сейчас их знать необязательно. Например, для cl-portaudio этот параметр выглядит так:
:components ((:module src
                :serial t
                :components (
                             (:file "package")
                             (:file "portaudio")
)
)
)

:module src означает, что файлы объеденены в модуль, и по-умолчанию находятся в одноимённой папке.
:serial t означает, что файлы зависимы друг от друга в том порядке, в котором перечислены.
в) Вуаля, библиотека на коммон лиспе готова. Допустим это папка myutils, c файлами utils.asd, utils.lisp. Теперь зайлейте это всё на github, ну или вообще на любой хостинг.
г) В коммон лиспе стараниями Зака Бина появлися прекрасный менеджер библиотек, который позволяет одной командой скачать загрузить как саму библиотеку, так и все её зависимости. Например,
(mapcar #'quicklisp:quickload '(:cl-gtk2-gtk :cl-portaudio))
Загрузит cl-gtk2 и cl-portaudio со всеми зависимостями, так что можно писать теперь свой скайп со шлюхами и блекджеком.
Для того, чтобы ваша библиотека попала в репозитарий quicklisp'а, просто оставьте на неё ссылку здесь: https://github.com/quicklisp/quicklisp-projects/issues?direction=desc&sort=created&state=open. Внимание, соблюдайте традицию вежливости, начинайте заголовок со слова "Please"!:)
Теперь ещё большее внимание!!! Всё это можно было проделать за ДВЕ команды. Итак:
(ql:quickload :quickproject)
(quickproject:make-project "path/to/library" :depends-on '() :license "MIT" :author "Your name <your@email.com>" :name "utils")
· original author: michael.filonenko
Ах жеш, оно оказывается наклонный шрифт делало.
· original author: andy128k
Я джва года ждал такой туториал.
· original author: motopeh
(mapcar #'quicklisp:quickload '(:cl-gtk2-gtk :cl-portaudio))
эквивалентно
(ql:quickload '(:cl-gtk2-gtk :cl-portaudio))
но последнее короче.
· original author: michael.filonenko
Моя ошибка.
· original author: stairs
создал проект таким образом(как вы писали):
(ql:quickload :quickproject)
(quickproject:make-project "path/to/library" :depends-on '() :license "MIT" :author "Your name <your@email.com>" :name "utils")
загрузил:
(ql:quickload "library")
все работало
но после перезагрузки РЕПЛа библиотека перестала загружаться(говорит, что такой не знает).
· original author: michael.filonenko
меня лучше на ты.
надо либо
(pushnew "/path/to/library/" asdf:*central-registry*)
, либо сделать сделать в папке ~/quicklisp/local-prjects ссылку на path/to/library.