digitalmars.D.learn - writeln, alias this and dynamic arrays.
- matthewh (45/45) Nov 16 2017 I am new to D and have been fiddling with bits and pieces.
- Michael V. Franklin (6/9) Nov 16 2017 I think that is due to this bug:
- Michael V. Franklin (6/15) Nov 16 2017 Actually, after playing with your example, I don't think that's
- Michael V. Franklin (5/15) Nov 16 2017 Actually, it looks like it's this 4-year old bug.
- Adam D. Ruppe (14/16) Nov 17 2017 Yeah, I suspected this is old and my comment in there still
- Steven Schveighoffer (35/49) Nov 17 2017 In doing some digging, I found that it actually calls the object version...
- matthewh (2/2) Nov 22 2017 Thank you all for the helpful responses.
I am new to D and have been fiddling with bits and pieces. I have this code: import std.stdio : writeln; import std.format : format; class Base { override { //string toString() //{ // return format("%s", store); //} } ubyte[] store; alias store this; this() { store = [1, 2, 3, 4, 5, 6, 7, 8]; } } class Top { Base store; alias store this; this() { store = new Base; } } void main() { auto f = new Top; writeln(f.store); writeln(f.store); } as is it produces: [1, 2, 3, 4, 5, 6, 7, 8] [] I expected it to produce: [1, 2, 3, 4, 5, 6, 7, 8] [1, 2, 3, 4, 5, 6, 7, 8] And with the toString override included it does. Why does the version without the toString override output an empty array? Thank you.
Nov 16 2017
On Friday, 17 November 2017 at 02:13:54 UTC, matthewh wrote:And with the toString override included it does. Why does the version without the toString override output an empty array?I think that is due to this bug: https://issues.dlang.org/show_bug.cgi?id=13189 It's actually on my todo list to fix, but I'm not sure yet if its within my current abilities. Mike
Nov 16 2017
On Friday, 17 November 2017 at 02:16:35 UTC, Michael V. Franklin wrote:On Friday, 17 November 2017 at 02:13:54 UTC, matthewh wrote:Actually, after playing with your example, I don't think that's the case. There's something else going on, and I'm not sure what it is. It's a strange error indeed. MikeAnd with the toString override included it does. Why does the version without the toString override output an empty array?I think that is due to this bug: https://issues.dlang.org/show_bug.cgi?id=13189 It's actually on my todo list to fix, but I'm not sure yet if its within my current abilities.
Nov 16 2017
On Friday, 17 November 2017 at 02:13:54 UTC, matthewh wrote:[...] as is it produces: [1, 2, 3, 4, 5, 6, 7, 8] [] I expected it to produce: [1, 2, 3, 4, 5, 6, 7, 8] [1, 2, 3, 4, 5, 6, 7, 8] And with the toString override included it does. Why does the version without the toString override output an empty array?Actually, it looks like it's this 4-year old bug. https://issues.dlang.org/show_bug.cgi?id=9506 So frustrating :( Mike
Nov 16 2017
On Friday, 17 November 2017 at 06:57:16 UTC, Michael V. Franklin wrote:Actually, it looks like it's this 4-year old bug. https://issues.dlang.org/show_bug.cgi?id=9506Yeah, I suspected this is old and my comment in there still applies... It passes the isInputRange test due to the implicit conversion of alias this, and then writeln takes it and consumes it. One thing you might consider is making the alias this go to a getter property instead of the method directly. Then operations on it will work on a copy of the slice, and thus not consume the original one. But then you can't do stuff like append do it directly either... imo writeln should check for .save and use it. But meh I don't care to personally bother fixing it and apparently nobody else does either.
Nov 17 2017
On 11/17/17 8:13 AM, Adam D. Ruppe wrote:On Friday, 17 November 2017 at 06:57:16 UTC, Michael V. Franklin wrote:In doing some digging, I found that it actually calls the object version of formatValue. Which is specifically written to check if Object.toString has been overridden. If not, and it has a range interface, it treats it as a range. So this is not a bug. By using alias this against a range, you have turned it into a range interface.Actually, it looks like it's this 4-year old bug. https://issues.dlang.org/show_bug.cgi?id=9506Yeah, I suspected this is old and my comment in there still applies... It passes the isInputRange test due to the implicit conversion of alias this, and then writeln takes it and consumes it.One thing you might consider is making the alias this go to a getter property instead of the method directly. Then operations on it will work on a copy of the slice, and thus not consume the original one. But then you can't do stuff like append do it directly either...It doesn't work, I tried that. The reason is because, for arrays, popFront requires an lvalue (obviously), and so isInputRange for such a class is false. It just prints the class name, like a normal class. Ironically, alias this to a struct range type (like say filter), would be even more disastrous: class C(R) { R foo; R getFoo() { return foo; } alias getFoo this; } auto f = [1, 2, 3, 4].filter!"a & 1"; auto c = new C!(typeof(f)); c.foo = f; writeln(c);// [1, 1, 1, 1, 1, 1,.... This is because C.getFoo.popFront works, even though it's an rvalue! I don't think there's a way to figure out this situation and properly deal with it. My recommendation is basically, don't do this. It's not going to work like you expect.imo writeln should check for .save and use it. But meh I don't care to personally bother fixing it and apparently nobody else does either..save isn't even properly implemented. It must return the same type as the original. e.g.: static assert(!isForwardRange!C); Jonathan has talked about this, and I agree with him. The only real way to fix forward ranges is to get rid of save, and make copyability the thing that makes a forward range a forward range. But that's not going to happen, too disruptive. -Steve
Nov 17 2017
Thank you all for the helpful responses. I will read more about ranges.
Nov 22 2017