Смекни!
smekni.com

Программирование и разработка приложений в Maple (стр. 119 из 135)

Если используется полный путь к каталогу, то он начинается с УВВ, в противном случае создаваемый каталог будет расположен в текущем каталоге пакета, который определяется по вызову iolib-функции currentdir(), например:

> currentdir(); ⇒ "C:\Program Files\Maple 10"

> mkdir("UserLib"); currentdir("UserLib"); currentdir();

"C:\Program Files\Maple 10\UserLib1"

Первый пример фрагмента определяет текущий каталог пакета (как правило, это основной каталог пакета), тогда как второй пример иллюстрирует создание в нем нового каталога UserLib под создаваемую библиотеку, определение его текущим и проверку нового текущего каталога. Под текущей понимается цепочка подкаталогов, с которой работают средства доступа пакета по умолчанию, т.е. в случае указания только имени файла. По вызову currentdir() возвращается значение текущей цепочки, тогда как по вызову вида currentdir(<цепочка>) устанавливается указанная цепочка в качестве текущей.

При установке новой текущей цепочки подкаталогов функция currentdir возвращает предыдущее значение для текущей цепочки, что позволяет при необходимости легко возвращаться к предыдущему значению. При этом, следует иметь в виду, что установка текущей цепочки отменяется только перезагрузкой пакета или ее переопределением. Более того, установленный по currentdir-функции каталог становится текущим только для внешних файлов пакета, т.е. эта функция используется со средствами доступа к внешним файлам данных пакета.

Между тем, по mkdir-функции мы имеем возможность создавать цепочки каталогов только одного уровня вложенности либо только один каталог, находящийся в конце уже существующей цепочки каталогов, иначе возникает ошибочная ситуация, например:

> mkdir("C:&bsol;Program Files&bsol;Maple 8&bsol;UserLib1/Dir1/Dir2");

Error, (in mkdir) file or directory does not exist

Это является весьма существенным ограничением в задачах, имеющих дело с доступом к элементам файловой системы компьютера. Для устранения данного недостатка нами была создана процедура MkDir [103], рассмотренная выше Процедура MkDir(dirName) создает каталог, цепочку каталогов и/ или файл данных в файловой системе базовой операционной среды. Аргумент dirName типа {string, symbol} определяет цепочку каталогов, которая должна быть создана. Процедура MkDir допускает кодирование фактического аргумента dirName строкой или символом следующего вида:

Устройство:&bsol;Каталог/Подкаталог_1&bsol;…/Подкаталог_n

Набор символов, допускаемых в названиях каталогов, является системо-зависимым, также как и символ, используемый для разделения компонент цепочки каталогов. Так, если в качестве разделителя используется обратный слэш (backslash), то он должен удваиваться, т. к. строки Maple используют этот символ в качестве управляющего (escape).

Создав по встроенной функции mkdir или по нашей процедуре MkDir каталог под создаваемую библиотеку (в нашем примере каталог "с:/program files/maple 10/UserLib"), теперь мы можем в нем создать «пустую» библиотеку с именем UserLib. Делается это по вызову следующего формата кодирования: march('create', "C:&bsol;Program Files&bsol;Maple 10&bsol;UserLib", <Размер>)

где аргумент <Размер> определяет размер создаваемой библиотеки. Размер библиотеки определяется количеством содержащихся в ней m-файлов с Maple-объектами (процедуры, модули, таблицы и т.д.). При этом, практически, имеется возможность сохранения в такой библиотеке числа m-файлов, примерно равного удвоенному числу, заданному во втором фактическом аргументе. О m-файлах речь шла выше. Таким образом, по вызову следующего формата кодирования: march('create', "C:&bsol;Program Files&bsol;Maple 10&bsol;UserLib", 350)

мы создаем пустую библиотеку UserLib, предназначенную для сохранения порядка 700 различных Maple-объектов (процедуры, модули, таблицы и т.д.).

В библиотеке создаются два макетных файла “Maple.ind” (индексный) и “Maple.lib” (с mфайлами Maple-объектов), впоследствии обновляемые при каждом помещении в библиотеку новых Maple-объектов либо при ее реорганизации средствами той же march-функции. В данной ситуации библиотека готова к своему наполнению программными средствами – процедурами, модулями и другими Maple-объектами, например, таблицами.

Этап 2. На данном этапе необходимо в текущем сеансе вычислить определения Mapleобъектов, помещаемых в библиотеку, например:

> Sr:= () -> `+`(args)/nargs; Ds:= () -> sqrt(sum((args[k] - Sr(args))^2, k = 1..nargs)/nargs);

`+`(args)

Sr := ( ) →

nargs

∑ (argsk − Sr args( ))

Теперь две процедуры Sr и Ds готовы для включения в созданную библиотеку UserLib.

Этап 3. Для определения пути к библиотеке, принимающей Maple-объекты, служит глобальная переменная savelibname, первоначально имеющая неопределенное значение. Для указания пути к библиотеке данной переменной присваивается полный путь к ней. Можно ограничиться и просто именем библиотеки, если она находится в текущем каталоге, однако первый способ более универсален, например, для нашего случая имеем: > savelibname; savelibname:= "C:&bsol;Program Files&bsol;Maple 10&bsol;UserLib": savelibname; savelibname

