www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Facing problems with Class Properties

reply d coder <dlang.coder gmail.com> writes:
--000e0cd32f648778c7049710f24f
Content-Type: text/plain; charset=ISO-8859-1

Greetings All

I am trying to compile the following D2 code. The code giving compilation
issues is the "this()" function of the class Foo. The constructor basically
tries to initialize all the data members of the class, of type BaseClass and
of type BaseClass array.

I am using class property tupleof to iterate over members of the class. Then
I check the type of each member and if the member is a BaseClass array, I
new all the elements of the array. Otherwise if the member is of the type
BaseClass, I new it as it is.

The issue is that when I try to compile the program, I get the error
bug.d(10): Error: no property 'length' for type 'test.Bar'

I am explicitly checking the field type, and I am making sure that the field
is an array type, before looking for its length. So I am not sure why this
error appears. Please guide me.

Regards
Cherry

import std.stdio;
class BaseClass { }

class Bar: BaseClass { }

class Foo: BaseClass {
  this() {
    foreach(i, f; this.tupleof) {
      if (is (typeof(f) : BaseClass[])) {
for (size_t j = 0; j < f.length; ++j) {
  f[j] = new typeof(f[j]) ();
}
      }
      if (is(typeof(f) : BaseClass)) {
f = new typeof(f) ();
      }
    }
  }
  Bar instance1;
  Bar instance2;
  Bar [10] instances;
}

unittest {
  Foo foo;
  foo = new Foo;
}

--000e0cd32f648778c7049710f24f
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div>Greetings All</div><div><br></div><div>I am trying to compile the foll=
owing D2 code. The code giving compilation issues is the &quot;this()&quot;=
 function of the class Foo. The constructor basically tries to initialize a=
ll the data members of the class, of type BaseClass and of type BaseClass a=
rray.</div>
<div><br></div><div>I am using class property tupleof to iterate over membe=
rs of the class. Then I check the type of each member and if the member is =
a BaseClass array, I new all the elements of the array. Otherwise if the me=
mber is of the type BaseClass, I new it as it is.</div>
<div><br></div><div>The issue is that when I try to compile the program, I =
get the error</div><div><div>bug.d(10): Error: no property &#39;length&#39;=
 for type &#39;test.Bar&#39;</div></div><div><br></div><div>I am explicitly=
 checking the field type, and I am making sure that the field is an array t=
ype, before looking for its length. So I am not sure why this error appears=
. Please guide me.</div>
<div><br></div><div>Regards</div><div>Cherry</div><div><br></div><div>impor=
t std.stdio;</div><div>class BaseClass { }</div><div><br></div><div>class B=
ar: BaseClass { }</div><div><br></div><div>class Foo: BaseClass {</div>
<div>=A0=A0this() {</div><div>=A0=A0 =A0foreach(i, f; this.tupleof) {</div>=
<div>=A0=A0 =A0 =A0if (is (typeof(f) : BaseClass[])) {</div><div><span clas=
s=3D"Apple-tab-span" style=3D"white-space:pre">	</span>for (size_t j =3D 0;=
 j &lt; f.length; ++j) {</div>
<div><span class=3D"Apple-tab-span" style=3D"white-space:pre">	</span> =A0f=
[j] =3D new typeof(f[j]) ();</div><div><span class=3D"Apple-tab-span" style=
=3D"white-space:pre">	</span>}</div><div>=A0=A0 =A0 =A0}</div><div>=A0=A0 =
=A0 =A0if (is(typeof(f) : BaseClass)) {</div>
<div><span class=3D"Apple-tab-span" style=3D"white-space:pre">	</span>f =3D=
 new typeof(f) ();</div><div>=A0=A0 =A0 =A0}</div><div>=A0=A0 =A0}</div><di=
v>=A0=A0}</div><div>=A0=A0Bar instance1;</div><div>=A0=A0Bar instance2;</di=
v><div>=A0=A0Bar [10] instances;</div>
<div>}</div><div><br></div><div>unittest {</div><div>=A0=A0Foo foo;</div><d=
iv>=A0=A0foo =3D new Foo;</div><div>}</div>

