Смекни!
smekni.com

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

elib := proc(e::symbol, L::{mlib, mla}) local a k, ; for k in march '( list L', ) do

if k[1] = "" || || e ".m" then a := SUB_S [( ", " = "/"], `` || (seqstr op(( k[2][1 .. 3])))); return true, `if`(2 < nargs, assign(args[3] = a), NULL)

end if

end do;

false

end proc

> elib(pusers, "C:/program files/maple 10/lib/userlib", 'h'), h; ⇒ true, 2007/1/21

Вызов представленной выше процедуры elib(e, L) возвращает true-значение, если объект е находится в Maple-библиотеке L, и false-значение в противном случае. Если указан и третий аргумент, то через него возвращается дата сохранения е-объекта в библиотеке.

3.4. Определяющие параметры и описания Mapleпроцедур

Прежде всего, представим секцию описания (description), завершающую описательную часть определения процедуры и при ее наличии располагающуюся между секциями {local, global, uses, options} и непосредственно телом процедуры. При отсутствии данных секций description-секция располагается непосредственно за заголовком процедуры и кодируется в следующем формате: description <Строчная конструкция> {:|;}

Определенная в данной секции строчная конструкция не влияет на выполнение процедуры и используется в качестве комментирующей компоненты, т.е. она содержит текстовую информацию, предназначенную, как правило, для документирования процедуры. При этом, в отличие от обычного комментария языка, которое игнорируется при чтении процедуры, описание ассоциируется с процедурой при ее выводе даже тогда, когда ее тело не выводится по причине использования рассматриваемой ниже опции Copyright. Более того, определяемый description-секцией комментарий может быть одного из типов {string, symbol}, как это иллюстрирует следующий простой фрагмент:

> REA:= proc() description `Average`; sum(args[k], k= 1 .. nargs)/nargs end proc: > REA(19.42, 19.47, 19.62, 19, 67, 19, 89, 20.06), eval(REA);

34.07125000, proc () description Average; sum(args[k],k = 1 .. nargs)/nargs end proc > REA:= proc() option Copyright; description "Average of real arguments"; sum(args[k], k= 1 .. nargs)/nargs end proc:

> eval(REA); ⇒ proc () description "Average of real arguments" … end proc

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

Рассмотрев секции local, global и description, несколько детальнее остановимся на секции {options|option}, которая должна кодироваться непосредственно за двумя первыми (или быть первой при их отсутствии) в описательной части определения процедуры. В качестве параметров (опций) данной секции допускаются следующие: builtin, arrow, Copyright, trace, operator, remember и call_external. При этом, перечень опций может зависеть от используемого релиза пакета.

Пакет располагает тремя типами процедур: встроенными непосредственно в ядро пакета, библиотечными и определяемыми самим пользователем. Параметр builtin определяет встроенную функцию пакета и при наличии он должен кодироваться первым в списке параметров option-секции. Данный параметр визуализируется при полном вычислении процедуры посредством eval-функции либо по print-функции, например:

> print(eval), eval(readlib); proc () option builtin; 169 end proc proc () options builtin, remember; 237 end proc

Каждая встроенная функция идентифицируется уникальным номером (зависящим от номера релиза пакета) и пользователь не имеет прямой возможности определять собственные встроенные функции. В приведенном примере первым выводится результат вызова print-функции, а вторым - eval-функции, из чего следует, что встроенные функции eval и readlib имеют соответственно номера 98 и 152 (Maple 8, тогда как уже для Maple 10 эти номера соответственно будут 117 и 274), а вторая процедура имеет дополнительно и опцию remember.

Для проверки процедур могут быть полезны и три наши процедуры ParProc, ParProc1 и Sproc [103], обеспечивающие возврат как основных параметров процедур, модулей и пакетов, так и их местоположение в библиотеках Maple, как это иллюстрирует следующий достаточно простой фрагмент:

> ParProc(MkDir), ParProc(came); map(ParProc, ['add', march, goto, iostatus, seq]);

locals = Arguments(cd r k h z K L, , , = , ,( ::F ,{string symbol, Λ, ,t d, , ω, u f s g v, , ,}) , ), Argumentsglobalslocals = = ( = __Art_Kr_(E(::f h,anything) ) )

[builtin function, 91, iolib function, 31, builtin function, 193, iolib function, 13, builtin function, 101]

> ParProc(DIRAX); DIRAX is module with exports [new,replace,extract,empty,size,reverse,insert,delete,sortd,printd,conv]

> ParProc(process); ⇒ inert_function process is module with exports [popen, pclose, pipe, fork, exec, wait, block, kill, launch]

> ParProc(Int);

Warning, <Int> is inert version of procedure/function <int>

> ParProc1(ParProc1, 'h'), h;