"C:&bsol;Program Files&bsol;Maple 10&bsol;UserLib"

Этап 4. На этом этапе производится непосредственно сохранение в библиотеке подготовленных выше процедур. Делается это вызовом процедуры savelib, имеющей формат вызова следующего вида:

savelib(N1, N2, ...)

где Nj – имена сохраняемых в библиотеке Maple-объектов. Для нашего примера будет:

> savelib(Sr, Ds);

Процедура возвращает NULL-значение, т.е. ничего, и для проверки результата сохранения рекомендуется использовать еще один формат вызова march-функции, а именно: march('list', <Путь к библиотеке>)

по которому возвращается список всех сохраненных в библиотеке, указанной вторым аргументом, Maple-объектов, точнее соответствующих им m-файлов, например:

> march('list', "C:&bsol;Program Files&bsol;Maple 10&bsol;UserLib");

[["Ds.m", [2006, 10, 2, 10, 24, 18], 1090, 115], ["Sr.m", [2006, 10, 2, 10, 24, 18], 1024, 66]]

Возвращаемый вложенный список содержит по одному подсписку для каждого содержащегося в библиотеке m-файла (первый элемент в виде "FileName.m"), второй содержит список с датой и временем создания файла, тогда как третий и четвертый указывает начальную позицию данного файла (точнее его смещение) в библиотечном файле “Maple.lib” и его размер в байтах соответственно. Результат проверки показывает, что наши две процедуры были сохранены успешно.

Этап 5. На данном этапе производится логическое подключение созданной библиотеки к основной библиотеке пакета, что позволит впредь обращаться к находящимся в ней объектам подобно стандартным средствам пакета Maple. Для этих целей служит предопределенная переменная libname, определяющая последовательность путей к библиотекам пакета, в которых будут отыскиваться вызываемые средства, если они не были определены и вычислены непосредствено в текущем сеансе. Для нашего случая текущее состояние libname-переменной есть:

> libname; ⇒ "c:/program files/maple 10/lib/userlib", "C:&bsol;Program Files&bsol;Maple 10/lib" определяющее, что пакет располагает логически сцепленной с главной Maple-библиотекой "c:&bsol;program files/maple 10/lib" библиотекой "c:/program files/maple 10/lib/userlib", имеющей высший приоритет. Приоритет определяется местоположением библиотеки в libname-цепочке – чем ближе она к началу, тем выше ее приоритет, определяющий порядок поиска библиотечных средств при их вызове: поиск производится, начиная в библиотеке с самым высоким приоритетом. Для подключения созданной нами библиотеки требуется переопределить значение libname-переменной, а именно:

> restart: libname:= libname, "C:&bsol;Program Files&bsol;Maple 10&bsol;UserLib": libname;

"C:&bsol;Program Files&bsol;Maple 10/lib", "C:&bsol;Program Files&bsol;Maple 10&bsol;Lib/UserLib"

В результате переопределения наша библиотека UserLib получила наименьший приоритет. Именно так и следует поступать при создании новых библиотек пока не проведена их детальная апробация в совокупности с другими сцепленными библиотеками пакета. Теперь мы можем реально проверить доступность нашей библиотеки и находящихся в ней средств, а именно:

> 6*Sr(64, 59, 39, 10, 17, 44), 6*Ds(64, 59, 39, 10, 17, 44); ⇒ 233, 14249

Из примера следует, что созданная библиотека (в рамках ее процедур Sr и Ds) функционирует корректно. Однако, здесь есть одно но. При переопределении libname-переменной мы предварительно выполнили restart-предложение, чтобы деактивировать в текущем сеансе ранее вычисленные определения процедур Sr и Ds, сохраняемых в библиотеке. Именно такой прием позволяет нам убедиться, что после переопределения libname-переменной мы будем иметь дело именно с библиотечными процедурами Sr и Ds. Между тем, при такой организации мы должны будем каждый раз перед вызовом средств из UserLib-библиотеки выполнять вышеуказанное переопределение libname-переменной, что, естественно, неудобно.

Во избежание этого рекомендуется поступить следующим образом. Maple допускает ряд инициализационных файлов (ini-файлов), из которых файл “Maplen.ini” создается уже при инсталляции пакета в его USERS-подкаталоге, где n – номер релиза пакета. В этот же подкаталог рекомендуется любым доступным средством (например, по Notepad) записать файл “Maple.ini” с единственной строкой следующего содержания: libname := libname, "C:/Program Files/Maple 10/UserLib":

или дополнить файл этой строкой, если он уже существовал. Данный подход обеспечит вам автоматическое подключение вашей библиотеки к главной Maple-библиотеке после каждой загрузки пакета. В результате реализации описанных этапов создана библиотека пользователя UserLib, средства которой становятся доступными наравне со стандартными при каждой загрузке пакета Maple.

При этом, подкаталог USERS предполагается по умолчанию, но данная установка может быть пересмотрена при инсталляции. Следующая таблица определяет целесообразное расположение файла "Maple.ini" в каталогах пакета, где: B – BIN, L – LIB и U – USERS,