www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Properties and std.container.Array

reply "Frustrated" <c1514843 drdrb.com> writes:
I've tried insert, indexing, ~=, etc but the length always 
returns 0.

e.g.,

std.container.Array!int arr;
arr ~= 3;
writeln(arr.length);

works fine, but when the array is a property of a class, it does 
not work, e.g.,

class x
{
std.container.Array!int _arr;
 property std.container.Array!int arr() { return _arr; }
 property std.container.Array!int arr(std.container.Array!int a) 
{_arr = a; return _arr; }
}

if I use _arr directly then everything works.

Why are properties screwing up std.container.Array?
Jan 09 2014
parent reply "Frustrated" <c1514843 drdrb.com> writes:
On Thursday, 9 January 2014 at 12:13:14 UTC, Frustrated wrote:
 I've tried insert, indexing, ~=, etc but the length always 
 returns 0.

 e.g.,

 std.container.Array!int arr;
 arr ~= 3;
 writeln(arr.length);

 works fine, but when the array is a property of a class, it 
 does not work, e.g.,

 class x
 {
 std.container.Array!int _arr;
  property std.container.Array!int arr() { return _arr; }
  property std.container.Array!int arr(std.container.Array!int 
 a) {_arr = a; return _arr; }
 }

 if I use _arr directly then everything works.

 Why are properties screwing up std.container.Array?
I should also mention that if I simply assign the arr property to a local variable before I use it everything works but this is not the way things should work.
Jan 09 2014
parent reply "Frustrated" <c1514843 drdrb.com> writes:
On Thursday, 9 January 2014 at 12:15:31 UTC, Frustrated wrote:
 On Thursday, 9 January 2014 at 12:13:14 UTC, Frustrated wrote:
 I've tried insert, indexing, ~=, etc but the length always 
 returns 0.

 e.g.,

 std.container.Array!int arr;
 arr ~= 3;
 writeln(arr.length);

 works fine, but when the array is a property of a class, it 
 does not work, e.g.,

 class x
 {
 std.container.Array!int _arr;
  property std.container.Array!int arr() { return _arr; }
  property std.container.Array!int arr(std.container.Array!int 
 a) {_arr = a; return _arr; }
 }

 if I use _arr directly then everything works.

 Why are properties screwing up std.container.Array?
I should also mention that if I simply assign the arr property to a local variable before I use it everything works but this is not the way things should work.
I guess I see what is going on. Since Array is a struct, a local copy is made and that never ends up updating the original? How can I use it then like an object so this is not a problem?
Jan 09 2014
parent reply "Dicebot" <public dicebot.lv> writes:
On Thursday, 9 January 2014 at 12:19:25 UTC, Frustrated wrote:
 I guess I see what is going on. Since Array is a struct, a 
 local copy is made and that never ends up updating the original?

 How can I use it then like an object so this is not a problem?
returning by ref may do what you want: property std.container.Array!int arr() { return _arr; } -> property ref std.container.Array!int arr() { return _arr; }
Jan 09 2014
parent reply "monarch_dodra" <monarchdodra gmail.com> writes:
On Thursday, 9 January 2014 at 13:32:08 UTC, Dicebot wrote:
 On Thursday, 9 January 2014 at 12:19:25 UTC, Frustrated wrote:
 I guess I see what is going on. Since Array is a struct, a 
 local copy is made and that never ends up updating the 
 original?

 How can I use it then like an object so this is not a problem?
returning by ref may do what you want: property std.container.Array!int arr() { return _arr; } -> property ref std.container.Array!int arr() { return _arr; }
As dicebot says, however, the issue is a bit more subtle. An `Array` is actually little more than a pointer to a payload. Passing by value is "almost" free, and updating a copy *should* update the original... ...that is, if it wasn't for the "Gotcha" that the `Array` needs to be initialized first. But overall, by ref should be just fine.
Jan 09 2014
parent reply "Frustrated" <c1514843 drdrb.com> writes:
On Thursday, 9 January 2014 at 14:51:33 UTC, monarch_dodra wrote:
 On Thursday, 9 January 2014 at 13:32:08 UTC, Dicebot wrote:
 On Thursday, 9 January 2014 at 12:19:25 UTC, Frustrated wrote:
 I guess I see what is going on. Since Array is a struct, a 
 local copy is made and that never ends up updating the 
 original?

 How can I use it then like an object so this is not a problem?
returning by ref may do what you want: property std.container.Array!int arr() { return _arr; } -> property ref std.container.Array!int arr() { return _arr; }
As dicebot says, however, the issue is a bit more subtle. An `Array` is actually little more than a pointer to a payload. Passing by value is "almost" free, and updating a copy *should* update the original... ...that is, if it wasn't for the "Gotcha" that the `Array` needs to be initialized first. But overall, by ref should be just fine.
I thought about using ref after the fact. It is a significant rework of my code but it does seem to work. I am not initializing the Arrays. It seems that a better approach maybe to wrap the Array in a class and use alias this? If Array does need to be initialized(seems to work fine without it but maybe a memory leak?) this could be done in the class. What I worry about is end up with a bunch of copies of the array and none of them updated properly. It doesn't seem quite right to have it as a struct.
Jan 09 2014
parent "Frustrated" <c1514843 drdrb.com> writes:
I think maybe using alias this would not solve the problem? One 
would have to dispatch all the calls on the class to the array. 
(simply wrap the struct but prevent the compiler from thinking it 
is a strut so it doesn't use value semantics on it)
Jan 09 2014