Logo

21 ноября 2014 г.

Этюд 2. Частичное применение

Со времен Turbo Vision в Turbo Pascal были записи WordRec и LongRec для приведения типов. С появлением Delphi они перекочевали в модуль SysUtils, но смысл сохранился. Поскольку в практической разработке без прямого доступа к байтам и словам порой никак, некий аналог должен быть и в Канторе, и он сейчас послужит нам этюдом с частичным применением.

На Delphi

Задача типов WordRec и LongRec — подружить строгую типизацию с низкоуровневым доступом к байтам и словам. Возьмем вариант из модуля CoreUtils.
type
  WordRec = packed record
    case Byte of
      0: (Lo, Hi: Byte);
      1: (Bytes: array [0..1] of Byte);
  end;

  LongRec = packed record
    case Byte of
      0: (Lo, Hi: Word);
      1: (Words: array [0..1] of Word);
      2: (Bytes: array [0..3] of Byte);
  end;

На Канторе

Пример на Канторе адаптирован из разрабатываемого кода, в нем демонстрируется использование ключевого слова partial — оператора частичного применения.
public class Core:Typecast with inner of
  class ByteArray with inner of
    final class Bytes = 0..1;
    public out Core:Byte RawBytes[Bytes];
    public RawBytes[Core:Byte; Bytes];
  end;

  class ShortWordArray with inner of
    final class Bytes = 0..3;
    public out Core:Byte RawBytes[Bytes];
    public RawBytes[Core:Byte; Bytes];

    final class ShortWords = 0..1;
    public out Core:ShortWord RawShortWords[ShortWords];
    public RawShortWords[Core:ShortWord; ShortWords];
  end;

  class ShortWord from ByteArray of // аналог WordRec
    public LowNibble = partial RawBytes[0];
    public HighNibble = partial RawBytes[1];
  end;

  class LongWord from ShortWordArray of // аналог LongRec
    public LowNibble = partial RawShortWords[0];
    public HighNibble = partial RawShortWords[1];
  end;
end;
В сравнении с Delphi код вышел объемней, но описание промежуточных классов на Канторе требуется для автоматического учета порядка байт на разных архитектурах. Код настоящего Core:Typecast еще сложней из-за широкого использования обобщений, и для этюда его пришлось упростить.

Без частичного применения код двух последних классов будет выглядеть так:
public class Core:Typecast with inner of
  class ShortWord from ShortWordArray of // аналог WordRec
    public LowNibble = RawBytes[0];
    public LowNibble[Core:Byte value] of
      RawBytes[0] = value;
    end;

    public HighNibble = RawBytes[1];
    public HighNibble[Core:Byte value] of
      RawBytes[1] = value;
    end;
  end;

  class LongWord from ShortWordArray of // аналог LongRec
    public LowNibble = RawShortWords[0];
    public LowNibble[Core:ShortWord value] of
      RawShortWords[0] = value;
    end;

    public HighNibble = RawShortWords[1];
    public HighNibble[Core:ShortWord value] of
      RawShortWords[1] = value;
    end;
  end;
end;
Две строчки с частичным применением против восьми при расписывании вручную, — префикс partial одной строкой описывает сразу несколько свойств — все, к которым подходит частичное применение. Рутина сокращается, код становится чище и наглядней.

Подсветка синтаксиса

Публикация скриншотов с подсветкой синтаксиса Кантора становится традицией этюдов.
Добавлена подсветка синтаксиса, скриншоты удалены.

Комментариев нет :

Отправить комментарий

Выбрав в выпадающем списке пункт «Имя/URL», можно оставить комментарий от своего имени без предварительной регистрации.