Sign in Join

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

Mailing lists / lazarus / 2011-07

array[0..n] of class of TSomething

8 messages · 6 people · –

Reply by email Subscribe to this list Your subscription

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

Bernd

Hi,

I have the following (I don't yet know whether this is only pseudo-code to demonstrate what I mean (I have clearly done too much Python during the last year) or whether something like this or similar would actually work, I haven't tested it yet, although it compiles without errors), or whether this is complete nonsense:

implementation

const
MsgTypes : array[0..1] of class of Tp2pMessage = ( Tp2pMessageVersion,
Tp2pMessageGetdata

  );    // this will be a lot more classes later

and later i have the following:

  procedure TPeer.ProcessMessage;
  var
    Msg        : Tp2pMessage;
    TMsg       : class of Tp2pMessage;
    ...
  begin
    ...
    for TMsg in MsgTypes do begin
      if Header.Command = TMsg.GetCommand then begin
        Msg := TMsg.Create(Buffer, Header.Length);
        Msg.Parse;
        Msg.Process;
        break;
      end;
    end;

(GetCommand is a class function).

I cannot use this syntax at all because Lazarus is not happy with with my array declaration and codetools will only give me the followin error whenever I use autocompletion:

    "test.pas(42,35) Error: procedure or function or constructor or

destructor expected, but of found"
and the cursor is pointing to the second "of" in my array declaration.

Now the question: Is this all complete nonsense what I am trying here and I am using it wrong or am trying to over-engineer a simple thing? I'm trying to avoid a spaghetti-like monster-if from hell and want most of the things that the received messages would do actually let the messages do it themselves.

is there any possible variation of this design pattern so that Lazarus will not complain (I haven't actually tested whether the above even works because some parts are still missing but at least it seems to compile with FPC 2.5.1.

Bernd

Reply by email

Sven Barth
to leledumbo
leledumbo wrote 9 lines
Seems like codetools parser bug. Try writing it type by type: type Tp2pMessageClass = class of Tp2pMessage; Tp2pMessageClassArray = array [0 .. 1] of Tp2pMessageClass; const MsgTypes: Tp2pMessageClassArray = ( ... );

Free Pascal supports "class of" in declarations while Delphi does not, but it's a seldom used feature so the developers of the code tools might not have noticed that problem at all :)

@Bernd: Would you create a bug report, please?

Regards,
Sven

Reply by email

Hans-Peter Diettrich
to Sven Barth
Show quoted text 14 lines
On 12.07.2011 18:38, leledumbo wrote: > Seems like codetools parser bug. Try writing it type by type: > > type > Tp2pMessageClass = class of Tp2pMessage; > Tp2pMessageClassArray = array [0 .. 1] of Tp2pMessageClass; > const > MsgTypes: Tp2pMessageClassArray = ( > ... > ); Free Pascal supports "class of" in declarations while Delphi does not, but it's a seldom used feature so the developers of the code tools might not have noticed that problem at all :)

IMO this "comfort" is a misfeature, that bloats the compiler and all other parsers. It has not been introduced in Delphi for good reason.

DoDi

Reply by email

Flávio Etrusco
to Hans-Peter Diettrich
Hans-Peter Diettrich wrote 23 lines
Sven Barth schrieb: > > On 12.07.2011 18:38, leledumbo wrote: >> >> Seems like codetools parser bug. Try writing it type by type: >> >> type >> ? Tp2pMessageClass = class of Tp2pMessage; >> ? Tp2pMessageClassArray = array [0 .. 1] of Tp2pMessageClass; >> const >> ? MsgTypes: Tp2pMessageClassArray = ( >> ? ? ... >> ? ); > > Free Pascal supports "class of" in declarations while Delphi does not, but > it's a seldom used feature so the developers of the code tools might not > have noticed that problem at all :) IMO this "comfort" is a misfeature, that bloats the compiler and all other parsers. It has not been introduced in Delphi for good reason. DoDi

Err, why pollute the namespace with an identifier you'll only refer once? It's hardly essential but surely not a "misfeature" either.

-Fl?vio

Reply by email

Flávio Etrusco
to Hans-Peter Diettrich: For clarity? Code is not only written for the compiler, but also for human readers. Look…
Hans-Peter Diettrich wrote 17 lines
Fl?vio Etrusco schrieb: > Err, why pollute the namespace with an identifier you'll only refer > once? For clarity? Code is not only written for the compiler, but also for human readers. Look at the C syntax for type declarations, where some constructs are nearly unparsable by humans (without pen and paper). The name also may be useful in debugging and RTTI, and with every usage of an array element in code. Pascal is a strongly typed language, where e.g. for local variables or parameter types a unique type name is a must! DoDi

I agree with on your principles - and your observation on C syntax ;-)
- but disagree this specific case goes against these principles.

Best regards,
Fl?vio

Reply by email

Hans-Peter Diettrich
to Flávio Etrusco: On Tue, Jul 12, 2011 at 7:53 PM, Hans-Peter Diettrich Err, why pollute the namespace with…
Err, why pollute the namespace with an identifier you'll only refer once?

For clarity? Code is not only written for the compiler, but also for human readers. Look at the C syntax for type declarations, where some constructs are nearly unparsable by humans (without pen and paper).

The name also may be useful in debugging and RTTI, and with every usage of an array element in code.

Pascal is a strongly typed language, where e.g. for local variables or parameter types a unique type name is a must!

DoDi

Reply by email

Mark Morgan Lloyd
to Hans-Peter Diettrich
Hans-Peter Diettrich wrote 7 lines
Fl?vio Etrusco schrieb: > Err, why pollute the namespace with an identifier you'll only refer > once? For clarity? Code is not only written for the compiler, but also for human readers.

As are comments. Particularly for a rarely-used construct like 'class of' I think it's reasonable to split it out and say why it's there.

(* An element is either a scalar or a column in a (row in a) table, and
is      *)
(* directly associated with the action of getting or setting a value via
SNMP.  *)
type    CNodeContent= class of TNodeContent;
         TNodeContentArray= array of CNodeContent;
         CNode= class of TNode;
         TNodeArray= array of CNode;
         TNodeContent= class(TObject)
                       public

Also (as shown above) there's the potential for forward references, in which case I suggest it's good practice to be consistent.

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

Reply by email