Thread overview
Properties and std.container.Array
Jan 09, 2014
Frustrated
Jan 09, 2014
Frustrated
Jan 09, 2014
Frustrated
Jan 09, 2014
Dicebot
Jan 09, 2014
monarch_dodra
Jan 09, 2014
Frustrated
Jan 09, 2014
Frustrated
January 09, 2014
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?

January 09, 2014
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.
January 09, 2014
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?


January 09, 2014
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; }
January 09, 2014
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.
January 09, 2014
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.
January 09, 2014
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)