¿Es posible obtener el nombre del procedimiento/función actual como una cadena, dentro de un procedimiento/función? Supongo que habría algún "macro" que se expande en tiempo de compilación.Cómo obtener el nombre del procedimiento/función actual en Delphi (como una cadena)
Mi caso es el siguiente: Tengo muchos procedimientos que tienen un registro y todos deben comenzar por verificar la validez del registro, por lo que pasan el registro a un "procedimiento de validación". El procedimiento de validación (el mismo para todos los procedimientos) genera una excepción si el registro no es válido, y quiero que el mensaje de la excepción no incluya el nombre del procedimiento del validador, sino el nombre de la función/procedimiento que llamó al validador procedimiento (naturalmente).
Es decir, tengo
procedure ValidateStruct(const Struct: TMyStruct; const Sender: string);
begin
if <StructIsInvalid> then
raise Exception.Create(Sender + ': Structure is invalid.');
end;
y luego
procedure SomeProc1(const Struct: TMyStruct);
begin
ValidateStruct(Struct, 'SomeProc1');
...
end;
...
procedure SomeProcN(const Struct: TMyStruct);
begin
ValidateStruct(Struct, 'SomeProcN');
...
end;
Sería algo menos propenso a errores si en cambio podría escribir algo así como
procedure SomeProc1(const Struct: TMyStruct);
begin
ValidateStruct(Struct, {$PROCNAME});
...
end;
...
procedure SomeProcN(const Struct: TMyStruct);
begin
ValidateStruct(Struct, {$PROCNAME});
...
end;
y luego cada uno vez que el compilador encuentra {$ PROCNAME}, simplemente reemplaza la "macro" con el nombre de la corriente función/procedimiento como un literal de cadena.
actualización
El problema con el primer enfoque es que es propenso a errores. Por ejemplo, sucede fácilmente que se obtiene por un error de copiar y pegar:
procedure SomeProc3(const Struct: TMyStruct);
begin
ValidateStruct(Struct, 'SomeProc1');
...
end;
o errores tipográficos:
procedure SomeProc3(const Struct: TMyStruct);
begin
ValidateStruct(Struct, 'SoemProc3');
...
end;
o confusión sólo temporal:
procedure SomeProc3(const Struct: TMyStruct);
begin
ValidateStruct(Struct, 'SameProc3');
...
end;
Esto sería dulce, pero hasta donde yo sé, no existe, y sí busqué algo similar. La única solución genérica que conozco sería utilizar la información de depuración que está incrustada en el EXE para obtener el nombre del procedimiento, pero esto sería un gran golpe de rendimiento en el tiempo de ejecución. Cuando necesitaba algo similar, escribía un pequeño programa que repasaba mis archivos PAS y reemplazaba cierta expresión con texto, pero para mí el nombre del archivo + número de línea era suficiente, no elegí el nombre del procedimiento. –
Según mi experiencia, los errores tipográficos y la confusión no son un gran problema. Siempre que sus registros muestren algún nombre de identificación, no importa cuál sea ese nombre. Si realmente no tienes una función con ese nombre, simplemente grep y encontrarás la única ocurrencia del nombre mal escrito en la función que estabas buscando de todos modos. –
FWIW, hay herramientas que lo harán por usted. Estoy familiarizado con CodeSite que agregará esas llamadas a funciones de registro usando su sistema. – mj2008