Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2013-03

Intercept call to a property, method or attribute

4 messages · 2 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Joao Morais

Hello list. I need to implement lazy loading for an OPF so I need to intercept the read call to a property. Lets take the following classes:

    TClient = class
    private
      FName: string;
    published
      property Name: string read FName write FName;
    end;
    TInvoice = class
    private
      FClient: TClient;
    published
      property Client: TClient read FClient write FClient;
    end;

Tinvoice.Client need to be checked by the OPF before return its actual value.

Some approaches I have outlined so far:

1. A future aspect implementation: so I can verify the Client property just before the value is returned to the caller.

2. A future (if possible) proxy (like Java proxy) implementation: so the OPF can place a "fake" TClient instance in the client property, and intercept calls to the Client instance. Just like Hibernate actually do.

3. A proxy object between TInvoice and TClient is possible today, with some effort from the user:

    TInvoice = class
    private
      FClient: specialize TProxy<TClient>;
    published
      property Client: TClient read GetClient write SetClient;
    end;
    GetClient: Result := FClient.GetValue;
    SetClient: FClient.SetInstance(AValue);

4. Finally a manual check is also possible and it's currently my preferred approach, but also with some effort from the user:

    TInvoice = class
    private
      FClient: TClient;
    published
      property Client: TClient read GetClient write FClient;
    end;
    GetClient: somecheck(Self, @FClient); Result := FClient;

Is there some compiler magic I am missing?

Joao Morais

Sven Barth
to Joao Morais
Joao Morais wrote
Is there some compiler magic I am missing?

Nope, you don't miss anything. The only thing which *could* help you is when the new RTTI unit is implemented which contains a TVirtualMethodInterceptor which allows you to - as its name suggests - intercept all calls to virtual methods, change their parameters, swallow or raise exceptions or discard the call completely. This will only work on virtual methods however (because this constructs a special VMT on the fly) and it might still take some time until this is implemented.

Regards,
Sven

Joao Morais
to Sven Barth
Sven Barth wrote 11 lines
On 03.03.2013 18:03, Joao Morais wrote: > > Is there some compiler magic I am missing? Nope, you don't miss anything. The only thing which *could* help you is when the new RTTI unit is implemented which contains a TVirtualMethodInterceptor which allows you to - as its name suggests - intercept all calls to virtual methods, change their parameters, swallow or raise exceptions or discard the call completely. This will only work on virtual methods however (because this constructs a special VMT on the fly) and it might still take some time until this is implemented.

Great new! Where do I click +1? =)

2.8 or pos 2.8 roadmap?

Joao Morais

Sven Barth
to Joao Morais
Joao Morais wrote 16 lines
On Sun, Mar 3, 2013 at 2:16 PM, Sven Barth wrote: > On 03.03.2013 18:03, Joao Morais wrote: >> >> Is there some compiler magic I am missing? > > Nope, you don't miss anything. The only thing which *could* help you is when > the new RTTI unit is implemented which contains a TVirtualMethodInterceptor > which allows you to - as its name suggests - intercept all calls to virtual > methods, change their parameters, swallow or raise exceptions or discard the > call completely. This will only work on virtual methods however (because > this constructs a special VMT on the fly) and it might still take some time > until this is implemented. Great new! Where do I click +1? =) 2.8 or pos 2.8 roadmap?

My *hope* is to get it into the next major version (aka 2.8) together with the complete extended RTTI, but I don't promise anything, as I first need to work on generics.

Regards,
Sven