Описание языка «PascalABC.NET».

Модули.

Структура модуля.

Модули предназначены для разбиения текста программы на несколько файлов. В модулях описываются переменные, константы, типы, классы, процедуры и функции. Для того чтобы эти объекты можно было использовать в вызывающем модуле (которым может быть и основная программа), следует указать имя файла модуля (без расширения .pas) в разделе uses вызывающего модуля. Файл модуля (.pas) или откомпилированный файл модуля (.pcu) должен находиться либо в том же каталоге, что и основная программа, либо в подкаталоге Lib системного каталога программы PascalABC.NET.

Модуль имеет следующую структуру:

Unit имя модуля; Interface. Раздел интерфейса. Implementation. Раздел реализации. Initialization. Раздел инициализации. Finalization. Раздел финализации. End.

Имеется также упрощенный синтаксис модулей без разделов интерфейса и реализации.

Первая строка обязательна и называется заголовком модуля. Имя модуля должно совпадать с именем файла.

Раздел интерфейса и раздел реализации модуля могут начинаться с раздела uses подключения внешних модулей и пространств имен .NET. Имена в двух разделах uses не должны пересекаться.

Раздел интерфейса включает объявление всех имен, которые экспортируются данным модулем в другие модули (при подключении его в разделе uses). Это могут быть константы, переменные, процедуры, функции, классы, интерфейсы. Реализация методов классов может быть дана прямо в разделе интерфейса, но это не рекомендуется.

Раздел реализации содержит реализацию всех процедур, функций и методов, объявленных в разделе интерфейса. Кроме этого, в разделе реализации могут быть описания внутренних имен, которые не видны вне модуля и используются лишь как вспомогательные.

Раздел инициализации и раздел финализации представляют собой последовательность операторов, разделяемых символом ;. Операторы из раздела инициализации модуля выполняются до начала основной программы, операторы из раздела финализации модуля - после окончания основной программы. Порядок выполнения разделов инициализации и разделов финализации подключенных модулей непредсказуем. Как раздел инициализации, так и раздел финализации могут отсутствовать.

Вместо разделов инициализации и финализации может присутствовать только раздел инициализации в виде.

Begin. последовательность операторов. End.

Например:

Unit Lib; Interface. Uses GraphABC; Const Dim = 5; Var Colors: array [1..Dim] of integer; Function RandomColor: integer; Procedure FillByRandomColor; Implementation. Function RandomColor: integer; Begin. Result := RGB(Random(255),Random(255),Random(255)); End; Procedure FillByRandomColor; Begin. for i: integer := 1 to Dim do. Colors[i] := RandomColor; End; Initialization. FillByRandomColor; End.

Циклические ссылки между модулями возможны при определенных ограничениях.

Раздел uses.

Раздел uses имеет вид.

Uses список имен;

Имена в списке перечисляются через запятую и могут быть либо именами подключаемых внешних модулей PascalABC.NET, либо пространствами имен .NET. Например:

Uses System, System.Collections.Generic, MyUnit;

Здесь MyUnit - модуль PascalABC.NET, представленный в виде исходного текста или откомпилированного .pcu-модуля, System и System.Collections.Generic - пространства имен .NET.

В модуле или основной программе, которая содержит раздел uses, можно использовать все имена из подключаемых модулей PascalABC.NET и пространств имен .NET. Основное отличие между модулями и пространствами имен .NET состоит в том, что модуль содержит код, а пространства имен .NET содержат лишь имена - для использования кода его необходимо подключить с помощью директивы компилятора {$reference ИмяСборки}, где ИмяСборки - имя dll-файла, содержащего .NET-код. Другое не менее важное отличие состоит в том, что в модуле или основной программе нельзя использовать имена, определенные в другом модуле, без подключения этого модуля в разделе uses. Напротив, если сборка .NET подключена директивой $reference, то можно использовать ее имена, явно уточняя их пространством имен, не подключая это пространство имен в разделе uses. Например:

Begin. System.Console.WriteLine('PascalABC.NET'); End.

По умолчанию в каждой секции uses неявно первым подключается системный модуль PABCSystem, содержащий стандартные константы, типы, процедуры и функции. Даже если секция uses отсутствует, модуль PABCSystem подключается неявно. Кроме того, по умолчанию с помощью неявной директивы $reference подключаются сборки System.dll, System.Core.dll и mscorlib.dll, содержащие основные .NET-типы.

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

ИмяМодуля.Имя.

Или.

ИмяПространстваИменNЕТ.Имя.

В качестве имени модуля может выступать также имя основной программы если у нее присутствует заголовок program.

