www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - convert "class of" in pascal to D.

reply "Eko Wahyudin" <eko.wahyudin yahoo.co.id> writes:
Hi, guys? I'm new in D and I come from pascal. The constructor
concept is very different, and it's very confusing for me.

I want to create some statement in D which in pascal like this.

type
      TMyObjectAClass = class of TMyObject_A;   // number 1

      TMyObject_A = class
         constructor Create(AString : String);
      end;

      TMyObject_B = class(TMyObject_A)
         constructor Create(AString : String); override;
      end;

      TMyObject_C = class(TMyObject_A)
      end;
- - - - - - - - - - - - - - - - -

function Foo(AClass: TMyObjectAClass): TMyObject_A;
begin
     Result:= AClass.Create(AClass.ClassName);  //number 2
end;

- - - - - - - - - - - - - - - - -
var
     B : TMyObject_B;
     C : TMyObject_C;
begin
     B:= Foo(TMyObject_B);  //number 3
     C:= Foo(TMyObject_C);
end.

===================================================================
Question 1> How I can make a data type "class of" in D language
Question 2> How to convert number 2, in D language.
Question 3> How I passing a "class type" as argument like number
3, and if D can do same thing like pascal, which one is called by
D, TMyObject_A.Create() or TMyObject_B.Create() ? In pascal It
should be call TMyObject_B.Create() first

Thanks :)
Eko
Jan 30 2013
next sibling parent "Namespace" <rswhite4 googlemail.com> writes:
Please post next time in D.learn.
In D it is still like in other C like languages:

class A {
public:
     this() { writeln("A CTor"); }
}

A a = new A(); create a new object of type A and print "A CTor"

Because D has no standard copy CTor for classes, you must declare 
your own:
class A {
public:
     this() { writeln("A CTor"); }
     this(ref const A a) { writeln("A copy CTor"); }
}

which is called with:
A a = new A();
A ac = new A(a); // <- calls copy CTor
Jan 30 2013
prev sibling next sibling parent reply Piotr Szturmaj <bncrbme jadamspam.pl> writes:
Eko Wahyudin wrote:
 Hi, guys? I'm new in D and I come from pascal. The constructor
 concept is very different, and it's very confusing for me.

 I want to create some statement in D which in pascal like this.

 type
       TMyObjectAClass = class of TMyObject_A;   // number 1

       TMyObject_A = class
          constructor Create(AString : String);
       end;

       TMyObject_B = class(TMyObject_A)
          constructor Create(AString : String); override;
       end;

       TMyObject_C = class(TMyObject_A)
       end;
 - - - - - - - - - - - - - - - - -

 function Foo(AClass: TMyObjectAClass): TMyObject_A;
 begin
      Result:= AClass.Create(AClass.ClassName);  //number 2
 end;

 - - - - - - - - - - - - - - - - -
 var
      B : TMyObject_B;
      C : TMyObject_C;
 begin
      B:= Foo(TMyObject_B);  //number 3
      C:= Foo(TMyObject_C);
 end.

 ===================================================================
 Question 1> How I can make a data type "class of" in D language
 Question 2> How to convert number 2, in D language.
 Question 3> How I passing a "class type" as argument like number
 3, and if D can do same thing like pascal, which one is called by
 D, TMyObject_A.Create() or TMyObject_B.Create() ? In pascal It
 should be call TMyObject_B.Create() first

"class of" in Delphi/OP means type or subtype of a class. You can use template parameters in D to pass "class of": // T : A means any type T that is equivalent to A or is subtype of A A foo(T : A)() { return new T(T.stringof); } B b; C c; b = foo!B(); c = foo!C();
Jan 30 2013
parent Piotr Szturmaj <bncrbme jadamspam.pl> writes:
Piotr Szturmaj wrote:
 A foo(T : A)()

