Глава 5 - Скрипты
REBOL/Core руководство пользователя Основное содержание Send Us Feedback
Содержание:
1. Обзор
1.1 Суффикс файла
1.2 Структура
2. Заголовки
3. Аргументы сценария
3.1 Параметры программы
4. Запуск сценариев
4.1 Загрузка сценариев
4.2 Сохранение сценариев
4.3 Комментирование сценариев
5. Руководство по стилям
5.1 Форматирование
5.2 Имена слов
5.3 Заголовки сценариев
5.4 Заголовки функций
5.5 Имена файлов сценариев
5.6 Встроенные примеры
5.7 Встроенная отладка
5.8 Сворачивание глобальных объектов
6. Очистка скрипта
1. Обзор
Термин script(скрипт/сценарий) относится не только к отдельным файлам, которые оцениваются, но и к исходному тексту, встроенному в другие типы файлов (например, веб-страницы), или фрагментам исходного текста, которые сохраняются как файлы данных или передаются как сообщения.
1.1 Суффикс файла
Сценарии REBOL обычно добавляют суффикс(расширение) .r к именам файлов; однако это соглашение не требуется. Интерпретатор читает файлы с любым суффиксом и просматривает их содержимое на предмет наличия допустимого заголовка сценария REBOL.
1.2 Структура
Структура скрипта произвольная. Отступы и интервалы могут использоваться для пояснения структуры и содержания сценария. Кроме того, вам рекомендуется использовать стандартный стиль написания сценариев, чтобы сделать сценарии более удобочитаемыми. См. Руководство по стилю для получения дополнительной информации.
2. Заголовки
Непосредственно перед телом сценария каждый сценарий должен иметь заголовок, определяющий его назначение и другие атрибуты. Заголовок может содержать название сценария, имя автора, дату, версию, имя файла и дополнительную информацию. Файлы данных REBOL, которые не предназначены для прямой оценки, не требуют заголовка.
Заголовки полезны по нескольким причинам.
- Они идентифицируют сценарий как действительный исходный текст пригодный для интерпретации REBOL.
- Интерпретатор использует заголовок, чтобы распечатать заголовок сценария и определить, какие ресурсы и версии ему необходимы, прежде чем оценивать сценарий.
- Заголовки предоставляют стандартный способ сообщить название, смысл программы, автора и другие детали. Часто по заголовку сценария можно определить, интересен ли он вам.
- Архивы сценариев и веб-сайты используют заголовки для создания каталогов сценариев, категорий и перекрёстных ссылок.
- Некоторые текстовые редакторы получают доступ и обновляют заголовок скрипта, чтобы отслеживать такую информацию, как автор, дата, версия и история.
Общая форма заголовка скрипта:
REBOL [block]
Чтобы интерпретатор мог распознать заголовок, блок должен сразу следовать за словом REBOL . Между словом REBOL и блоком разрешены только пробелы (пробелы, табуляции и строки).
Блок, следующий за словом REBOL, представляет собой определение объекта, описывающего сценарий. Предпочтительный минимальный заголовок:
REBOL [
Title: "Сканер Web сайтов"
Date: 2-Feb-2000
File: %webscan.r
Author: "Jane Doer"
Version: 1.2.3
]
Когда скрипт загружается, блок заголовка оценивается, и его словам присваиваются определённые значения. Эти значения используются интерпретатором, а также могут использоваться самим сценарием.
Обратите внимание, что слова, определённые как одно значение, также можно определить как несколько значений, предоставив их в блоке:
REBOL [
Title: "Сканер Web сайтов"
Date: 12-Nov-1997
Author: ["Ema User" "Wasa Writer"]
]
Заголовки могут быть более сложными, предоставляя информацию об авторе, авторских правах, форматировании, требованиях к версии, истории изменений и многом другом. Поскольку блок используется для создания объекта заголовка, он также может быть расширен новой информацией. Это означает, что сценарий может расширять заголовок по мере необходимости, но это следует делать с осторожностью, чтобы избежать неоднозначной или избыточной информации.
Полный заголовок может выглядеть примерно так:
REBOL [
Title: "Full REBOL Header Example"
Date: 8-Sep-1999
Name: 'Full-Header ; For window title bar
Version: 1.1.1
File: %headfull.r
Home: http://www.rebol.com/rebex/
Author: "Carl Sassenrath"
Owner: "REBOL Headquarters"
Rights: "Copyright (C) Carl Sassenrath 1999"
Needs: [2.0 ODBC]
Tabs: 4
Purpose: {
The purpose or general reason for the program
should go here.
}
Note: {
An important comment or notes about the program
can go here.
}
History: [
0.1.0 [5-Sep-1999 "Created this example" "Carl"]
0.1.1 [8-Sep-1999 {Moved the header up, changed
comment on extending the header, added
advanced user comment.} "Carl"]
]
Language: 'English
]
Предисловие сценария
Текст сценария не обязательно должен начинаться с заголовка. Скрипты могут начинаться с любого текста, что позволяет вставлять их в сообщения электронной почты, веб-страницы и другие файлы.
Заголовок отмечает начало сценария, а текст, который следует за ним, является телом сценария. Текст, который появляется перед заголовком, называется предисловием и игнорируется во время оценки.
Текст, который появляется перед заголовком, игнорируется.
от REBOL и может использоваться для комментариев, заголовков писем,
HTML-теги и т.д.
REBOL [
Title: "Пример предисловия"
Date: 8-Jul-1999
]
print "Перед заголовком этого файла есть предисловие."
Встраивание скриптов в текст
Если за сценарием должен следовать другой текст, не связанный с самим сценарием, сценарий должен быть заключён в квадратные скобки []:
Какой-то текст перед сценарием.
[
REBOL [
Title: "Встроенный сценарий"
Date: 8-Nov-1997
]
print "done"
]
Какой-то текст после сценария.
Между начальной скобкой и словом REBOL допускается только пробел.
3. Аргументы скрипта
Когда сценарий оценивается/выполняется, он имеет доступ к информации о себе. Он находится в объекте system/script. Объект содержит поля, перечисленные в полях объекта для system/script.
Заголовок
Родитель
Путь
Args
| | Header(Заголовок) | Объект заголовка скрипта. Это может быть использовано для доступа к заголовку скрипта, автору, версии, дате и другим полям.
|
| | Parent(Родитель) | Если сценарий был оценён/запущен из другого сценария, это объект system/script от родительского сценария.
|
| | Path(Путь) | Путь к каталогу файла или URL-адрес оцениваемого сценария.
|
| | Args(Аргументы) | Аргументы сценария. Они передаются из командной строки операционной системы или из функции do, которая использовалась для оценки/запуска скрипта.
|
Примеры использования объекта скрипта:
print system/script/title
print system/script/header/date
do system/script/args
do system/script/path/script.r
В последнем примере оценивается сценарий с именем script.r в том же каталоге, что и сценарий, который выполняется в данный момент.
3.1 Опции программы
Главная Путь к файлу определяется средой вашей операционной системы. Это путь, заданный вПеременная среды HOME или системный реестр для систем, которые ее поддерживают. Это путь, по которомуrebol.r и user.r файлы.
Сценарий Имя файла исходного сценария, предоставленное при запуске интерпретатора.
Путь Путь к текущему каталогу.
Args Первоначальные аргументы, предоставляемые интерпретатору в командной строке.
Do-arg С
system / options
Сценарии также имеют доступ к параметрам, предоставленным интерпретатору REBOL при его запуске. Они находятся в объекте system/options. Объект содержит поля, перечисленные в полях объекта для system/options.
| | Home | Путь к файлу определяется вашей операционной системой. Это путь, заданный в переменной среды HOME или системный реестр для систем, которые его поддерживают. Это путь, по которому rebol.r и user.r файлы. |
| | Script | Имя файла исходного сценария, указанного при запуске интерпретатора.
|
| | Path | Путь текущего каталога.
|
| | Args | Первоначальные аргументы, указанные интерпретатору в командной строке.
|
| | Do-arg | Строка, предоставленная в качестве аргумента для параметр --do в командной строке.
|
Объект system/options object также содержит дополнительные параметры, которые были предоставлены в командной строке. Тип
probe system/options
для проверки содержимого объекта параметров.
Примеры:
print system/options/script
probe system/options/args
print read system/options/home/user.r
4. Запуск сценариев
Есть два способа запустить сценарий: в качестве исходного сценария, указанного в командной строке, в виде аргумента, при запуске интерпретатора REBOL или из функции do.
Чтобы запустить сценарий при запуске интерпретатора, укажите имя сценария в командной строке после имени программы REBOL:
rebol script.r
Как только интерпретатор инициализируется, выполняется оценка сценария.
В функции do укажите имя файла сценария или URL-адрес в качестве аргумента. Файл загружается в интерпретатор и оценивается:
do %script.r
do http://www.rebol.com/script.r
Функция do возвращает результат скрипта, когда он завершает оценку.
Обратите внимание, что файл сценария должен включать допустимый заголовок REBOL.
4.1 Загрузка скриптов
Файлы сценариев могут быть загружены как данные с помощью функции load. Эта функция читает сценарий и переводит его в значения, слова и блоки, но не оценивает (не запускает) сценарий. Результатом функции load является блок, если было загружено только одно значение, тогда это значение возвращается.
Аргументом для функции load является имя файла, URL-адрес или строка.
load %script.r
load %datafile.txt
load http://www.rebol.org/script.r
load "print now"
Функция load выполняет следующие шаги:
- Читает текст из файла, URL-адреса или строки.
- Ищет заголовок скрипта, если он есть.
- Переводит данные, начинающиеся после заголовка, если они найдены.
- Возвращает блок, содержащий переведённые значения.
Например, если файл скрипта buy.r содержал текст:
Buy 100 shares at $20.00 per share
он может быть загружен строкой:
data: load %buy.r
что приведёт к формированию в переменной data блока:
probe data
[Buy 100 shares at $20.00 per share]
Следует отметить, что приведённый выше пример «Buy» - это диалект REBOL, а не непосредственно исполняемый код. См. Главу 4 о выражениях или главу 15 о синтаксическом анализе для получения дополнительной информации.
Обратите внимание, что файл не требует загрузки заголовка. Заголовок необходим только в том случае, если файл будет запускаться как сценарий.
Функция load поддерживает несколько уточнений (дополнительных параметров). В разделе «Усовершенствования функций загрузки» перечислены уточнения и описание их функций:
| | /header | Включает заголовок, если он есть.
|
| | /next | Загружает только следующее значение, по одному за раз. Это полезно для разбора скриптов REBOL.
|
| | /markup | Обрабатывает файл как файл HTML или XML и возвращает блок, содержащий его теги и текст.
|
Обычно load не возвращает заголовок из сценария. Но, если используется уточнение /header, возвращаемый блок содержит объект заголовка в качестве первого аргумента.
Уточнение /next загружает следующее значение и возвращает
блок, содержащий два значения. Первое возвращаемое значение-это следующее значение из
серии. Второе возвращаемое значение-это позиция строки, следующая сразу
за последним загруженным элементом.
Уточнение /markup позволяет загрузить HTML и данные XML как блок тегов и строк. Все теги являются типами данных тегов. Все остальные данные обрабатываются как строки.
Если следующее содержимое файла загружено с load/markup:
<title>Это пример</title>
будет создан блок:
probe data
[<title> "Это пример" </title>]
4.2 Сохранение скриптов
Данные могут быть сохранены в файл сценария в формате, который можно загрузить в REBOL с помощью функции load. Это полезный способ сохранения значений данных и блоков данных. Таким образом можно создавать целые мини-базы данных.
Функция save ожидает два аргумента: имя файла и либо блок, либо значение для сохранения:
data: [Buy 100 shares at $20.00 per share]
save %data.r data
Данные записываются в формате исходного текста REBOL, который можно загрузить позже с помощью:
data: load %data.r
Также можно сохранять и загружать простые значения. Например, отметку даты можно сохранить с помощью:
save %date.r now
а затем перезагружен:
stamp: load %date.r
В предыдущем примере, поскольку stamp является единственным значением, при загрузке оно не заключено в блок.
Чтобы сохранить файл сценария с заголовком, заголовок может быть предоставлен в уточнении как объект или блок:
header: [Title: "Это пример"]
save/header %data.r data header
4.3 Комментирование скриптов
Комментирование полезно для пояснения назначения разделов скрипта. Заголовки сценария содержат высокоуровневое описание сценария, а комментарии содержат краткое описание функций. Также рекомендуется комментировать другие части кода.
Однострочный комментарий записывается после точки с запятой. Все, что стоит после точки с запятой и до конца строки, является комментарием, который полностью игнорируется интерпретатором:
zertplex: 10 ; установили значение на высшее качество
Вы также можете использовать несколько строк для комментариев. Например, вы можете создавать многострочные комментарии со строками, заключёнными в фигурные скобки:
{
Это длинный
при длинный
многострочный
комментарий.
}
Этот метод комментирования работает только в том случае, если строка не интерпретируется как аргумент функции. Если вы хотите быть уверенным в том, что многострочный комментарий распознаётся как комментарий и не интерпретируется как код, поставьте перед строкой слово comment:
comment {
Это длинный
при длинный
многострочный
комментарий.
}
Функция comment сообщает REBOL игнорировать следующий блок или строку. Обратите внимание, что строковые и блочные комментарии фактически являются частью блока скрипта. Следует проявлять осторожность, чтобы не помещать их в блоки данных, поскольку они могут появиться как часть данных.
5. Руководство по стилю
Скрипты REBOL имеют произвольную форму. Вы можете написать сценарий, используя отступы, интервалы, длину строки и терминаторы строки, которые вы предпочитаете. Вы можете поместить каждое слово в отдельную строку или объединить их в одну длинную строку.
Хотя форматирование вашего скрипта не влияет на интерпретатор, оно влияет на его удобочитаемость. По этой причине REBOL Technologies рекомендует вам следовать стандартному стилю сценариев, описанному в этом разделе.
Конечно, вам не обязательно следовать ни одному из этих предложений. Однако стиль написания сценариев важнее, чем кажется на первый взгляд. Это может иметь большое значение для удобочитаемости и повторного использования скриптов. Пользователи могут судить о качестве ваших скриптов по ясности их стиля. Неряшливые сценарии часто означают небрежный код. Опытные авторы сценариев обычно обнаруживают, что чистый, последовательный стиль облегчает создание, поддержку и исправление их кода.
5.1 Форматирование
Для ясности используйте следующие рекомендации по форматированию скриптов REBOL.
5.1.1 Отступ содержания для ясности
Содержимое блока имеет отступ, а квадратные скобки блока [] - нет. Это потому, что квадратные скобки относятся к предыдущему уровню синтаксиса, поскольку они определяют блок, но не являются его содержимым. Кроме того, легче заметить разрывы между соседними блоками, когда скобки выступают наружу.
По возможности открывающая квадратная скобка остается на строке со связанным с ней выражением. За закрывающей скобкой могут следовать другие выражения того же уровня. Эти же правила в равной степени применяются к круглым скобкам () и фигурным скобкам {}.
if check [сделайте то и то]
if check [
сделай это и сделай то
сделать другое дело
сделай еще несколько операций
]
either check [сделайте что-нибудь короткое][
сделай что-нибудь другое]
either check [
когда выражение расширяется
после конца блока ...
][
это помогает сохранить
читаемость и наглядность.
]
while [
сделай более длинное выражение
чтобы увидеть,
правда ли это
][
конец последнего блока
и начало нового
находятся на одном уровне
и это визуально их разделяет
между собой продолжая указывать
на то, что они оба относятся
к функции while
]
adder: func [
"Это пример функции"
arg1 "это первый аргумент"
arg2 "это второй аргумент"
][
arg1 + arg2
]
Исключение делается для выражений, которые обычно принадлежат одной строке, но распространяются на несколько строк:
if (это длинное условное выражение, которое
делится на несколько строк и имеет отступ
)[
так что это выглядит немного странно
]
Это также относится к сгруппированным значениям, которые принадлежат друг другу, но должны быть заключены в оболочку, чтобы поместиться в строке:
[
"Hitachi Precision Focus" $1000 10-Jul-1999
"Computers Are Us"
"Nuform Natural Keyboard" $70 20-Jul-1999
"The Keyboard Store"
]
5.1.2 Стандартный размер отступа (табуляции)
Стандартный размер табуляции REBOL - четыре пробела. Поскольку люди используют разные редакторы и читатели для сценариев, вы можете использовать пробелы, а не клавишу табуляции.
5.1.3 "Детаб" перед публикацией
Символ табуляции (ASCII 9) не делает отступ строго в четыре пробела во многих программах просмотра, браузерах или оболочках, поэтому используйте редактор или REBOL, чтобы заменить символы табуляции на пробелы перед его публикацией в сети. Следующая функция заменяет в файле символы табуляции на четыре пробела:
detab-file: func [file-name [file!]] [
write file-name detab read file-name
]
detab-file %script.r
Следующая функция преобразует табуляцию с восемью пробелами в табуляцию с четырьмя пробелами:
detab-file: func [file-name [file!]] [
write file-name detab entab/size read file-name 8
]
5.1.4 Ограничение длины строки до 80 символов.
Для удобства чтения и редактирования в разных пограммах рекомендуется ограничивать длину строки до 80 символов. Длинные строки, уходящие за край экрана, трудно и неудобно читать.
5.2 Имена слов
Слова - это первое знакомство пользователя с вашим кодом, поэтому очень важно тщательно выбирать слова. Сценарий должен быть чётким и лаконичным. По возможности, слова должны относиться к своему английскому или другому эквиваленту на человеческом языке простым и прямым образом.
Ниже приведены стандартные соглашения об именах для REBOL.
5.2.1 Используйте самое короткое слово, передающее смысл
По возможности лучше всего подходят короткие, чёткие слова:
size time send wait make quit
Локальные имена переменных часто можно сократить до одного слова. Более длинные и описательные слова лучше подходят для глобальных переменных.
5.2.2 По возможности используйте целые слова
То, что вы экономите при сокращении слов, редко того стоит. Лучше введите слово "дата_файла" полностью, а не "дф" или "файл_с_изображением", а не "фи". Это очень поможет при работе с исходным кодом вашего сценария.
5.2.3 Расстановка нескольких слов через дефис
Стандартный стиль - использовать дефисы или "нижний дефис" (символ подчёркивания), а не регистр символов, чтобы различать слова.
group-name image-file clear-screen bake-cake
файл_изображения очистка_экрана общая_сумма
5.2.4 Начинайте имена функций с глагола
Имена функций начинаются с глагола, а за ними следует существительное, наречие или прилагательное. Некоторые существительные также могут использоваться как глаголы.
make print scan find show hide take
rake-coals find-age clear-screen
Избегайте лишних слов. Смысл слова "выход" также понятен, как и "выход-из-программы".
При использовании существительного в качестве глагола используйте специальные символы, например? где применимо. Например, функция для получения длины серии - это длина?. Другие функции REBOL, использующие это соглашение об именах:
size? dir? time? modified?
5.2.5 Начинайте слова данных с существительных
Слова для объектов или переменных, содержащих данные, должны начинаться с существительного. При необходимости они могут включать модификаторы (прилагательные):
image sound big-file image-files start-time
5.2.6 Использование стандартных имён
В REBOL есть стандартные имена, которые следует использовать для аналогичных типов операций. Например:
make-blub ;создание чего-то нового
free-blub ;высвобождение ресурсов чего-то
copy-blub ;копирование содержимого чего-либо
to-blub ;преобразование во что-то
insert-blub ;вставка чего-то
remove-blub ;удаление чего-то
clear-blub ;очистка чего-то
5.3 Заголовки скрипта
Преимущество использования заголовков очевидно. Заголовки предоставляют пользователям сводку сценария и позволяют другим сценариям обрабатывать информацию (например, сценарий каталогизации). Минимальный заголовок содержит заголовок, дату, имя файла и цель. Также могут быть предоставлены другие поля, такие как автор, примечания, использование и потребности/зависимости.
REBOL [
Title: "Local Area Defringer"
Date: 1-Jun-1957
File: %defringe.r
Purpose: {
Stabilize the wide area ignition transcriber
using a double ganged defringing algorithm.
}
]
5.4 Заголовки функций
Полезно предоставить описание в блоках спецификации функций. Ограничьте такой текст одной строкой из 70 символов или меньше. В описании укажите, какой тип значения обычно возвращает функция.
набор: func [
"Вернуть стоимость набора текста"
size "Размер рукописного текста"
time "Время выполнения набора"
/cost num "Максимальная стоимость"
/compound "Составной расчёт"
][
...код функции...
]
5.5 Имена файлов сценариев
Лучший способ дать файлу имя - подумать о том, как лучше всего найти этот файл через несколько месяцев. Часто бывает достаточно коротких и понятных имён. Следует избегать множественного числа, если оно не имеет смысла.
Кроме того, при присвоении имени сценарию следует учитывать, как имя будет отсортировано в каталоге. Например, объедините связанные файлы, начав их с общего слова.
%net-start.r
%net-stop.r
%net-run.r
5.6 Встроенные примеры
При необходимости предоставьте примеры в сценарии, чтобы показать, как работает сценарий, и дать пользователям быстрый способ проверить правильность работы сценария в их системе.
5.7 Встроенная отладка
Часто бывает полезно встроить функции отладки как часть сценария. Это особенно верно в отношении сетевых сценариев и сценариев обработки файлов, в которых нежелательно отправлять и записывать файлы во время работы в тестовом режиме. Такие тесты можно включить с помощью контрольной переменной вначале скрипта.
отладка: вкл
check-data: off
5.8 Свернуть глобальные объекты
В больших скриптах и по возможности избегайте использования глобальных переменных, которые передают своё внутреннее состояние от одного модуля или функции к другому. Для коротких сценариев это не всегда практично. Но помните, что короткие сценарии со временем могут стать более длинными.
Если у вас есть набор глобальных переменных, которые тесно связаны между собой, рассмотрите возможность использования объекта для их представления:
пользователь: make object! [
имя: "Fred Dref"
возраст: 94
телефон: 707-555-1234
почта: dref@fred.dom
]
6. Очистка скрипта
Вот короткий скрипт, который можно использовать для очистки отступов скрипта. Он работает, анализируя синтаксис REBOL и реконструируя каждую строку скрипта. Этот пример можно найти в библиотеке сценариев REBOL на сайте www.REBOL.com.
out: none ; вывод текста через
spaced: off ; добавить дополнительный отступ
indent: "" ; содержит вкладки с отступом
emit-line: func [] [append out newline]
emit-space: func [pos] [
append out either newline = last out [indent] [
pick [#" " ""] found? any [
spaced
not any [find "[(" last out
find ")]" first pos]
]
]
]
emit: func [from to] [
emit-space from append out copy/part from to
]
clean-script: func [
"Возвращает новый текст скрипта со стандартным интервалом."
script "Исходный текст сценария"
/spacey "Необязательные пробелы возле скобок"
/local str new
] [
spaced: found? spacey
out: append clear copy script newline
parse script blk-rule: [
some [
str:
newline (emit-line) |
#";" [thru newline | to end] new:
(emit str new) |
[#"[" | #"("]
(emit str 1 append indent tab)
blk-rule |
[#"]" | #")"]
(remove indent emit str 1) |
skip (set [value new]
load/next str emit str new) :new
]
]
remove out ; remove first char
]
script: clean-script read %script.r
write %new-script.r script
|