Упрощенный синтаксис модуля.

Упрощенный синтаксис модулей без разделов интерфейса и реализации имеет вид:

Unit имя модуля; Раздел описаний. End.

Или.

Unit имя модуля; Раздел описаний. Begin. Раздел инициализации. End.

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

Циклические ссылки между модулями.

Циклические ссылки модулей в интерфейсных частях запрещены. Например, следующая ситуация ошибочна:

Unit A; Interface. Uses B; Implementation. End. Unit B; Interface. Uses A; Implementation. End.

Таким образом, невозможно определить два общедоступных класса в разных модулях с объектными полями, ссылающимися друг на друга.

Однако, если одна ссылка находится в интерфейсной части, а вторая - в части реализации, или обе - в частях реализации, то циклические ссылки в этом случае разрешены:

Unit A; Interface. Implementation. Uses B; End. Unit B; Interface. Uses A; Implementation. End.

Библиотеки dll.

Библиотеки dll (dynamically linked libraries):

* содержат группу взаимосвязанных подпрограмм.

* находятся в откомпилированном файле.

* предназначены для обращения к ним из различных программ.

Они находятся в файле с расширением .dll либо в текущем каталоге приложения (локальные), либо в системном каталоге (глобальные библиотеки). Глобальными библиотеками могут пользоваться одновременно несколько приложений.

По своему назначению библиотеки очень похожи на модули, однако, имеют ряд важных отличий.

Отличия библиотек от модулей.

* При создании из модулей исполняемого файла .exe программа-линковщик помещает в него только те подпрограммы, переменные, типы и константы, которые используются (вызываются) в основной программе. При компиляции же библиотеки в нее добавляются все подпрограммы, потому что неизвестно, какие подпрограммы потребуются конкретному приложению.

* Библиотеки .dll при выполнении программы полностью загружаются в оперативную память.

* Библиотеки .dll часто используются одновременно несколькими программами.

* Библиотека .dll может быть написана и откомпилирована на одном языке, а обращаться к ней можно из программ, написанных на других языках. Например, программа на PascalABC.NET может вызывать функцию из библиотеки, созданной на языке C# и наобороот. Таким образом, библиотеки обеспечивают межъязыковое взаимодействие.

Структура библиотеки.

Библиотека имеет практически ту же структуру, что и модуль:

Library имя библиотеки; Interface. Раздел интерфейса. Implementation. Раздел реализации. End.

Имя библиотеки должно совпадать с именем pas-файла, в котором библиотека находится.

Имеется также упрощенный синтаксис библиотек - без разделов интерфейса и реализации, совпадающий с упрощенным синтаксисом модулей (за исключением заголовка).

В результате компиляции библиотеки в текущем каталоге создаётся .dll-файл, содержащий откомпилированную библиотеку.

Подключение библиотеки к основной программе.

Для подключения библиотеки к основной программе используется директива компилятора {$reference ИмяБиблиотеки}. Например:

{$reference ABC.dll}. {$reference ABC1.dll}. Begin. Writeln(a.GetType); End.

Подключение библиотеки может проводиться в любом месте исходного файла.

Библиотеки ABC и ABC1 имеют соответственно вид:

Library ABC; Var a: integer; End.

И.

Library ABC1; Var a: real; End.

Алгоритм поиска имен в библиотеках.

В первую очередь имя ищется в исходном модуле, затем в модулях, подключенных в разделе uses в порядке справа налево, и только потом - в подключенных библиотеках в порядке подключения.

Согласно этому правилу в примере из предыдущего пункта переменная a будет иметь тип integer.

В случае коллизии имен используемое имя можно предварять именем библиотеки с последующей точкой:

{$reference ABC.dll}. {$reference ABC1.dll}. Begin. Writeln(ABC1.a.GetType); End.

Документирующие комментарии.

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

Документирующий комментарий располагается на строчке, предшествующей помечаемому объекту, и начинается с символов ///. Например:

Const. /// Константа Pi. Pi = 3.14; Type. /// TTT - синоним целого типа. TTT = integer; /// Документирующий комментарий класса XXX. XXX = class. End; /// Документирующий комментарий процедуры p. Procedure p(a : integer); Begin. End; Var. /// Документирующий комментарий переменной t1. T1: TTT;

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

///- Exclude(var s : set of T; el : T). ///Удаляет элемент el из множества s. Procedure Exclude(var s: TypedSet; el: object);

Если первая строка документирующего комментария имеет вид ///--, то подсказка не всплывает. Это делается для элементов, которые хочется скрыть от системы всплывающих подсказок.