that should be: T foo(T : A)()
Jan 30 2013
prev sibling next sibling parent reply "rumbu" <rumbu rumbu.ro> writes:
On Wednesday, 30 January 2013 at 14:48:07 UTC, Eko Wahyudin wrote:
 Hi, guys? I'm new in D and I come from pascal. The constructor
 concept is very different, and it's very confusing for me.

 I want to create some statement in D which in pascal like this.

 type
      TMyObjectAClass = class of TMyObject_A;   // number 1

      TMyObject_A = class
         constructor Create(AString : String);
      end;

      TMyObject_B = class(TMyObject_A)
         constructor Create(AString : String); override;
      end;

      TMyObject_C = class(TMyObject_A)
      end;
 - - - - - - - - - - - - - - - - -

 function Foo(AClass: TMyObjectAClass): TMyObject_A;
 begin
     Result:= AClass.Create(AClass.ClassName);  //number 2
 end;

 - - - - - - - - - - - - - - - - -
 var
     B : TMyObject_B;
     C : TMyObject_C;
 begin
     B:= Foo(TMyObject_B);  //number 3
     C:= Foo(TMyObject_C);
 end.

 ===================================================================
 Question 1> How I can make a data type "class of" in D language
 Question 2> How to convert number 2, in D language.
 Question 3> How I passing a "class type" as argument like number
 3, and if D can do same thing like pascal, which one is called 
 by
 D, TMyObject_A.Create() or TMyObject_B.Create() ? In pascal It
 should be call TMyObject_B.Create() first

 Thanks :)
 Eko

