Sign in Join

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

Mailing lists / fpc-pascal / 2013-03

Case based on type

6 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

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

Mark Morgan Lloyd

Given a procedure definition like

procedure checkLibrariesAndConnect(db: TSQLConnection);

is there a more elegant way of performing type-specific actions than

begin
   if db is TPQConnection then begin
   end;
   if db is TIBConnection then begin
   end
end { checkLibrariesAndConnect } ;

i.e. something like case TypeOf(db) ?

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]
Sven Barth
to Mark Morgan Lloyd
Mark Morgan Lloyd wrote 15 lines
Given a procedure definition like procedure checkLibrariesAndConnect(db: TSQLConnection); is there a more elegant way of performing type-specific actions than begin if db is TPQConnection then begin end; if db is TIBConnection then begin end end { checkLibrariesAndConnect } ; i.e. something like case TypeOf(db) ?

No, there is currently no such construct. You could do this though:

=== example begin ===

procedure checkLibrariesAndConnect(db: TSQLConnection);
   procedure SetupPQConnection(db: TSQLConnection);
   // ...
   procedure SetupIBConnection(db: TSQLConnection);
   // ...
type
   TConnectionInitializer = record
     Connection: class of TSQLConnection;
     Setup: procedure(db: TSQLConnection) is nested; // needs
{$modeswitch nestedprocvars}
   end;
const
   ConnectionTypes: array[0..1] of TConnectionInitializer = (
     (Connection: TPQConnection; Setup: @SetupPQConnection),
     (Connection: TIBConnection; Setup: @SetupIBConnection)
   );
var
   conn: TConnectionInitializer;
begin
   for conn in ConnectionTypes do
     if db is conn.Connection then begin
       conn.Setup(db);
       Break;
     end;
end;

=== example end ===

Alternatively if you don't need to check the hierarchy, but can live with an exact match you can do this:

=== example begin ===

procedure checkLibrariesAndConnect(db: TSQLConnection);
begin
   case LowerCase(db.ClassName) of
     // Note: .ClassName won't work here
     'TPQConnection': ...;
     'TIBConnection': ...;
   end;
end;

=== example end ===

Regards,
Sven

Mark Morgan Lloyd
to Sven Barth
Sven Barth wrote 66 lines
On 01.03.2013 23:35, Mark Morgan Lloyd wrote: > Given a procedure definition like > > procedure checkLibrariesAndConnect(db: TSQLConnection); > > is there a more elegant way of performing type-specific actions than > > begin > if db is TPQConnection then begin > end; > if db is TIBConnection then begin > end > end { checkLibrariesAndConnect } ; > > i.e. something like case TypeOf(db) ? > No, there is currently no such construct. You could do this though: === example begin === procedure checkLibrariesAndConnect(db: TSQLConnection); procedure SetupPQConnection(db: TSQLConnection); // ... procedure SetupIBConnection(db: TSQLConnection); // ... type TConnectionInitializer = record Connection: class of TSQLConnection; Setup: procedure(db: TSQLConnection) is nested; // needs {$modeswitch nestedprocvars} end; const ConnectionTypes: array[0..1] of TConnectionInitializer = ( (Connection: TPQConnection; Setup: @SetupPQConnection), (Connection: TIBConnection; Setup: @SetupIBConnection) ); var conn: TConnectionInitializer; begin for conn in ConnectionTypes do if db is conn.Connection then begin conn.Setup(db); Break; end; end; === example end === Alternatively if you don't need to check the hierarchy, but can live with an exact match you can do this: === example begin === procedure checkLibrariesAndConnect(db: TSQLConnection); begin case LowerCase(db.ClassName) of // Note: .ClassName won't work here 'TPQConnection': ...; 'TIBConnection': ...; end; end;

Thanks Sven, noted with interest. case LowerCase(...ClassName) looks like "the best of a bad job", provided obviously that it's called infrequently.

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]
Marco van de Voort
to Sven Barth: No, there is currently no such construct. You could do this though: === example begin ===…

In our previous episode, Sven Barth said:

Show quoted text 15 lines
=== example end === Alternatively if you don't need to check the hierarchy, but can live with an exact match you can do this: === example begin === procedure checkLibrariesAndConnect(db: TSQLConnection); begin case LowerCase(db.ClassName) of // Note: .ClassName won't work here 'TPQConnection': ...; 'TIBConnection': ...; end; end;
var typ : TCLass;
begin
  typ:=db.classtype;  found:=false;
  while not found and assigned(typ) do
    begin
       case lowercase(typ.classname)
         ..  // must set found=true on match or break.
       end;
      typ:=typ.classparent;
    end;
waldo kitty
to Sven Barth: No, there is currently no such construct. You could do this though: === example begin ===…

On 3/1/2013 17:57, Sven Barth wrote:
[...]

Show quoted text 13 lines
Alternatively if you don't need to check the hierarchy, but can live with an exact match you can do this: === example begin === procedure checkLibrariesAndConnect(db: TSQLConnection); begin case LowerCase(db.ClassName) of // Note: .ClassName won't work here 'TPQConnection': ...; 'TIBConnection': ...; end; end;

is there a bug here? i would expect "LowerCase(anything)" to return all lower case characters... that means that 'TPQConnection' would not match since it contains uppercase characters...

what am i missing?

Mark Morgan Lloyd
to Marco van de Voort: In our previous episode, Sven Barth said: var typ : TCLass; begin typ:=db.classtype; …
Marco van de Voort wrote 28 lines
In our previous episode, Sven Barth said: > === example end === > > Alternatively if you don't need to check the hierarchy, but can live > with an exact match you can do this: > > === example begin === > > procedure checkLibrariesAndConnect(db: TSQLConnection); > begin > case LowerCase(db.ClassName) of > // Note: .ClassName won't work here > 'TPQConnection': ...; > 'TIBConnection': ...; > end; > end; var typ : TCLass; begin typ:=db.classtype; found:=false; while not found and assigned(typ) do begin case lowercase(typ.classname) .. // must set found=true on match or break. end; typ:=typ.classparent; end;

Thanks, detail noted.

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]