Смекни!
smekni.com

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

3 – удаление из библиотеки L объектов с именами, определяемыми фактическими аргументами, начиная с 3-го

4 – упаковка библиотеки L после удаления из нее ненужных объектов

5 – возврат списка объектов, содержащихся в библиотеке L

6 – создание пустой справочной базы для библиотеки L

7 – обновление справочной базы библиотеки L новой страницей (разделом); все аргументы при вызове процедуры должны иметь symbol-тип; обновление производится на основе mws-файла, находящегося по адресу, указанному четвертым фактическим аргументом, тогда как третий фактический аргумент определяет имя сохраняемой страницы 8 – удаление из справочной базы библиотеки L страницы (раздела), указанной третьим аргументом; этот аргумент при вызове процедуры должен иметь symbol-тип

9 – вывод на экран справки по странице (разделу) справочной базы библиотеки L с именем, определяемым третьим фактическим аргументом; при этом, производится логическое сцепление библиотеки L с главной Maple-библиотекой с наименьшим приоритетом первой 10 – создание логического сцепления библиотеки L с главной Maple-библиотекой; данное сцепление действует до переопределения libname-переменной, до restart-предложения либо до перезагрузки пакета. Вызов процедуры возвращает текущее состояние libnameпеременной пакета.

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

ulibrary := proc(O::{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, L::{string, symbol}) local a b c mkdir1, , , ; global libname; mkdir1 := proc(L::{string symbol, }) local a b c, , ; assign(a = "", b = ""), [seq(`if`(c = "\" or c = "/", assign(' 'a = cat(a, "","")), assign(' 'a = cat(a c, ))), c = cat "",( L))]; for c in parse cat(( "["", ,a ""]")) do b := cat(b c, , "\" ;) try mkdir(b)

catch "directory exists and is not empty": next catch "file I/O error": next catch "permission denied": next end try

end do

end proc ; if O = 1 then mkdir1 L( ); march '( create L', , `if`(nargs = 3 and type(args 3[ ], 'posint'), args 3[ ], 65)); WARNING "library <%1> has been created",( L) elif O = 2 then assign('savelibname' = L), savelib(

`if`(nargs = 2, ERROR("no names specified to save"), args 3 .. -1[ ])); WARNING("names %1 have been saved in library <%2>"[, args 3 .. -1[ ]], L) elif O = 3 then march('delete', L,

`if`(nargs = 2, ERROR("no names specified to delete"), args 3 .. -1[ ])); WARNING "names %1 have been deleted out of library <%2>,"(

[args 3 .. -1[ ]], L)

elif O = 4 then march('pack', L); WARNING("library <%1> has been packed", L) elif O = 5 then WARNING "content of library <%1> is:",( L); march '( list L', ) elif O = 6 then

WARNING("Help database for library <%1> has been created", L);

INTERFACE_HELP '( insert', topic = "UserLib", text = TEXT "The help ( &bsol; on my means located in UserLib. The library has been created 5.10.2&bsol;

006"), library = L) elif O = 7 then makehelp `if`( (nargs = 4 and map(type, {args 3 .. 4[ ]}, 'symbol') = {true}, args 3 .. 4[ ], ERROR "3rd and 4th arguments should have symbol-ty&bsol;(

pe and represent topic name and mws-file accordingly")), L);

WARNING( "topic <%1> had been added to the help database of library <%2>", args 3[ ], L)

elif O = 8 then INTERFACE_HELP '( delete topic', = `if`( nargs = 3 and type(args[3], 'symbol'), args[3], ERROR "topic specified to delete is missing")( ) , library = L) elif O = 9 then libname := libname L, ;

INTERFACE_HELP '( display topic', = `if`( nargs = 3 and type(args[3], 'symbol'), args[3],

ERROR "topic specified to display is missing"))( ) elif O = 10 then libname := libname L, ;

WARNING(

"library <%1> has been logically connected with main Maple-library", L)

;

libname

end if

end proc

> P:= () -> `+`(args)/nargs: P1:= () -> `*`(args): M:= module() export x; x:= () -> `+`(args) end module:

> ulibrary(1, `C:/AVZ/AGN&bsol;VSV/Art&bsol;Kr`);

Warning, library <C:/AVZ/AGN&bsol;VSV/Art&bsol;Kr> has been created

> ulibrary(2, `C:/AVZ/AGN&bsol;VSV/Art&bsol;Kr`); Error, (in ulibrary) no names specified to save

> ulibrary(2, `C:/AVZ/AGN&bsol;VSV/Art&bsol;Kr`, P, P1, M, Sv); Warning, names [P, P1, M, Sv] have been saved in library <C:/AVZ/AGN&bsol;VSV/Art&bsol;Kr> > ulibrary(5, `C:/AVZ/AGN&bsol;VSV/Art&bsol;Kr`);

Warning, content of library <C:/AVZ/AGN&bsol;VSV/Art&bsol;Kr> is:

[[":-1.m", %1, 1215, 75], ["P.m", %1, 1024, 65], ["P1.m", %1, 1089, 56], ["M.m", %1, 1145, 70]]

%1 := [2006, 10, 5, 10, 0, 44]

> ulibrary(3, `C:/AVZ/AGN&bsol;VSV/Art&bsol;Kr`, P, AVZ);

Warning, member "AVZ" not found in archive, skipping

Warning, names [P, AVZ] have been deleted out of library <C:/AVZ/AGN&bsol;VSV/Art&bsol;Kr>

> ulibrary(4, `C:/AVZ/AGN&bsol;VSV/Art&bsol;Kr`);

Warning, library <C:/AVZ/AGN&bsol;VSV/Art&bsol;Kr> has been packed > ulibrary(5, `C:/AVZ/AGN&bsol;VSV/Art&bsol;Kr`);

Warning, content of library <C:/AVZ/AGN&bsol;VSV/Art&bsol;Kr> is:

[[":-1.m", [2006, 10, 5, 10, 0, 44], 1024, 75], ["P1.m", [2006, 10, 5, 10, 0, 44], 1099, 56],

["M.m", [2006, 10, 5, 10, 0, 44], 1155, 70]]

> ulibrary(6, "C:/AVZ/AGN&bsol;VSV/Art&bsol;Kr");

Warning, Help database for library <C:/AVZ/AGN&bsol;VSV/Art&bsol;Kr> has been created

> ulibrary(7, `C:/AVZ/AGN&bsol;VSV/Art&bsol;Kr`, MKDIR,

`D:/Academy/UserLib6789/Common/HelpBase/MkDir.mws`);

Warning, topic <MKDIR> had been added to the help database of library

<C:/AVZ/AGN&bsol;VSV/Art&bsol;Kr>

> ulibrary(9, `C:/AVZ/AGN&bsol;VSV/Art&bsol;Kr`, P1); Error, Could not find any help on "P1"

> ulibrary(9, `C:/AVZ/AGN&bsol;VSV/Art&bsol;Kr`, MKDIR); # Вывод справки по MKDIR на экран

> ulibrary(8, `C:/AVZ/AGN&bsol;VSV/Art&bsol;Kr`, MKDIR); > ulibrary(9, `C:/AVZ/AGN&bsol;VSV/Art&bsol;Kr`, MKDIR); Error, Could not find any help on "MKDIR"

> ulibrary(10, `C:/AVZ/AGN&bsol;VSV/Art&bsol;Kr`);

Warning, library <C:/AVZ/AGN&bsol;VSV/Art&bsol;Kr> has been logically connected with main Maple-library

"c:/program files/maple 8/lib/userlib", "C:&bsol;Program Files&bsol;Maple 8/lib", "C:/AVZ/AGN&bsol;VSV/Art&bsol;Kr"

Между тем, процедура не обеспечена развитой системой обработки ошибочных ситуаций, что требует от пользователя внимательности при кодировании фактических аргументов при ее вызове. Сделано это было в целях упрощения алгоритма процедуры и его большей прозрачности в учебных целях. В то же время данная процедура представляет достаточно простое и эффективное средство при выполнении базовых операций с Mapleбиблиотеками пакета. Рекомендуется обратить внимание на подпроцедуру mkdir1, обеспечивающую создание цепочки каталогов любого уровня вложенности. Она намного проще нашей стандартной (используемой процедурами нашей библиотеки [103]) процедуры MkDir, однако не снабжена развитой системой обработки ошибочных ситуаций.

Достаточно полезной оказывается и процедура, чей вызов Plib(L) возвращает полный путь к Maple-библиотеке, заданной своим именем либо путем L к ней, и которая логически связана с главной библиотекой пакета. При отсутствии такой библиотеки либо логической связи для нее возвращается false-значение. Нижеследующий фрагмент представляет исходный текст процедуры и пример ее применения.

Plib := proc(L::{string, symbol}) local a b c k h p, , , , , , ω; assign(a = [libname], b = cat "/",( Case(L, 'lower')),

ω = (( ) → Case(sub_1("&bsol;" = "/" args, ))), c = cat "&bsol;",( Case(L, 'lower'))), seq(`if`( ω(a k[ ]) = ω(L) or Search1(Case(a k[ ], 'lower'), b, ' 'h ) and h = ['right'] or Search1(Case(a[k], 'lower'), c, 'p') and p = ['right'], RETURN(a[k]), NULL), k = 1 .. nops(a)), false

end proc

> Plib(userlib), Plib(UserLib), Plib("C:&bsol;RANS/Academy/ModProcLib"), Plib(Svetlana);

"c:/program files/maple 9/lib/userlib", "c:/program files/maple 9/lib/userlib", "c:/rans/academy/modproclib", false

Для поддержки разнообразных процедур работы с Maple-библиотеками нами создан целый ряд полезных средств, представленных в книгах [41,42,43,103] и в прилагаемых к ним библиотекам программных средств для пакета Maple релизов 6 – 10. Рассмотрим теперь еще несколько способов организации пользовательских библиотек, которые в ряде случаев оказываются даже эффективнее стандартного подхода, поддерживаемого Maple.

8.2. Специальные способы создания пользовательских библиотек в среде Maple

Прежде всего, созданные и отлаженные процедуры и программные модули можно сохранять в текстовых файлах во входном формате Maple-языка. В данном случае они впоследствии читаются read-преложением, корректно загружая в текущий сеанс определения как процедур, так и программных модулей (стандартные средства пакета для модулей не могут обеспечить их корректного сохранения в m-файлах внутреннего Maple-формата). Сохранение процедур и модулей производится в результате выполнения save-предложения следующего формата кодирования:

save N1, N2, …, Nk, <СФ> либо save(N1, N2, …, Nk, <СФ>)

где фактические аргументы Nj определяют идентификаторы сохраняемых процедур и/или модулей, а СФ - спецификатор принимающего файла (имя либо полный путь к файлу). Если имя файла завершается символами “.m”, то принимающий файл СФ будет во внутреннем Maple-формате, который не позволяет корректно сохранять программные модули [12-14,41-43,103,109]. Поэтому, совместное сохранение процедур и модулей следует делать в файле входного Maple-формата, для чего имя принимающего файла достаточно кодировать без завершающих его символов “.m”. Загрузка сохраненных процедур и модулей производится по предложению read <СФ> {read(<СФ>)}, в результате чего определения процедур и модулей, находящихся в файле СФ, вычисляются и они становятся доступными текущему сеансу пакета. Следующий весьма простой фрагмент иллюстрирует вышесказанное:

> G:= () -> `+`(args)/nargs: S:= module() export Sr; Sr:= () -> `+`(args)/nargs end module:

> save(G, S, "C:/Temp/File.lib");

> restart; read "C:/Temp/File.lib": 5*G(42, 47, 67, 85, 96), with(S), 5*S:- Sr(42, 47, 67, 85, 96); 337, [Sr], 337

Суть фрагмента сводится к следующему. Определяются простая G-процедура, возвращающая сумму значений передаваемых ей фактических аргументов, и программный модуль S с единственным экспортом Sr, и производится их вычисление с последующим сохранением по save-предложению в файле входного Maple-формата. По restart-предложению восстанавливается исходное состояние текущего сеанса. После этого по предложению read производится загрузка из файла G-процедуры и S-модуля с последующим вызовом процедуры и Sr-экспорта модуля S, завершившиеся вполне корректно.

Таким образом, по save-предложению можно создавать файлы входного Maple-языка, содержащие корректные определения сохраненных в них объектов (процедуры, модули и др.). В случае же внутреннего Maple-формата (m-файлы) программные модули сохраняются некорректно, без их тела. Данная проблематика детально рассмотрена в наших книгах [13,14,41-43,103] и там же представлен целый ряд средств по устранению данной ситуации. В частности, в целях устранения данного недостатка нами была создана процедура SaveMP, обеспечивающая для пакета релизов 6-10 корректное выполнение данной операции наряду с другими. Процедура и примеры ее применения представлены ниже.