--000e0cd32f648778c7049710f24f--
Dec 10 2010
next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 10 Dec 2010 11:35:50 -0500, d coder <dlang.coder gmail.com> wrote:

 Greetings All

 I am trying to compile the following D2 code. The code giving compilation
 issues is the "this()" function of the class Foo. The constructor  
 basically
 tries to initialize all the data members of the class, of type BaseClass  
 and
 of type BaseClass array.

 I am using class property tupleof to iterate over members of the class.  
 Then
 I check the type of each member and if the member is a BaseClass array, I
 new all the elements of the array. Otherwise if the member is of the type
 BaseClass, I new it as it is.

 The issue is that when I try to compile the program, I get the error
 bug.d(10): Error: no property 'length' for type 'test.Bar'

 I am explicitly checking the field type, and I am making sure that the  
 field
 is an array type, before looking for its length. So I am not sure why  
 this
 error appears. Please guide me.

 Regards
 Cherry

 import std.stdio;
 class BaseClass { }

 class Bar: BaseClass { }

 class Foo: BaseClass {
   this() {
     foreach(i, f; this.tupleof) {
       if (is (typeof(f) : BaseClass[])) {
 for (size_t j = 0; j < f.length; ++j) {
   f[j] = new typeof(f[j]) ();
 }
       }
       if (is(typeof(f) : BaseClass)) {
 f = new typeof(f) ();
       }
     }
   }
   Bar instance1;
   Bar instance2;
   Bar [10] instances;
 }

 unittest {
   Foo foo;
   foo = new Foo;
 }

is(typeof(f) : BaseClass[]) is a compile-time construct, yet you are trying to use it at runtime. I'm not even sure how this could compile. I imagine that you could use a recursive template to deal with the tuple, but I didn't think you could use a foreach loop. Is there a reason you can't directly reference the members? After all, you are writing the class. Another thing, is(T : U) simply means T is implicitly castable to U. Due to a compiler bug, Bar[] is implicitly castable to BaseClass[]. is(T == U) ensures that the type is exact. -Steve
Dec 10 2010
prev sibling next sibling parent Jesse Phillips <jessekphillips+D gmail.com> writes:
d coder Wrote:

 The issue is that when I try to compile the program, I get the error
 bug.d(10): Error: no property 'length' for type 'test.Bar'
 
 I am explicitly checking the field type, and I am making sure that the field
 is an array type, before looking for its length. So I am not sure why this
 error appears. Please guide me.
 
 Regards
 Cherry
 
 import std.stdio;
 class BaseClass { }
 
 class Bar: BaseClass { }
 
 class Foo: BaseClass {
   this() {
     foreach(i, f; this.tupleof) {
       if (is (typeof(f) : BaseClass[])) {
 for (size_t j = 0; j < f.length; ++j) {
   f[j] = new typeof(f[j]) ();
 }
       }
       if (is(typeof(f) : BaseClass)) {
 f = new typeof(f) ();
       }
     }
   }
   Bar instance1;
   Bar instance2;
   Bar [10] instances;
 }
 
 unittest {
   Foo foo;
   foo = new Foo;
 }

typeof() and is() are compile time constructs. Change your if statements to static if.
Dec 10 2010
prev sibling next sibling parent d coder <dlang.coder gmail.com> writes:
 Is there a reason you can't directly reference the members? =A0After all,=

 are writing the class.

Thanks Steve for your inputs. Actually this is part of a bigger code that I am trying to create. Though I am pretty new to D. What I have posted is a reduced code that illustrated the issue I am facing. In the actual code, I am using string mixins and there are too many classes (all derived from BaseClass) and too many class instances, and the constructor call for Bar (and other classes) is a bit more involved. There is a need to make sure that all the constructors are called in a seamless fashion. In fact, I will not be the end-user. I would just be coding the BaseClass and the mixin. The actual end-users are not supposed to be quite D-literate and I would be asking them to code something to the effect: class Foo: BaseClass { mixin(CreateInstances()); // Define your Bar and other sub-class instances here //... // More code here } Any ideas? Regards - Cherry
Dec 10 2010
prev sibling next sibling parent d coder <dlang.coder gmail.com> writes:
 Another thing, is(T : U) simply means T is implicitly castable to U. =A0D=

 a compiler bug, Bar[] is implicitly castable to BaseClass[].

Steve I realize that I am using this compiler bug as a feature. It would be kind of you to suggest me a code that would not exploit this bug. I was thinking of using something to the effect: if (__traits(isStaticArray, this.tupleof[i]) { if (is (typeof(this.tupleof[i][0]) : BaseModule)) { Regards - Cherry
Dec 10 2010
prev sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 10 Dec 2010 20:22:52 -0500, d coder <dlang.coder gmail.com> wrote:

 Another thing, is(T : U) simply means T is implicitly castable to U.  
  Due to
 a compiler bug, Bar[] is implicitly castable to BaseClass[].

Steve I realize that I am using this compiler bug as a feature. It would be kind of you to suggest me a code that would not exploit this bug. I was thinking of using something to the effect: if (__traits(isStaticArray, this.tupleof[i]) { if (is (typeof(this.tupleof[i][0]) : BaseModule)) {

Just use is(T == U) instead of is(T : U) -Steve
Dec 13 2010