Warning, procedure ParProc1 is in library [Proc, User, {"c:/program files/maple

10/lib/userlib"}]

localsArguments = globals(a b c d p h t z cs L R N, , , , , , , , = = ((M_62 ParProc Sproc::{,procedure,, , module, , ), ω ν},) ), [Proc User, , {"c:/program files/maple 10/lib/userlib"}] > ParProc1(Sockets, 't'), t;

Warning, module Sockets is in library [package, Maple, {"C:&bsol;Program Files&bsol;Maple 10/lib"}]

[exports = (socketID, Open, Close, Peek, Read, Write, ReadLine, ReadBinary,

WriteBinary Server Accept Serve Address ParseURL LookupService, , , , , , ,

GetHostName GetLocalHost GetLocalPort GetPeerHost GetPeerPort, , , , ,

GetProcessID HostInfo Status Configure _pexports, , , , )]

[locals = (defun trampoline soPath solib passign setup finalise, , , , , , )]

[options = (package, noimplicit, unload = finalise, load = setup)]

[description = ("package for connection oriented TCP/IP sockets" ,)]

[package Maple, , {"C:&bsol;Program Files&bsol;Maple 10/lib"}] Sproc := proc(P::symbol) local k L R h s, , , , , ω; `if`(type(P procedure, ) or type(P `module`, ), assign(L = [libname], R = { }, s = CF cat(( CDM( ), "&bsol;lib"))), RETURN(false)), assign(ω = (proc(R s, ) local a, b; assign(a = map(CF R, ), b = `if` type( ,( P 'package'), 'package', `if`(type(P procedure, ), 'Proc', 'Mod'))); if { }s = a then b, 'Maple' elif member(s a, ) then b `Maple&User`,

else b, 'User' end if

end proc ));

`if` type( ,( P 'builtin'), RETURN(true, `if`(1 < nargs, assign(args 2[ ] = ['Proc', 'builtin', Builtin(P), s]), 7 )) , 7); try assign(h = IO_proc(P)), `if`(type(h, 'integer'), RETURN(true,

`if`(1 < nargs assign(, args 2[ ] = ['Proc', 'iolib h s', , ]), NULL)), NULL) catch : seq `if`( (search(convert(march '( list', L k[ ]), 'string'), cat "["",( P, ".m",")), assign(' 'R = {L k[ ], op(R)}), NULL), k = 1 .. nops(L))

end try ;

`if`(R = { }, RETURN(false),

RETURN(true, `if`(nargs = 2, assign([args] 2[ ] = [ω(R s, ), R]), NULL)))

end proc

> Sproc(MkDir, 'h'), h; ⇒ true, [Proc, User, {"c:/program files/maple 9/lib/userlib"}] > Sproc(`type/package`, 'h'), h;

true, [Proc, Maple&User, {"C:&bsol;Program Files&bsol;Maple 9/lib",

"c:/program files/maple 9/lib/userlib"}]

С описанием данных процедур можно ознакомиться в [103], тогда как сами они включены в прилагаемую Библиотеку [109]. Там же можно получить и их исходные тексты.

Параметр Copyright определяет авторские права процедуры, ограничивая возможности вывода ее определения на печать. В качестве такого параметра пакет рассматривает любую конструкцию option-секции, начинающуюся с Copyright-слова. Все библиотечные Maple-процедуры определены с параметром Copyright, требуя для вывода на печать их определений установки опции verboseproc=n (n={2|3}) в interface-процедуре. Типичное содержимое option-секции библиотечных процедур имеет следующий вид:

option `Copyright (c) 1997 Waterloo Maple Inc. All rights reserved.`;

option {system,} `Copyright (c) 1992 by the University of Waterloo. All rights reserved.`;

в зависимости от релиза пакета; при этом, каждый релиз пакета совмещает процедуры и более ранних релизов. Текст любой пакетной процедуры (включая их remember-таблицы), кроме встроенных, можно получать по конструкции следующего простого вида: interface(verboseproc = 3): {print|eval}(<Id-процедуры>);

как это иллюстрирует следующий достаточно простой пример:

> interface(verboseproc = 3): eval(savemp); (M::{`module`, set(`module`), list(`module`)}, F) → (proc() local a; a := x → `if`(type(x `module`, ), [ ]x , x); map(mod21, a M( ));

modproc op( (( a M))); (proc() save args, F end proc )(op(a(M))) end proc )( )

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

Параметр package определяет принадлежность процедуры внутреннему модулю пакета. Тогда как по trace-параметру определяется режим трассировки вызова процедуры независимо от значения глобальной printlevel-переменной пакета, устанавливающей режим вывода служебной информации на экран монитора.

Совместное использование двух параметров operator и arrow информирует пакет о том, что процедура должна рассматриваться как функциональный (->)-оператор во всех ее вызовах, а также при выводе ее определения на печать, например:

> G:= proc() option operator, arrow; evalf(sqrt(sum(args[k]^2, k= 1 .. nargs))) end proc;

G := ( ) → evalf nargsk∑ = 1 argsk2 

> S:= proc() local k, p; option operator, arrow; for k to nargs do p:= args[k]: if type(p, 'numeric') then next else print(p, whattype(p)) end if end do end proc;

S := proc () local k, p; options operator, arrow; for k to nargs do p := args[k]; if type(p, 'numeric') then next else print(p, whattype(p)) end if end do end proc

Использование указанных параметров предполагает также упрощение тела процедуры. С другой стороны, как иллюстрируют примеры процедур G и S, далеко не каждая процедура допускает представление в нотации функционального (->)-оператора. Данную возможность допускают, как правило, простые процедуры, реализованные однострочным экстракодом, что иллюстрирует простая G-процедура первого примера фрагмента. Прежде, чем переходить к рассмотрению важного remember-параметра, представим общие средства доступа к процедурным объектам Maple-языка. Для идентификации процедурного типа Proc-объекта служат два ранее рассмотренных тестирующих средства: type(Proc, 'procedure') и whattype(eval(Proc))