Jump to page: 1 2
Thread overview
Separate dynamic object arrays for multiple instances of overlying object
Mar 14
Jonathan
Mar 14
Jonathan
Mar 14
Jonathan
Mar 14
Basile B.
Mar 14
Jonathan
Mar 14
Matheus
Mar 16
matheus
Mar 14
An Pham
March 14

I'm having some trouble creating arrays that are themselves unique within multiple instances of an object. Example code:

class individual
{
    int a = 1; // placeholder for data
}

class individualList
{
    individual[] individuals;  // Something likely has to change here
}

void main()
{
    individualList list1 = new  individualList();
    assert(list1.individuals.length == 0);
    individual person1 = new individual();
    list1.individuals ~= person1;
    assert(list1.individuals.length == 1);

    individualList list2 = new individualList();
    assert(list2.individuals.length == 0); // breaks, list2.individuals.length is 1
}

I'd like the array "individuals" to be unique for each instance of individualList, but it seems to be using the same list among the different instances. The following code doesn't work as I don't know the required length of the arrays:

class individualList
{
    individual[] individuals = new individual[];  // Doesn't compile, requires length
}

I've looked a bit and don't see a solution to this within the documentation for arrays or objects.

Further information:
This is being used to parse a xml-style file, the example code is a base example, I'm having to do this list population a few times, one within another. Some lists have their count displayed before starting to add "individuals" so I could use a constructor, but some do not (to my knowledge) have that option, and I'd rather use one solution through the whole parser.

March 14
That code example works fine as is.

When you give a value to a field, it places whatever that is into the initialize state that is shared between all instances of that type.

As long as its null or allocated in a constructor, it'll work.
March 14

On Thursday, 14 March 2024 at 09:43:09 UTC, Jonathan wrote:

>

I'm having some trouble creating arrays that are themselves unique within multiple instances of an object. Example code:

class individual
{
    int a = 1; // placeholder for data
}

class individualList
{
    individual[] individuals;  // Something likely has to change here
}

void main()
{
    individualList list1 = new  individualList();
    assert(list1.individuals.length == 0);
    individual person1 = new individual();
    list1.individuals ~= person1;
    assert(list1.individuals.length == 1);

    individualList list2 = new individualList();
    assert(list2.individuals.length == 0); // breaks, list2.individuals.length is 1
}

I'd like the array "individuals" to be unique for each instance of individualList, but it seems to be using the same list among the different instances.

Shouldn't be. Each non static class member is a distinct thing in each instance of the class. They are not shared across instances. When I paste your code into run.dlang.io and add this:

    writeln(list1.individuals.length);
    writeln(list2.individuals.length);

No asserts trigger and I see this output as expected:

1
0

Is the code you pasted here exactly what you're running?

March 14

On Thursday, 14 March 2024 at 09:53:27 UTC, Mike Parker wrote:

>

On Thursday, 14 March 2024 at 09:43:09 UTC, Jonathan wrote:

>

I'm having some trouble creating arrays that are themselves unique within multiple instances of an object. Example code:

class individual
{
    int a = 1; // placeholder for data
}

class individualList
{
    individual[] individuals;  // Something likely has to change here
}

void main()
{
    individualList list1 = new  individualList();
    assert(list1.individuals.length == 0);
    individual person1 = new individual();
    list1.individuals ~= person1;
    assert(list1.individuals.length == 1);

    individualList list2 = new individualList();
    assert(list2.individuals.length == 0); // breaks, list2.individuals.length is 1
}

I'd like the array "individuals" to be unique for each instance of individualList, but it seems to be using the same list among the different instances.

Shouldn't be. Each non static class member is a distinct thing in each instance of the class. They are not shared across instances. When I paste your code into run.dlang.io and add this:

    writeln(list1.individuals.length);
    writeln(list2.individuals.length);

No asserts trigger and I see this output as expected:

1
0

Is the code you pasted here exactly what you're running?

You're right, my example code doesn't function as my nonworking code does, sorry about that.

No, this is not the same, the code that doesn't work is part of a 1000+ line parser, I thought this example would work the same. I'm trying multiple loops to get the same problem, but I'm having trouble getting it to do so. Will get back when I have a proper example.

March 14

The following seems the be the minimum required for this problem to pop up. I've changed the names to what I'm using in my code to make it more clear for me.

import std;
class SpectrumList
{
    int count = 2;
    Spectrum[] spectra;
}

class Spectrum
{
    PrecursorList precursorList = new PrecursorList();
}

class PrecursorList
{
 	int count = 3;
    Precursor[] precursors;
}

class Precursor
{
 	string a = "placeholder";
    string b = "loren ipsum";
}

void main()
{
   SpectrumList mySpectrumList = new SpectrumList;
   for(int j=0; j<mySpectrumList.count; ++j)
   {
   	    Spectrum mySpectrum = new Spectrum;
        writeln(mySpectrum.precursorList.precursors.length); // should always be 0
        assert(mySpectrum.precursorList.precursors.length == 0);
        for(int k=0; k<mySpectrum.precursorList.count; ++k)
        {
            Precursor myPrecursor = new Precursor;
            mySpectrum.precursorList.precursors ~= myPrecursor;
        }
        mySpectrumList.spectra ~= mySpectrum;
   }
}

