Старый вопрос Паскаля о том, как правильно привести параметры функции записи варианта
Я пытаюсь создать функцию с вариантом параметра типа записи, который позволяет встроенное приведение или присваивание, как таковой:
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 ответ
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 лет. Пусть это гниет с миром.