Jump to content
Bill Meyer

can you reference unit name in code?

Recommended Posts

Is there any way to refer to the unit name in the unit's code? The question arises in connection with logging, and the convenience it would bring not to have to manually enter the unit name in those calls. Something like:

  LogThis(ThisUnit, SomeValue);

If this were only an occasional need, it would not matter, but I have hundreds units into which to add the calls.

Edited by Bill Meyer

Share this post


Link to post

If this call happens inside a method or class method in that unit, you can use UnitName for that. Every class returns the unit of its declaration with this function. See: http://docwiki.embarcadero.com/Libraries/Rio/en/System.TObject.UnitName

 

As it is a class method, you can even make use of it outside of that class as long as there is at least one class declared in that unit.

Edited by Uwe Raabe

Share this post


Link to post
1 hour ago, Uwe Raabe said:

If this call happens inside a method or class method in that unit, you can use UnitName for that. Every class returns the unit of its declaration with this function. See: http://docwiki.embarcadero.com/Libraries/Rio/en/System.TObject.UnitName

I thought I remembered UnitName in some hazy way. But the issue here is that I need to add logging into an initialization section, and not all of those are calling into classes. I am simply trying to find the least change needed to get the log to demonstrate the initialization order. Then I will apply that sequence in a module in which I manage the initialization sequence, and in each module, the initialization and finalization will be replaced by procedures InitializeUnit and FinalizeUnit, which contain the original code.

The issue is that the initialization sequence contains some traps, in that there are sequence dependencies, and on the way to a complete solution, making the order explicit in my code shields me from the shifting sands when changes are made to uses clauses. This in turn is a concern because of massive unit dependencies I am trying to reduce. As I learned painfully some months ago, removing unneeded unit references can cause the execution order of those initializations to change.

And yes, in the long run, refactoring and redesign is needed, but meanwhile, I have a couple thousand units in a large legacy app which must first be made stable.

Share this post


Link to post

As I said, you can call UnitName on every class declared in that unit. If the unit contains no suitable class declaration in the first place, you can always add one just for this purpose:

 

type
  TClassInThisUnit = class;

initialization
  LogThis(TClassInThisUnit.UnitName, SomeValue);
end.

 

  • Like 1
  • Thanks 1

Share this post


Link to post

You can also create an include file with the following content

type
  TLog = class
  public
    class procedure This(const Msg:string);
  end;

class procedure TLog.This(const Msg: string);
begin
  LogThis(UnitName, Msg);
end;

In your units add an appropriates include directive directly below the implementation uses. Then replace all LogThis calls with TLog.This calls, without bothering about the unit name at all.

Edited by Uwe Raabe

Share this post


Link to post

Parsing the detailed map file is probably the easiest way to do this is a large project.

 

If you know you have dependencies on initialization order, I'd solve the problem by removing those dependencies. 

Edited by David Heffernan
  • Like 1

Share this post


Link to post
1 hour ago, Uwe Raabe said:

You can also create an include file with the following content


type
  TLog = class
  public
    class procedure This(const Msg:string);
  end;

class procedure TLog.Line(const Msg: string);
begin
  LogThis(UnitName, Msg);
end;

In your units add an appropriates include directive directly below the implementation uses. Then replace all LogThis calls with TLog.This calls, without bothering about the unit name at all.

Shouldn't that be:

class procedure TLog.This(const Msg: string);
begin
  LogThis(UnitName, Msg);
end;
  • Thanks 1

Share this post


Link to post
8 hours ago, David Heffernan said:

Parsing the detailed map file is probably the easiest way to do this is a large project.

 

If you know you have dependencies on initialization order, I'd solve the problem by removing those dependencies. 

 

Is the sequence of the units in the map file identical to the sequence in which the initialization sections are processed?

 

Share this post


Link to post

Actually, I think that might be right, there is a section in the map file that lists the units in the order they are initialized. 

 

Also, there are tons of questions on this topic on SO. 

Share this post


Link to post
30 minutes ago, David Heffernan said:

there is a section in the map file that lists the units in the order they are initialized.

That is the ICODE section (probably stands for initialization code).

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×