Copyright (C) А.Гавва V-0.4w май 2004

8. Переименования

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

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

8.1 Уменьшение длин имен

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


with  Ada.Text_IO;
with  Ada.Integer_Text_IO;

procedure Gun_Aydin is

    package TIO renames  Ada.Text_IO;
    package IIO renames  Ada.Integer_Text_IO;

    . . .

В этом случае, для внутреннего использования, длинное имя Ada.Text_IO переименовано в короткое имя TIO, а длинное имя Ada.Integer_Text_IO переименовано в короткое имя IIO.

8.2 Переименование знаков операций

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

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


with  Ada.Text_IO;

procedure diamond1 is

    package TIO renames  Ada.Text_IO;

    function "+" (L, R: TIO.Count) return TIO.Count renames TIO."+";
    function "-" (L, R: TIO.Count) return TIO.Count renames TIO."-";

    . . .

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


package Nested  is

    type T1     is private;
    type Status is (Off, Low, Medium, Hight);

    package Operators is

        function ">=" (L, R: Status) return Boolean renames Nested.">=";
        function "="  (L, R: Status) return Boolean renames Nested."=";

    end Operators;

private
    type T1 is ...
    . . .
end Nested;

Показанный выше, вложенный пакет может быть сделан доступным путем указания спецификатора контекста "with Nested;", и последующего спецификатора использования "use Nested.Operators;" следующим образом:


with Nested;

procedure Test_Nested is

    use Nested.Operators;
    . . .
begin
    . . .

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

8.3 Переименование исключений

В некоторых случаях полезно осуществить локальное переименование исключения:


with  Ada.IO_Exceptions;

package My_IO is

    Data_Error: exception renames Ada.IO_Exceptions.Data_Error;
    . . .
end My_IO;

8.4 Переименование компонентов

Наиболее часто забываемым свойством переименования Ады является возможность предоставления собственного имени определенному компоненту составного типа:


with  Ada.Text_IO;

package Rename_A_Variable is

    Record_Count: renames Ada.Text_IO.Count;
    . . .
end Rename_A_Variable;

8.4.1 Переименование отрезка массива

Предположим, что у нас есть следующая строка:


Name  : String(1..60);

Причем, отрезок (1..30) - это фамилия (last name), отрезок (31..59) - имя (first name), символ в позиции 60 - это инициал отчества (middle name). Используя переименования мы можем выполнить следующее:


declare
    Last    : String renames Name(1..30);
    First   : String renames Name(31..59);
    Middle  : String renames Name(60..60);
begin
    Ada.Text_IO.Put_Line(Last);
    Ada.Text_IO.Put_Line(First);
    Ada.Text_IO.Put_Line(Middle);
end;

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

8.4.2 Переименование поля записи

Предположим, что у нас имеются следующие описания:


subtype Number_Symbol     is Character range '0' .. '9';
subtype Address_Character is Character range
    Ada.Characters.Latin_1.Space .. Ada.Characters.Latin_1.LC_Z;

type  Address_Data  is array (Positive range <>) of Address_Character;
type  Number_Data   is array (Positive range <>) of Number_Symbol;

type  Phone_Number  is
    record
        Country_Code  : Number_Data(1..2);
        Area_Code     : Number_Data(1..3);
        Prefix        : Number_Data(1..3);
        Last_Four     : Number_Data(1..4);
    end record;

type  Address_Record  is
    record
        The_Phone         : Phone_Number;
        Street_Address_1  : Address_Data(1..30);
        Street_Address_2  : Address_Data(1..20);
        City              : Address_Data(1..25);
        State             : Address_Data(1..2);
        Zip               : Number_Data(1..5);
        Plus_4            : Number_Data(1..4);
    end record;


One_Address_Record  : Address_Record;

Используя переименование, мы можем переименовать один из внутренних компонентов переменной записи One_Address_Record типа Address_Record, для прямого использования в программе. Например, мы можем переименовать Area_Code в инструкции блока:


declare
    AC: Number_Data renames One_Address_Record.The_Phone.Area_Code;
begin
    . . .
end;

Описание AC не требует никакого распределения дополнительного пространства данных. Вместо этого, оно локализует имя для компонента, который вложен в запись. При наличии компонентов записей с большим уровнем вложения, такой подход может оказаться весьма удобным.

8.5 Переименование библиотечного модуля

Предположим, что в нашей библиотеке есть пакет который часто используется, и предположим, что этот пакет имеет довольно длинное имя. Пользуясь переименованием, мы можем указать этот пакет в спецификаторе контекста with, после чего, переименовать пакет с длинным именем, и скомпилировать полученный модуль с более коротким именем обратно в библиотеку. Например:


with  Graphics.Common_Display_Types;
package CDT renames Graphics.Common_Display_Types;

Далее, мы можем использовать библиотечный модуль CDT, с более коротким именем, также как и библиотечный модуль Graphics.Common_Display_Types. При этом следует избегать переименований, когда новое имя очень сильно отличается от оригинала.


Copyright (C) А.Гавва V-0.4w май 2004