Design with appender: good or bad?

Chris wendlec at tcd.ie
Thu Apr 10 06:53:45 PDT 2014


On Thursday, 10 April 2014 at 10:47:08 UTC, Rene Zwanenburg wrote:
> On Thursday, 10 April 2014 at 10:16:43 UTC, Chris wrote:
>> Ah, this one \me (= escaped me). Sorry I wasn't precise, I was 
>> wondering if it is in any way dangerous to have
>>
>> @property string[] items() {
>>  return buf.data;
>> }
>>
>> instead of:
>>
>> string[] items;
>> // ...
>> public addItem(string item) {
>>  items ~= item;
>> }
>>
>> because the two are not the same. When you print MyStruct to 
>> console you get the address of appender buf, whereas when you 
>> use string[] items you get the actual items. I'm only 
>> wondereing if using appender is potentially dangerous and 
>> could bite me later.
>
> The only thing I know of is if you store the reference returned 
> by items(), clear the appender, and add new items, the contents 
> of the previously returned slice will change too. Clearing an 
> appender is similar to setting slice length to 0 and calling 
> assumeSafeAppend on it.

Like so:

import std.stdio, std.array;

void main() {
   auto mystr1 = MyStruct1("Hello1");
   auto mystr2 = MyStruct2("Hello2");
   mystr1.addItem("World1");
   mystr2.addItem("World2");
   auto data1 = mystr1.items;
   writeln(mystr1.buf.data.length);
   auto data2 = mystr2.items;
   writeln(data1[0]);
   writeln(data2[0]);
   mystr1.clear();
   mystr2.clear();
   writeln(mystr1.buf.data.length);
   writeln(data1[0]);
   writeln(data2[0]);
   mystr1.addItem("After World 1");
   mystr2.addItem("After World 2");
   writeln(mystr1.items[0]);
   writeln(mystr2.items[0]);
   writeln(data1[0]);  // Is now After World 1
   writeln(data2[0]);  // Still is World2
}

struct MyStruct1 {
   Appender!(string[]) buf;
   string name;

   this(string name) {
     this.name = name;
     buf = appender!(string[]);
   }

   public void addItem(string item) {
     buf.put(item);
   }

   @property ref auto items() {
     return buf.data;
   }

   public void clear() {
     buf.clear();
   }
}

struct MyStruct2 {
   string[] stuff;
   string name;

   this(string name) {
     this.name = name;
   }

   public void addItem(string item) {
     stuff ~= item;
   }

   @property ref string[] items() {
     return stuff;
   }

   public void clear() {
     stuff.clear();
   }
}


More information about the Digitalmars-d-learn mailing list