Всем привет. Сегодня я расскажу (и покажу) вам, как организована работа с файлами в Dyalog APL. Экспериментировать мы будем с «родной» файловой системой Dyalog — DCF; другие файлы в данной статье не рассматриваются.
Также будет затронута тема обработки исключений.
Все эксперименты будут проводиться на материале из последняя тема.
К сожалению, некоторые изображения плохого качества, прошу меня извинить, так как я не знаю хорошего хостинга изображений.
Итак, начнем.
Что такое DCF?
У Dyalog APL есть свой способ хранения информации — файлы-компоненты.Суть такова: файл представляет собой последовательность «ячеек» (компонентов), и в каждую из них можно записать значение только одной переменной.
Над файлом можно выполнять следующие операции: создавать, открывать, читать компонент, заменять компонент, прикреплять в конец новый компонент, закрывать и различные специальные операции, не рассмотренные в этой статье.
Попробуем открыть какой-нибудь файл:
И получаем ошибку, потому что файл не существует. Из этого «эксперимента» можно сделать два вывода:
— для открытия файла используется системная функция []FTIE. Его аргументами являются полное имя файла слева и специальный номер идентификатора файла (номер связи), который впоследствии используется для доступа к файлу;
— в окне интерпретатора выводятся сообщения об ошибках с указанием причины ошибки (в нашем случае это FILE NAME ERROR).
Забегая немного вперед, отмечу, что каждая ошибка имеет свой номер, который используется для перехвата этих самых ошибок.
Таким образом, файл не может быть открыт. Значит, нам нужно его создать! Для этого используйте системную функцию []FCREATE с теми же аргументами, что и у []FTIE.
Итак, теперь у нас есть файл test.dcf с идентификационным номером 1. По умолчанию (если не указать полный путь) файлы появляются на рабочем столе.
Созданные файлы не содержат компонентов, в чем можно убедиться с помощью системной функции []FSIZE, передав ей номер файла справа.
На данный момент нас интересует только второй элемент результата этой функции — он содержит номер следующего свободного компонента.
Поскольку для файла test.dcf это число равно 1, количество компонентов равно нулю.
Для заполнения файлов используется системная функция []FAPPEND, которой необходимо передать переменную или значение слева и номер файла справа.
Чтобы проверить, что информация действительно была записана, воспользуемся функцией []FREAD. Он принимает в качестве одного аргумента два значения — номер файла и номер компонента.
Чтобы закрыть файл, используйте функцию []FUNTIE с номером файла.
Чтобы убедиться, что связи с файлом больше нет, воспользуемся функцией nyladic []FNUMS, которая возвращает вектор номеров файлов.
Используя полученные знания, попробуем доработать программный код из предыдущего примера.
Немного практики
Внесем некоторые изменения в программу: 1. Запишем используемый в программе текст в файл и загрузим его при выполнении.2. Тексты функций запишем в другой файл и выполним их при загрузке рабочей области, а при выходе сохраним обратно в файл.
Сохранение и загрузка текста
Для начала напишем функцию, которая будет инициализировать текст программы — txtIni. Нам нужно: открыть файл, если файл не существует, то создать его и записать текст, прочитать текст в глобальную (для этой функции) переменную и закрыть файл.
Заголовок функции будет выглядеть так:
Функция принимает полное имя файла в качестве аргумента (fname).
Переменная Tien будет хранить номер файла.
При работе с файлами легко допустить ошибки, поэтому необходимо использовать инструменты обработки ошибок.
Для нашего примера подойдет конструкция :Trap :Else :EndTrap, которая по идеологии чем-то похожа на try-catch.
Конструкция :Trap 0 1000 определяет коды ошибок, которые следует перехватывать.
В данном случае это все системные события (0) и все пользовательские события (1000).
Также в этих границах вы можете определить обработку отдельных событий с помощью конструкций :Case и :CaseList. Обратите внимание на использование метки L1: — она используется для безусловного перехода после обработки исключения.
Остальное просто: если файл содержит компоненты, читаем первый в переменную txt, если нет — заполняем его текстом и записываем в файл.
Затем закройте файл.
Далее необходимо определить последовательность действий при возникновении ошибок.
На отсутствие файла пишем отдельный :Case, на остальные - :Else. Самое простое, что можно сделать в случае непредвиденных ошибок — закрыть все открытые файлы функцией []FUNTIE с аргументом []FNUMS, а затем выдать сообщение в окне интерпретатора с помощью функции []SIGNAL. Его аргументами являются текст сообщения справа и код ошибки слева.
В нашем примере будет достаточно использовать системные переменные []DM (текст) и []EN (код ошибки).
Если файла нет (или указано неправильно имя), этот файл создается и затем берется путь до метки.
Все очень просто!
Чтобы скачанный текст можно было использовать в программе, необходимо немного изменить функции приложения, добавив обращения к элементам вложенного вектора текста txt.
Аргумент в функции WhatNum удален, так как его значение (заголовок формы) теперь берется из файла.
Все символьные константы заменены путем доступа к элементам вектора txt с вызовом функции «Раскрыть», которая преобразует вложенный элемент вектора в вектор символов.
Изменения в функции checkNum такие же:
Скрытие кода
Теперь самое интересное: вы можете хранить переменные в файлах компонентов, но можете ли вы хранить функции? ДА! Для этого вам нужно всего лишь преобразовать функцию в текст и присвоить ее переменной, что и сделает функция saveFns. Преобразование происходит мгновенно: системная функция []CR (каноническое представление) с именем функции в качестве аргумента возвращает символьную матрицу с текстом.Но настоящая магия начинается с использования оператора «Каждый».
Таким образом, вся переменная содержит три текста наших функций, и каждый текст представляет собой символьную матрицу, представленную в виде скаляра (ранг равен 0)!
Ниже приводится уже описанная процедура записи в файл.
В конце добавим вызов системной функции []EX, которая будет удалять ненужные объекты из рабочей области.
Теперь осталось написать код инициализации, который будет выполняться при загрузке рабочей области.
Последовательность действий следующая: открытие файла, чтение, закрытие файла.
Тогда магия APL снова начинает работать: легким движением руки все вектор превращается в полноценные функции рабочего пространства! После загрузки функций можно вызвать WhatNum и убедиться, что все работает.
Большой.
Остается только сохранить наши функции в файл, изменить содержимое системной переменной []LX и сохранить рабочую область.
После этого в рабочей области останутся только функции для работы с файлами и будет загружен код приложения.
Для запуска программы достаточно открыть файл рабочей области, и если все сделано правильно, на экране появится окно приложения.
Общий
Сегодня вы увидели немного магии APL, а заодно узнали о таких важных вещах, как работа с файлами и обработка исключений.Продолжение следует. Теги: #APL #исключения #файлы #программирование
-
Yota — Сколько (Внутри)?
19 Oct, 24 -
Сми Нового Поколения
19 Oct, 24 -
Эволюция Зевса. Часть I
19 Oct, 24 -
Пожалуйста Помоги
19 Oct, 24