Старый вопрос Паскаля о том, как правильно привести параметры функции записи варианта - PullRequest
3 голосов
/ 09 сентября 2010

Я пытаюсь создать функцию с альтернативным параметром типа записи, который позволяет выполнять линейное приведение или присвоение, как таковое:

type rectype = ( VT_INT, VT_CHAR, VT_BOOL );
     rec = record
       case t : rectype of
         VT_INT  : ( i : integer );
         VT_CHAR : ( c : char );
         VT_BOOL : ( b : boolean );
     end;

procedure handler( r : rec );
begin
  case r.t of
    VT_INT  : { do something with r.i }
    VT_CHAR : { do something with r.c }
    VT_BOOL : { do something with r.b }
  end;
end;

Теперь вышеприведенное "работает" нормально, если вы потратите время на ручную настройку переменной, как таковая:

 r.t := VT_INT;
 r.i := 42;
 handler( r );

Но я бы хотел немного злоупотребить системой набора текста и попытаться сделать это встроенным (я объясню почему через некоторое время), как:

 handler( rec( VT_INT, 42 ) );

Вспомогательная функция тоже подойдет, и я попробовал несколько разных способов сделать это, что можно увидеть здесь (для краткости этого поста):

http://pastie.org/private/glxhwbpsbbh5gtxju0uvxa

Теперь по причине: я работаю над этим и действительно выпустил пакет модульного тестирования, который стремится быть таким же переносимым, как и сам Pascal (собирается под FreePascal и Turbo Pascal 7 (да, действительно)). Я уже публично выпустил программное обеспечение с открытым исходным кодом (пока не могу связать, недостаточно повторений), которое включает в себя различные функции для разных типов: isI (), isR (), isS (), isP (), isC () и т. д. Это повторяет много кода, и я знаю, что есть лучший способ сделать это. Я считаю, что есть тип варианта, поддерживаемый FPC и Delphi, который я могу использовать с помощью директив IFDEF на этих платформах, но реальным доводом является TP7, который я все еще хочу поддерживать по непристойным причинам.

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

is( VT_INT, SomeIntFunc( v ), 42, 'Test Name' );

Я готов пойти на все, чтобы обойти типизацию под TP7, включая манипулирование стеком самостоятельно в сборке и т. Д. Но я надеюсь, что модифицированная версия с использованием синтаксиса, с которым я просто не знаком, сделает эту работу.

Итак, программисты Pascal старой школы (я знаю, что там должно быть где-то ), какие-нибудь предложения?

1 Ответ

1 голос
/ 10 сентября 2010

Free Pascal не проблема, так как он поддерживает конструкции Delphi, такие как (пользовательские) варианты, массив константных интерфейсов и другие приемы, чтобы иметь дело с типизацией во время выполнения (при условии, что он ограничен наблюдаемым числом).Недавние Delphi и FPC поддерживают дженерики, и вы, вероятно, могли бы пройти долгий путь, дублируя его.

Делать это ТП старой школы, однако, является трудной частью.Он просто почти не имеет нетипизированных (или, что еще лучше, функциональных данных).

Единственное, о чем я могу думать, это

 procedure rec(vartype:Ttypeofvar;var value):tvariantrecord;
 begin
   rec.t:=vartype
   case vartype of 
      vt_int: move (value,@rec.i,sizeof(integer));
      ..
      ..
 end;

Рабочий обходной путь, но не типобезопасный, так как передача rec (varint, "что-то двойное") возможно.С TP просто нечем работать, кроме формального параметра VAR.

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

...