Символы shorthands, иногда называемые «переименованные символы», являются символьными формами, встречающимися в исходном коде Lisp. Они ничем не отличаются от обычных символьных форм, за исключением того, что когда парсер Lisp встречает их, он создает символы, которые имеют другое и обычно более длинное имя вывода (print name) (см. Компоненты символов).
Полезно рассматривать сокращения как сокращение полных названий предполагаемых символов. Несмотря на это, не путайте сокращения с системой Abbrev (см. Abbrevs и расширение Abbrev).
Сокращения облегчают работу с правилами именования (namespacing etiquette)
Emacs Lisp. Поскольку все символы хранятся в одном obarray
(см. Создание и интернирование символов),
программисты обычно префиксуют имя каждого символа именем библиотеки, из которой он
происходит. Например, функции text-property-search-forward и
text-property-search-backward принадлежат библиотеке
text-property-search.el (см. Загрузка).
Правильно префиксируя имена символов, можно эффективно предотвратить конфликты
между символами с похожими именами, принадлежащими к разным библиотекам и, следовательно,
выполняющими разные действия. Однако эта практика часто приводит к очень
длинным именам символов, которые неудобно набирать и читать со временем.
Сокращения решают эти проблемы чистым способом.
Значение этой переменной представляет собой alist, элементы которого имеют вид
(shorthand-prefix . longhand-prefix).
Каждый элемент инструктирует парсер Lisp читать каждую символьную форму, начинающуюся
с shorthand-prefix, как если бы она начиналась с longhand-prefix.
Эту переменную можно установить только в файловых переменных (см. Локальные переменные в файлах в Руководство GNU Emacs).
Вот пример использования сокращений в гипотетической библиотеке для манипулирования строками some-nice-string-utils.el.
(defun some-nice-string-utils-split (separator s &optional omit-nulls) "A match-data saving variant of `split-string'." (save-match-data (split-string s separator omit-nulls))) (defun some-nice-string-utils-lines (s) "Split string S at newline characters into a list of strings." (some-nice-string-utils-split "\(\r\n\|\[\n\r\]\)" s))
Как видно, читать или разрабатывать этот код довольно утомительно, поскольку имена символов для набора очень длинные. Мы можем использовать сокращения, чтобы смягчить эту проблему.
(defun snu-split (separator s &optional omit-nulls)
"A match-data saving variation on `split-string'."
(save-match-data (split-string s separator omit-nulls)))
(defun snu-lines (s)
"Split string S into a list of strings on newline characters."
(snu-split "\(\r\n\|\[\n\r\]\)" s))
;; Local Variables:
;; read-symbol-shorthands: (("snu-" . "some-nice-string-utils-"))
;; End:
Хотя два фрагмента выглядят по-разному, после обработки парсером Lisp они
очень похожи. Оба приведут к интернированию абсолютно одинаковых символов
(см. Создание и интернирование символов).
Таким образом, загрузка или байт-компиляция любого из двух файлов дает
эквивалентные результаты. Сокращения snu-split и
snu-lines, используемые во второй версии, не
интернируются в obarray. Это легко увидеть, переместив курсор в место, где
используются сокращения, и дождавшись подсказки ElDoc (см. Локальные переменные в файлах в Руководство GNU Emacs),
чтобы увидеть истинное полное имя символа под курсором в области вывода.
Поскольку read-symbol-shorthands является файловой
переменной, возможно, что несколько библиотек, зависящих от
some-nice-string-utils-lines.el, ссылаются на одни и те же
символы под разными сокращениями или вообще не используют
сокращения. В следующем примере библиотека my-tricks.el
ссылается на символ some-nice-string-utils-lines, используя
префикс sns- вместо snu-.
(defun t-reverse-lines (s) (string-join (reverse (sns-lines s)) "\n")
;; Local Variables:
;; read-symbol-shorthands: (("t-" . "my-tricks-")
;; ("sns-" . "some-nice-string-utils-"))
;; End:
Обратите внимание, что если у вас есть два сокращения в одном файле, где одно является префиксом другого, будет предпринята попытка использовать более длинное сокращение. Это происходит независимо от порядка, в котором вы указываете сокращения в разделе локальных переменных вашего файла.
'(
t//foo ; читается как 'my-tricks--foo', а не 'my-tricks-/foo'
t/foo ; читается как 'my-tricks-foo'
)
;; Local Variables:
;; read-symbol-shorthands: (("t/" . "my-tricks-")
;; ("t//" . "my-tricks--"))
;; End:
Существуют два исключения из правил, управляющих преобразованиями сокращений:
- или
/= в качестве префиксов сокращений, но это не будет
затенять арифметические функции этих имен.