There are no class types in D and classes without empty constructors cannot be instantiated directly. The closest solution is to use a templated function for Foo: class TMyObject_A { this(string AString) { } } class TMyObject_B : TMyObject_A { this(string AString) { super(AString); } } class TMyObject_C : TMyObject_A { this(string AString) { super(AString); } //there is no default constructor without parameters in the base class. } TMyObjectAClass Foo(TMyObjectAClass)() if (is(TMyObjectAClass : TMyObject_A)) { return new TMyObjectAClass(TMyObjectAClass.stringof); } int main(string[] argv) { TMyObject_B B = Foo!TMyObject_B(); TMyObject_C C = Foo!TMyObject_C(); return 0; }
Jan 30 2013
parent reply dennis luehring <dl.soluz gmx.net> writes:
Am 30.01.2013 17:16, schrieb Eko Wahyudin:
 thanks all,

 I think i am understand, if the closest solution is template,
 there is no solution in D for my code like this.

 type
         TMyObjectClass = class of TMyObjectA;

 var
         ClassArray : array of TMyObjectClass; //the content
 initialized
 randomly
         ObjectArray : array of TMyObjectA;
         i, j : Integer;

 procedure CreateAllObject;
 begin
         J:= length(ClassArray);
         for I:= 0 to J do begin
           ObjectArray[I]:= ClassArray[I].Create({some argument});
         end;
 end;

 if D unable to do this, I think we must do something with D.

 I'm still thinking, why constructor in D adopt C++ style rather
 than pascal style, while pascal style is better :-?

sorry but the pascal "class of"-type and the ctor-derivation isn't that super-mighty at all as long as the ctors of your object are the same everything is fine else -> the feature isn't useable anymore, then you need a real object factory in real OOP objects are specialized through its virtual method implementations AND its ctor-parameters (which are similar in very very few rare cases) for example pseudo code class Stream virtual read_bytes()... class FileStream: Stream this(filename) class NetworkStream: Stream this(tcp_ip,timeout) Stream[] streams streams ~= FileStream("c:/temp/test.txt"); streams ~= NetworkStream("123.112.2.1", 1000); stream[n].read_bytes() this is a much more common OOP/ctor situation then yours i think its part of pascal/object delphi to ease the VCL development but this can be easily reached with an internal CreateInstance routine like Stream virtual Stream CreateInstance() and FileStream implements CreateInstance() with with return new FileStream NetworkStream "" with new NetworkStream etc. so whats the realy big deal/feature of this "class of"-type except for very trivial OOP case
Jan 30 2013
parent reply Paulo Pinto <pjmlp progtools.org> writes:
Am 30.01.2013 18:18, schrieb dennis luehring:
 Am 30.01.2013 17:16, schrieb Eko Wahyudin:
 thanks all,

 I think i am understand, if the closest solution is template,
 there is no solution in D for my code like this.

 type
         TMyObjectClass = class of TMyObjectA;

 var
         ClassArray : array of TMyObjectClass; //the content
 initialized
 randomly
         ObjectArray : array of TMyObjectA;
         i, j : Integer;

 procedure CreateAllObject;
 begin
         J:= length(ClassArray);
         for I:= 0 to J do begin
           ObjectArray[I]:= ClassArray[I].Create({some argument});
         end;
 end;

 if D unable to do this, I think we must do something with D.

 I'm still thinking, why constructor in D adopt C++ style rather
 than pascal style, while pascal style is better :-?

sorry but the pascal "class of"-type and the ctor-derivation isn't that super-mighty at all as long as the ctors of your object are the same everything is fine else -> the feature isn't useable anymore, then you need a real object factory in real OOP objects are specialized through its virtual method implementations AND its ctor-parameters (which are similar in very very few rare cases) for example pseudo code class Stream virtual read_bytes()... class FileStream: Stream this(filename) class NetworkStream: Stream this(tcp_ip,timeout) Stream[] streams streams ~= FileStream("c:/temp/test.txt"); streams ~= NetworkStream("123.112.2.1", 1000); stream[n].read_bytes() this is a much more common OOP/ctor situation then yours i think its part of pascal/object delphi to ease the VCL development but this can be easily reached with an internal CreateInstance routine like Stream virtual Stream CreateInstance() and FileStream implements CreateInstance() with with return new FileStream NetworkStream "" with new NetworkStream etc. so whats the realy big deal/feature of this "class of"-type except for very trivial OOP case

Actually there are many definitions what real OOP means. As for Delphi's case, if I am not mistaken it tries to follow the metaclass concept that Smalltalk has, and Java/.NET have to a certain extent. You can do lots of cool tricks with metaclass programming, specially in Smalltalk. -- Paulo
Jan 30 2013
parent reply dennis luehring <dl.soluz gmx.net> writes:
Am 30.01.2013 19:58, schrieb Paulo Pinto:
 Am 30.01.2013 18:18, schrieb dennis luehring:
 in real OOP objects are specialized through its virtual method
 implementations AND its ctor-parameters (which are similar in very very
 few rare cases)

 for example pseudo code

 class Stream
    virtual read_bytes()...

    class FileStream: Stream
      this(filename)

    class NetworkStream: Stream
      this(tcp_ip,timeout)

 Stream[] streams

 streams ~= FileStream("c:/temp/test.txt");
 streams ~= NetworkStream("123.112.2.1", 1000);

 stream[n].read_bytes()

 this is a much more common OOP/ctor situation then yours
 i think its part of pascal/object delphi to ease the VCL development

 but this can be easily reached with an internal CreateInstance routine like

 Stream
    virtual Stream CreateInstance()

 and
    FileStream implements CreateInstance() with with return new FileStream
    NetworkStream "" with new NetworkStream etc.

 so whats the realy big deal/feature of this "class of"-type except for
 very trivial OOP case

Actually there are many definitions what real OOP means. As for Delphi's case, if I am not mistaken it tries to follow the metaclass concept that Smalltalk has, and Java/.NET have to a certain extent.

no there aren't many definitions but many many missuse of the concept you interface is the adaptor, your virtual method code is the special behavior, your ctors parameters are the intialisers of the special behavior - everything else is just a pseudo-procedural style - its not OOP if you need to use casts and ifs on your object-type, thats procedural programming with class-based fake-namespaces can you give me a small example of the metaclass concept of smalltalk - related to my simple stream example?
Jan 30 2013
parent Paulo Pinto <pjmlp progtools.org> writes:
Am 30.01.2013 20:11, schrieb dennis luehring:
 Am 30.01.2013 19:58, schrieb Paulo Pinto:
 Am 30.01.2013 18:18, schrieb dennis luehring:
 in real OOP objects are specialized through its virtual method
 implementations AND its ctor-parameters (which are similar in very very
 few rare cases)

 for example pseudo code

 class Stream
    virtual read_bytes()...

    class FileStream: Stream
      this(filename)

    class NetworkStream: Stream
      this(tcp_ip,timeout)

 Stream[] streams

 streams ~= FileStream("c:/temp/test.txt");
 streams ~= NetworkStream("123.112.2.1", 1000);

 stream[n].read_bytes()

 this is a much more common OOP/ctor situation then yours
 i think its part of pascal/object delphi to ease the VCL development

 but this can be easily reached with an internal CreateInstance
 routine like

 Stream
    virtual Stream CreateInstance()

 and
    FileStream implements CreateInstance() with with return new
 FileStream
    NetworkStream "" with new NetworkStream etc.

 so whats the realy big deal/feature of this "class of"-type except for
 very trivial OOP case

Actually there are many definitions what real OOP means. As for Delphi's case, if I am not mistaken it tries to follow the metaclass concept that Smalltalk has, and Java/.NET have to a certain extent.

no there aren't many definitions but many many missuse of the concept

Well, Smalltalk, Simula, C++/Java/C#, OCaml, CLOS, JavaScript, BETA, Modula-3, Eiffel, Ada, Sather, and many others. All have different concepts what OO should really be. Enough material to write a few OOPSLA papers I would say.
 you interface is the adaptor, your virtual method code is the special
 behavior, your ctors parameters are the intialisers of the special
 behavior - everything else is just a pseudo-procedural style - its not
 OOP if you need to use casts and ifs on your object-type, thats
 procedural programming with class-based fake-namespaces

There I agree with you. Casts should only be a kind of last resort and are mostly a sign of bad design.
 can you give me a small example of the metaclass concept of smalltalk -
 related to my simple stream example?

Your simple example was correct, as this is not the use case of metaclasses. Maybe my post was a bit off topic. In case you are not familiar with the concept, in Smalltalk everything is an object. Every object is of course represented by a class description and you create instances of the said classes. Additionally each class also has a class that represents it. In a simple description it allows to manipulate the set of methods, instances and other information that represents the real class. It is also the container for what is known as static methods/variables in other languages. However, given Smalltalk's dynamic behavior, you can on the fly change a class's metaclass and with it simulate multiple inheritance, method call delegation or other tricks. If I am not mistaken, Objective-C and Ruby allow similar tricks, given their Smalltalk influence. -- Paulo
Jan 30 2013
prev sibling next sibling parent "Eko Wahyudin" <eko.wahyudin yahoo.co.id> writes:
thanks all,

I think i am understand, if the closest solution is template,
there is no solution in D for my code like this.

type
       TMyObjectClass = class of TMyObjectA;

var
       ClassArray : array of TMyObjectClass; //the content
initialized
randomly
       ObjectArray : array of TMyObjectA;
       i, j : Integer;

procedure CreateAllObject;
begin
       J:= length(ClassArray);
       for I:= 0 to J do begin
         ObjectArray[I]:= ClassArray[I].Create({some argument});
       end;
end;

if D unable to do this, I think we must do something with D.

I'm still thinking, why constructor in D adopt C++ style rather
than pascal style, while pascal style is better :-?
Jan 30 2013
prev sibling parent "rumbu" <rumbu rumbu.ro> writes:
On Wednesday, 30 January 2013 at 16:16:49 UTC, Eko Wahyudin wrote:
 thanks all,

 I think i am understand, if the closest solution is template,
 there is no solution in D for my code like this.

 type
       TMyObjectClass = class of TMyObjectA;

 var
       ClassArray : array of TMyObjectClass; //the content
 initialized
 randomly
       ObjectArray : array of TMyObjectA;
       i, j : Integer;

 procedure CreateAllObject;
 begin
       J:= length(ClassArray);
       for I:= 0 to J do begin
         ObjectArray[I]:= ClassArray[I].Create({some argument});
       end;
 end;

 if D unable to do this, I think we must do something with D.

 I'm still thinking, why constructor in D adopt C++ style rather
 than pascal style, while pascal style is better :-?

The only problem for translating your code is the parameterized constructor. Otherwise, your code will look in D like this an no template is involved: TypeInfo_Class[] ClassArray; TMyObjectA[] ObjectArray; void CreateAllObject() { foreach(int i = 0; i < ClassArray.length; i++) ObjectArray[i] = ClassArray[i].create(); } Anyway, you can transform your constructor parameter in a field or property and set it in the for statement for each new object.
Jan 30 2013