Библиотеки
Основную мощь экосистемы 1Script составляют готовые библиотеки, разрабатываемые сообществом. При разработке ваших собственных решений вы можете подключить к вашей программе те или иные готовые библиотеки и использовать их возможности.
Данные раздел описывает механику загрузки библиотек.
Готовые решения распространяются в виде пакетов
. Пакет это файл с расширением .ospx, который технически представляет собой zip-архив определенной структуры. Пакеты бывают двух видов:
- Приложения: конечные самостоятельные утилиты, которые запускаются непосредственно, как программы и выполняют свое предназначение.
- Библиотеки: повторно используемые компоненты, которые сами по себе не могут запускаться, а предназначены для использования сторонними приложениями
Внутреннее устройство библиотек и приложений практически не отличается и все, о чем пойдет далее речь, справедливо и для библиотек, и для приложений.
Устройство пакета
В общем случае, движок 1Script ничего не знает об устройстве библиотеки и никак не диктует внутреннее устройство пакета. Подключение сторонней библиотеки к вашему коду выполняется с помощью директивы препроцессора #Использовать
.
Эта директива указывается в самом начале модуля, до определения переменных.
// Подключаем библиотеку fs
#Использовать fs
// Модуль РаботаСФайлами предоставляется библиотекой fs.
// Мы можем использовать этот модуль привычным образом.
РаботаСФайлами.ОбеспечитьПустойКаталог("C:/devops/demo");
Как это работает? Почему система понимает, что означали буквы fs и как эти буквы превратить в общий модуль?
Все очень просто. Директива Использовать
имеет два варианта синтаксиса:
- Имя библиотеки указано без кавычек - выполняется поиск библиотеки в предопределенных, заранее известных системе каталогах.
#Использовать json // встроенный алгоритм поиска
- Имя библиотеки указано в кавычках - имя библиотеки интерпретируется, как обычный файловый путь. Относительный путь считается от каталога в котором лежит файл текущего скрипта.
#Использовать "lib/mylib" // явное указание пути к библиотеке
Сама библиотека является каталогом на диске. То есть, путь в директиве Использовать
всегда указывает на каталог.
Классы и модули
Библиотека может добавить в область видимости скрипта 2 вида сущностей: классы и модули. Каждая библиотека может включать в себя неограниченное количество классов и модулей.
Класс
Под классом понимается новый тип в системе типов приложения. Экземпляры объектов этого типа создаются через оператор Новый.
// подключаем функционал JSON
#Использовать json
Парсер = Новый ПарсерJSON(); // Тип ПарсерJSON объявлен в библиотеке
Модуль
Модуль это то же самое, что ОбщийМодуль в системе 1С:Предприятие. Модуль - это свойство в глобальном контексте, методы которого мы можем вызывать из языка.
// подключаем функционал JSON
#Использовать json
Студент = Новый Структура("Имя,Фамилия", "Иван", "Петров");
// Модуль "РаботаСJSON" объявлен в библиотеке и доступен благодаря директиве #Использовать
РаботаСJSON.ЗаписатьОбъект(Студент, "C:\students.json");
Каталог библиотек
Как система узнает, где же находятся каталоги с библиотеками, из которых можно подгружать внешний код? Все очень просто, система имеет настройки, которые сообщают ей о том, где находится каталог с библиотеками. Подробнее о возможных настройках см. раздел Конфигурация. В нашем случае, система прочитала настройку lib.system
из конфигурационного файла oscript.cfg
и узнала, где находится папка, в которой лежит библиотека fs.
Когда компилятор встречает в коде директиву #Использовать
он выполняет поиск указанного каталога библиотеки и запускает процедуру ее загрузки. При этом, алгоритм загрузки (знающий, как именно трактовать содержимое каталога библиотеки) может быть переопределен в специальном файле package-loader.os
, который расположен в корне хранилища библиотек.
Модуль загрузчика вызывается движком OneScript в момент начала загрузки библиотеки. Примерная аналогия - модуль документа в платформе 1С:Предприятие. Система вызывает метод "ПередЗаписью" и позволяет разработчику как-то управлять процессом записи в БД.
Иными словами, в движке существует объект "Загрузчик", который имеет скриптовый модуль, определяемый извне движка.
Алгоритм загрузки библиотек
Когда мы «используем» с помощью соответствующей инструкции какую-либо библиотеку, OneScript выполняет определенную последовательность действий.
Сначала интерпретатор в корневом каталоге библиотеки ищет и пытается выполнить специальный «волшебный» сценарий package-loader.os
– так называемый «загрузчик библиотек». Это специальный сценарий, который, как следует из его названия, занимается загрузкой библиотек – добавлением в область видимости классов и модулей, которые предоставляются библиотекой. В специальной процедуре-обработчике «ПриЗагрузкеБиблиотеки» среди параметров есть «СтандартнаяОбработка». Если в результате работы загрузчика она останется выставлена в «Истина» или файл package-loader.os в корне библиотеки вовсе отсутствует, то загрузка библиотеки переходит к следующему шагу.
Процедура ПриЗагрузкеБиблиотеки(Путь, СтандартнаяОбработка, Отказ)
Сообщить("Я - загрузчик библиотеки!");
СтандартнаяОбработка = Ложь;
ПутьКМодулю = ОбъединитьПути(ТекущийСценарий().Каталог, "Вычислитель.os");
// Именно эта строчка сделает доступным общий модуль Вычислитель
// и его код будет взят из файла, указанного в переменной ПутьКМодулю
ДобавитьМодуль(ПутьКМодулю, "Вычислитель");
КонецПроцедуры
На следующем шаге выполняется загрузчик «по умолчанию» - это такой же файл package-loader.os
, который располагается в «системном каталоге библиотек». Значение системного каталога библиотек берется из параметра lib.system
в файле oscript.cfg
, расположенного либо в каталоге с точкой входа в приложение (первоначально запускаемый сценарий, например my_project/script.os) либо в каталоге самого интерпретатора oscript.exe. В базовом варианте lib.system начинает вести в место установки OneScript, подкаталог lib.
Программный интерфейс загрузчика
Методы
ДобавитьКласс(Знач ИмяФайла, Знач Идентификатор)
Метод регистрирует новый тип в системе типов. В параметре "ИмяФайла" передается имя файла, реализующего класс, в параметре "Идентификатор" - имя класса, как он будет выглядеть в системе.
// файл package-loader.os
ДобавитьКласс("C:\moneygen.os", "ГенераторДенег");
// файл основного скрипта
Генератор = Новый ГенераторДенег;
Генератор.ДайДенег(100500);
ДобавитьМодуль(Знач ИмяФайла, Знач Идентификатор)
Метод регистрирует новый модуль в глобальном контексте. В параметре "ИмяФайла" передается имя файла, реализующего модуль, в параметре "Идентификатор" - имя модуля, как он будет выглядеть в системе.
// файл package-loader.os
ДобавитьМодуль("C:\worldcontrol.os", "УправлениеМиром");
// файл основного скрипта
УправлениеМиром.СделатьВсемХорошо(Истина);
События
ПриЗагрузкеБиблиотеки(Путь, СтандартнаяОбработка, Отказ)
Событие вызывается, когда система определила конкретный каталог библиотеки, перед попыткой загрузки этой библиотеки.
Параметры события:
- Путь - полный путь к каталогу загружаемой библиотеки.
- СтандартнаяОбработка - позволяет использовать встроенный алгоритм загрузки (см. ниже)
- Отказ - если обработчик события взводит флаг "Отказ", то генерируется ошибка "Библиотека не может быть загружена".
Стандартная обработка загрузки
Если обработчик не сбросил флаг стандартной обработки, то выполняется стандартный алгоритм загрузки:
- Находятся файлы в каталоге библиотеки с расширением .os;
- Если имя файла удовлетворяет правилам формирования идентификаторов он загружается, как модуль
- Имя модуля будет таким же, как имя файла
Таким образом, если библиотека содержит только общие модули, то достаточно назвать файлы, как они должны выглядеть в языке и разместить их в каталоге библиотеки.
Пакетирование библиотеки
Для публикации библиотеки каталог с исходными кодами должен содержать манифест проекта (файл packagedef).
В манифесте обязательно должны быть указаны:
- Имя пакета
- Версия пакета
- Состав пакета
Как правило, также указываются зависимости, которые надо установить вместе с пакетом. На примере ниже указаны зависимости от библиотек fs
и asserts
.
Описание.Имя("my-package")
.Версия("1.0.0")
.ВерсияСреды("2.0.0")
.ЗависитОт("fs", "1.0.0")
.ЗависитОт("asserts", "1.3.0")
.ВключитьФайл("packagedef")
.ВключитьФайл("src")
.ВключитьФайл("oscript_modules")
.ИсполняемыйФайл("src/my-script.os");
Свойства манифеста
- ВерсияСреды - минимально необходимая версия движка 1Скрипт, на которой будет работать пакет
- ЗависитОт - указание библиотеки, которую использует наш пакет и, опционально, минимальный номер ее версии
- ВключитьФайл - файл или каталог, который входит в состав пакета и будет включен в дистрибутив
- ИсполняемыйФайл - если мы разрабатываем не библиотеку, а самостоятельное приложение, то здесь указываем путь к точке входа
Информация
Полный перечень настроек манифеста содержится в документации к пакетному менеджеру opm.
Сборка пакета осуществляется командой (из каталога с манифестом)
opm build .
Если пакет необходимо опубликовать в хабе пакетов, то нужно выполнить предварительные организационные мероприятия, а затем запустить команду
opm push my-file.ospx --token ТОКЕН_ГИТХАБА