title: How To Get the Name of the Current Procedure/Function in Delphi (As a String)
body: <p>Is it possible to obtain the name of the current procedure/function as a string, within a procedure/function? I suppose there would be some "macro" that is expanded at compile-time.</p>
  
  <p>My scenario is this: I have a lot of procedures that are given a record and they all need to start by checking the validity of the record, and so they pass the record to a "validator procedure". The validator procedure (the same one for all procedures) raises an exception if the record is invalid, and I want the message of the exception to include not the name of the validator procedure, but the name of the function/procedure that called the validator procedure (naturally).</p>
  
  <p>That is, I have</p>
  
  <pre><code>procedure ValidateStruct(const Struct: TMyStruct; const Sender: string);
  begin
   if &lt;StructIsInvalid&gt; then
      raise Exception.Create(Sender + ': Structure is invalid.');
  end;
  </code></pre>
  
  <p>and then</p>
  
  <pre><code>procedure SomeProc1(const Struct: TMyStruct);
  begin
    ValidateStruct(Struct, 'SomeProc1');
    ...
  end;
  
  ...
  
  procedure SomeProcN(const Struct: TMyStruct);
  begin
    ValidateStruct(Struct, 'SomeProcN');
    ...
  end;
  </code></pre>
  
  <p>It would be somewhat less error-prone if I instead could write something like</p>
  
  <pre><code>procedure SomeProc1(const Struct: TMyStruct);
  begin
    ValidateStruct(Struct, {$PROCNAME});
    ...
  end;
  
  ...
  
  procedure SomeProcN(const Struct: TMyStruct);
  begin
    ValidateStruct(Struct, {$PROCNAME});
    ...
  end;
  </code></pre>
  
  <p>and then each time the compiler encounters a {$PROCNAME}, it simply replaces the "macro" with the name of the current function/procedure as a string literal.</p>
  
  <p><strong>Update</strong></p>
  
  <p>The problem with the first approach is that it is error-prone. For instance, it happens easily that you get it wrong due to copy-paste:</p>
  
  <pre><code>  procedure SomeProc3(const Struct: TMyStruct);
    begin
      ValidateStruct(Struct, 'SomeProc1');
      ...
    end;
  </code></pre>
  
  <p>or typos:</p>
  
  <pre><code>procedure SomeProc3(const Struct: TMyStruct);
  begin
    ValidateStruct(Struct, 'SoemProc3');
    ...
  end;
  </code></pre>
  
  <p>or just temporary confusion:</p>
  
  <pre><code>procedure SomeProc3(const Struct: TMyStruct);
  begin
    ValidateStruct(Struct, 'SameProc3');
    ...
  end;
  </code></pre>