Delphi 2007 Handbook








March 19, 2008

Dynamic Method Invocation in Delphi (Part 1)

As Danny Thorpe pointed out recently, Delphi has had dynamic method invocation for many years before C#. First post of a long story...

A few weeks ago (I've collected many links in my "for blog" bookmarks recently) Danny Thorpe blogged about Dynamic Method Invocation, claiming Delphi did years ago what C# is aiming at now (the history of Delphi leading on the tech side is repeating). His post was a response to the post of yet-another ex-Borlander, Charlie Calvert, who posted about Dynamic Lookups in C# in a Future Focus column of his blog. I find the proposed C# syntax confusing, and don't think that making out the section of code for dynamic invocation at the caller side makes a lot of sense, but I had only a cursory view.


Let me start (today) by showing you how the call looks like:

var
  v: variant;
begin
  v := VarDSLDateTimeCreate (now);
  v.NextMonday;
  v.am7;

This sets the date and time represented by the variant to 7 am next Monday. I had a much better invocation mechanism by embedding the variant within an actual object, something I'll work on for a future post. Before that, I'll show you the custom variant architecture. All I want to show you for today, is that NextMonday and 7am are not hard-coded functions. They don't exist. The object receives a call and parses and interprets the function name to determine what to do! Here is a snippet, I'll expand soon with the details:

function TDslDateTimeVariantType.DoProcedure(const V: TVarData;
  const Name: string; const Arguments: TVarDataArray): Boolean;
var
  tmp: string;
  value, month, day: Integer;
  tmpDate: TDateTime;
begin
  if Pos ('AM', Name) > 0 then
  begin
    // parse and process...
    tmp := StringReplace (Name, 'AM', '', []);
    value := StrToIntDef (tmp, 0);

// yes this is ugly!!!
    TDslDateTimeVarData(V).VDateTime.DateTime :=
      RecodeTime (TDslDateTimeVarData(V).VDateTime.DateTime, value, 0, 0, 0);
  end;

...

  if Pos ('NEXT', Name) > 0 then
  begin
    // parse and process...
    tmp := StringReplace (Name, 'NEXT', '', []);
    if tmp = 'MONDAY' then
    begin
      // compute next monday date...
...

Stay tuned for the rest of the code and an improved version of it.





 

3 Comments

Maybe I'm getting old (happy birthday to me!) but ... 

I just don't get it.

Why would we WANT to be able to write code that we
have no idea will work or not?

In this specific case, why not have a DateTime class
that supports some methods like:

  TDateTime.Next(Monday)
  TDateTime.At(7, AM)

The "dynamic" approach sounds sexy but is only partly
dynamic.  After all, I can't invoke just any old thing
I like, I have to invoke things that will be understood.

Why deliberately set out to make it harder to be
understood (parsing) AND to know whether an invocation
WILL be understood at all?

I just don't get it.
Comment by Jolyon Smith [http://www.deltics.co.nz] on March 20, 01:38

Dynamic Method Invocation in Delphi Part 1 

Yup, I don't get it either. Can you give a useful
example of why this could be a good idea?

By going this route you've lost all compile-time
checking? And, surely your sample wouldn't work anyway
because you should be calling v.AM7, not v.am7. Not
that the compiler will care, which is exactly the kind
of thing that scares me about this.


Comment by Roddy [] on March 20, 12:02

Dynamic Method Invocation in Delphi Part 1 

OK, I failed to tell why ad when you'd want to write
code like this. I'll keep this for a new post, rather
than replying here.

As for the code not being correct, I did cut an
"uppercase" call in the DoProcedure, the code example
does work...
Comment by Marco Cantù [http://www.marcocantu.com] on March 20, 13:09


Post Your Comment

Click here for posting your feedback to this blog.

There are currently 0 pending (unapproved) messages.