Thread overview
Re: Facing problems with Class Properties
Dec 10, 2010
Jesse Phillips
Dec 11, 2010
d coder
Dec 11, 2010
d coder
Dec 11, 2010
d coder
Dec 11, 2010
Jesse Phillips
Dec 11, 2010
spir
December 10, 2010
Jesse Phillips Wrote:

> typeof() and is() are compile time constructs. Change your if statements to
> static if.

Just realized what the issue is. You are creating code as foreach becomes a static foreach when iterating a tupleof. (Yes steven it does work)

This you are building code which looks like

if(false) {
    for (size_t j = 0; j < f.length...)
    ...
}

Semantically this code is wrong as you can't take the length of f which is class Bar. The static if forces the compiler to not generate this code as it is known to be false.
December 10, 2010
On Fri, 10 Dec 2010 15:08:34 -0500, Jesse Phillips <jessekphillips+D@gmail.com> wrote:

> Jesse Phillips Wrote:
>
>> typeof() and is() are compile time constructs. Change your if statements to
>> static if.
>
> Just realized what the issue is. You are creating code as foreach becomes a static foreach when iterating a tupleof. (Yes steven it does work)

Ah, good to know :)

-Steve
December 11, 2010
> if(false) {
>    for (size_t j = 0; j < f.length...)
>    ...
> }
>
> Semantically this code is wrong as you can't take the length of f which is class Bar. The static if forces the compiler to not generate this code as it is known to be false.
>

Thanks Jesse

What you are saying makes sense to me. The problem is that the following code works perfectly. I have just commented out some part and replaced it with some debug statements.

The output from this code makes me believe that "is" and "typeof" do have some run-time semantics. Or is it a D2 bug. BTW I am using Digital Mars D Compiler v2.050.

Regards
- Puneet

import std.stdio;
class BaseClass { }

class Bar: BaseClass { }

class Foo: BaseClass {
  this() {
    foreach(i, f; this.tupleof) {
      if (is (typeof(this.tupleof[i]) : BaseClass[])) {
	writeln("Creating new objects for all ARRAY types ", this.tupleof[i].stringof);
	// for (size_t j = 0; j < this.tupleof[i].length; ++j) {
	//   this.tupleof[i][j] = new typeof(this.tupleof[i][j]) ();
	// }
      }
      if (is(typeof(this.tupleof[i]) : BaseClass)) {
	writeln("Creating new objects for all NON-ARRAY types ",
this.tupleof[i].stringof);
	// this.tupleof[i] = new typeof(this.tupleof[i]) ();
      }
    }
  }
  Bar instance1;
  Bar instance2;
  Bar [10] instances;
}

unittest {
  Foo foo;
  foo = new Foo;
}

// I am getting the following output
// Creating new objects for all NON-ARRAY types this.instance1
// Creating new objects for all NON-ARRAY types this.instance2
// Creating new objects for all ARRAY types this.instances
December 11, 2010
> What you are saying makes sense to me. The problem is that the following code works perfectly. I have just commented out some part and replaced it with some debug statements.

Ah.. Now I think I understand.

This new code I have written will all be run at compile time. So in this case, the foreach statement inside the constructor would be reduced to a bunch of writeln statements at compile time and those writeln would be executed at the run time. This will not happen with the actual code since there are other typeof and is statements in there that can not be run at runtime.

Did I get it right?
December 11, 2010
> Ah.. Now I think I understand.
>
> This new code I have written will all be run at compile time. So in this case, the foreach statement inside the constructor would be reduced to a bunch of writeln statements at compile time and those writeln would be executed at the run time. This will not happen with the actual code since there are other typeof and is statements in there that can not be run at runtime.
>
> Did I get it right?
>

If I got it right now, It will be possible for me to unroll the
foreach loop and the if statements in a mixin and that would work
well.
Or may be changing the "if" statement to "static if" would do the
trick. I will give it a try.

Thank you Steve and tank you Jesse for showing me the light.

Regards
- Cherry
December 11, 2010
d coder Wrote:

> > Ah.. Now I think I understand.
> >
> > This new code I have written will all be run at compile time. So in this case, the foreach statement inside the constructor would be reduced to a bunch of writeln statements at compile time and those writeln would be executed at the run time. This will not happen with the actual code since there are other typeof and is statements in there that can not be run at runtime.

Yes, but the if statement will also be there so the code would look something like:

if(true)
    writeln(...)

if(false)
    writeln(...)
...

> If I got it right now, It will be possible for me to unroll the
> foreach loop and the if statements in a mixin and that would work
> well.
> Or may be changing the "if" statement to "static if" would do the
> trick. I will give it a try.

Static if must be done so that invalid code is not generated. As for another part of what you want. Use std.range.ElementType so that you can get the type you wish to call new for:

           this.tupleof[i][j] = new ElementType!(this.tupleof[i])();

December 11, 2010
On Sat, 11 Dec 2010 06:11:43 +0530
d coder <dlang.coder@gmail.com> wrote:

> > if(false) {
> >    for (size_t j = 0; j < f.length...)
> >    ...
> > }
> >
> > Semantically this code is wrong as you can't take the length of f which is class Bar. The static if forces the compiler to not generate this code as it is known to be false.
> >
> 
> Thanks Jesse
> 
> What you are saying makes sense to me. The problem is that the following code works perfectly. I have just commented out some part and replaced it with some debug statements.
> 
> The output from this code makes me believe that "is" and "typeof" do have some run-time semantics. Or is it a D2 bug. BTW I am using Digital Mars D Compiler v2.050.
> 
> Regards
> - Puneet
> 
> import std.stdio;
> class BaseClass { }
> 
> class Bar: BaseClass { }
> 
> class Foo: BaseClass {
>   this() {
>     foreach(i, f; this.tupleof) {
>       if (is (typeof(this.tupleof[i]) : BaseClass[])) {
> 	writeln("Creating new objects for all ARRAY types ", this.tupleof[i].stringof);
> 	// for (size_t j = 0; j < this.tupleof[i].length; ++j) {
> 	//   this.tupleof[i][j] = new typeof(this.tupleof[i][j]) ();
> 	// }
>       }
>       if (is(typeof(this.tupleof[i]) : BaseClass)) {
> 	writeln("Creating new objects for all NON-ARRAY types ",
> this.tupleof[i].stringof);
> 	// this.tupleof[i] = new typeof(this.tupleof[i]) ();
>       }
>     }
>   }
>   Bar instance1;
>   Bar instance2;
>   Bar [10] instances;
> }
> 
> unittest {
>   Foo foo;
>   foo = new Foo;
> }
> 
> // I am getting the following output
> // Creating new objects for all NON-ARRAY types this.instance1
> // Creating new objects for all NON-ARRAY types this.instance2
> // Creating new objects for all ARRAY types this.instances

Hello "d coder",


Maybe this is wrong and stupid, but I have faced several times similar cases ; meaning cases whare I perfectly knew (and D as well should have known ;-) that a given thing was of given type, but could not access its slots.
Try and downcast 'this.tupeof[i]' to the type that has a 'length'; if I'm right, you're done. (I find this wrong, buggy, & ugly, but well...) Else, sorry for the noise.

Denis
-- -- -- -- -- -- --
vit esse estrany ☣

spir.wikidot.com