Output from run.dlang.io:

0
3
core.exception.AssertError@onlineapp.d(32): Assertion failure
----------------
??:? [0x55676698b006]
??:? [0x55676698ac82]
??:? [0x5567669b11d6]
??:? [0x5567669927ef]
??:? [0x556766989d92]
onlineapp.d:32 [0x556766959f4c]
??:? [0x5567669924bc]
??:? [0x5567669923b6]
??:? [0x55676699220d]
/dlang/ldc-1.35.0/bin/../import/core/internal/entrypoint.d:42 [0x55676695a1d1]
??:? [0x7efc3bed5d8f]
??:? __libc_start_main [0x7efc3bed5e3f]
??:? [0x556766959c54]
Error: /tmp/onlineapp-ae55ed failed with status: 1
March 14

On Thursday, 14 March 2024 at 10:21:41 UTC, Jonathan wrote:

>

The following seems the be the minimum required for this problem to pop up. I've changed the names to what I'm using in my code to make it more clear for me.

[...]

Classic. Instead of a static initializer rather uses a constructor for instances.

class Spectrum
{
    PrecursorList precursorList;
    this()
    {
        precursorList = new PrecursorList();
    }
}
March 14

On Thursday, 14 March 2024 at 10:21:41 UTC, Jonathan wrote:

>

class Spectrum
{
PrecursorList precursorList = new PrecursorList();
}

>

void main()
{
SpectrumList mySpectrumList = new SpectrumList;
for(int j=0; j<mySpectrumList.count; ++j)
{
Spectrum mySpectrum = new Spectrum;
writeln(mySpectrum.precursorList.precursors.length); // should always be 0
assert(mySpectrum.precursorList.precursors.length == 0);
for(int k=0; k<mySpectrum.precursorList.count; ++k)
{
Precursor myPrecursor = new Precursor;
mySpectrum.precursorList.precursors ~= myPrecursor;
}
mySpectrumList.spectra ~= mySpectrum;
}

>

You encounter a gotcha unfriendly construct of D. For every "new Spectrum", there is only one instant of mySpectrum.precursorList hence for subsequence iteration, the list is already filled with myPrecursor hence the assert problem. So either move that static new to constructor or in the loop

Cheers
Happy coding

March 14

On Thursday, 14 March 2024 at 12:00:37 UTC, Basile B. wrote:

>

On Thursday, 14 March 2024 at 10:21:41 UTC, Jonathan wrote:

>

The following seems the be the minimum required for this problem to pop up. I've changed the names to what I'm using in my code to make it more clear for me.

[...]

Classic. Instead of a static initializer rather uses a constructor for instances.

class Spectrum
{
    PrecursorList precursorList;
    this()
    {
        precursorList = new PrecursorList();
    }
}

This seems to have solved the problem. This thought had crossed my mind at one point, then left before I could implement it. Really appreciate the help!

March 14
On Thursday, 14 March 2024 at 12:00:37 UTC, Basile B. wrote:
> On Thursday, 14 March 2024 at 10:21:41 UTC, Jonathan wrote:
>> The following seems the be the minimum required for this problem to pop up.  I've changed the names to what I'm using in my code to make it more clear for me.
>>
>> [...]
>
> Classic. Instead of a static initializer rather uses a constructor for instances.
>
> ```d
> class Spectrum
> {
>     PrecursorList precursorList;
>     this()
>     {
>         precursorList = new PrecursorList();
>     }
> }
> ```

I wonder how it would be if we had an error or warning for something like this. For example displaying a message forcing the use of the word "static" and initialize with "static this" when expecting static initialization or construct for new instances.

Before someone points out: https://dlang.org/spec/class.html

Yes I know, but unfortunately this mistake as Basile noted as "classic", is very common.

Matheus.
March 16
On 3/14/24 15:44, Matheus wrote:
> On Thursday, 14 March 2024 at 12:00:37 UTC, Basile B. wrote:
>> On Thursday, 14 March 2024 at 10:21:41 UTC, Jonathan wrote:
>>> The following seems the be the minimum required for this problem to pop up.  I've changed the names to what I'm using in my code to make it more clear for me.
>>>
>>> [...]
>>
>> Classic. Instead of a static initializer rather uses a constructor for instances.
>>
>> ```d
>> class Spectrum
>> {
>>     PrecursorList precursorList;
>>     this()
>>     {
>>         precursorList = new PrecursorList();
>>     }
>> }
>> ```
> 
> I wonder how it would be if we had an error or warning for something like this. For example displaying a message forcing the use of the word "static" and initialize with "static this" when expecting static initialization or construct for new instances.
> 
> Before someone points out: https://dlang.org/spec/class.html
> 
> Yes I know, but unfortunately this mistake as Basile noted as "classic", is very common.
> 
> Matheus.

Well, I guess I can still point out that this is what OpenD does:
https://github.com/opendlang/opend/pull/8
« First   ‹ Prev
1 2