суббота, 23 августа 2014 г.

Ссылка. PL/I

Почему-то захотелось поделиться ссылкой - PL/I

Я лет двадцать назад читал про него книжку. Ещё папину. И решал задачи из "примеров".

Почему захотелось поделиться?

Там даже числа Фиббоначи или факториалы можно было макросами разворачивать.

В контексте вот этого - О возбуждении исключений

Если найдётся кто-то дотошный - тогда поясню.

Поясню пока лишь вскользь, там можно написать что-то вроде (я синтаксис уже не помню, поэтому использую паскалеподобный):

MACRO NameAndValue (R, A)
begin
 R.Value := A;
 R.Name := '%A%';
end;

Тогда если мы напишем:

TMyRec = record
 Value : Int64;
 Name : String;
end;

var
 myRec : TMyRec;

NameAndValue(myRec, SomeValue)

То это развернётся в:
 myRec.Value := SomeValue;
 myRec.Name := 'SomeValue';

Т.е. те же "шаблоны" из C++, но с "подстановкой".

Я могу путать детали. Скорее всего я их путаю. Но хотелось бы "идею донести".

Почему "обработка исключений"?

А вот почему:

Цитата:

Можно было бы конечно "сочинить" что-то вроде:

Em3InvalidStreamPos.Check(Self.IsValidPosition,
                          aHeader.f_Name,
                          [l_Pos,
                           aHeader.f_TOCItemData.rBody.rRealSize,
                           aHeader.f_TOCItemData.rBody.RTOCBuffRootPosition,
                           aHeader.f_TOCItemData.rBody.RTOCItemListPosition,
                           aHeader.f_TOCItemData.RNextPosition]);

-- но я осознанно этого не делаю.

Т.к. конечно запись короче и "читабельнее". 

Но! В таком варианте - сложнее искать реальный источник ошибки.

Конец цитаты.


А вот если бы можно было бы написать:



Em3InvalidStreamPos.Check(Self.IsValidPosition,
                          [
                           NameAndValue(l_Pos),
                           NameAndValue(aHeader.f_TOCItemData.
                                         rBody.rRealSize),
                           NameAndValue(aHeader.f_TOCItemData.
                                         rBody.RTOCBuffRootPosition),
                           NameAndValue(aHeader.f_TOCItemData.
                                         rBody.RTOCItemListPosition),
                           NameAndValue(aHeader.f_TOCItemData.RNextPosition)
                          ]);

-- тогда - я бы обязательно воспользовался бы подобной конструкцией.

Как бы выглядел бы этот Check?

А вот так:

type
 TNameAndValue = record
  Name : String;
  Value : Int64;
  constructor Create(const aName: String; aValue: Int64);
 end;//TNameAndValue

....

constructor Create(const aName: String; aValue: Int64);
begin
 Name := aName;
 Value := aValue;
end;

MACRO NameAndValue (A)
begin
 TNameAndValue.Create('%A%', A');
end;

class procedure Em3InvalidStreamPos.Check(aCondition: TInt64Predicate; const aValues array of TNameAndValue);
var
 l_V : TNameAndValue;
begin
 for l_V in aValues do
  if not aCondition(l_V.Value) then
   raise Self.CreateFmt('Invalid data: %s = %d', [l_V.Name, l_V.Value]);
end;

-- для разработки и "реального программирования" это конечно же - бред.

А вот для диагностики ошибок - самое то.

В "моих скриптах" я кстати подобное уже сделал.

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

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