www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Problems with OutputRanges

reply "Meta" <jared771 gmail.com> writes:
I'm not sure what I'm doing wrong... the following code prints 
nothing:

void main()
{
     import std.stdio, std.range;
	
     string str = "asdf";
     auto sink = new dchar[](str.length);
     auto fun = (dchar c) { sink.put(c); };
     foreach (dchar c; str)
     {
         fun(c);
     }
     writeln(sink);
}

If I print sink's length inside the foreach loop, its length is 
reduced by 1 each step, until it's 0. That explains why nothing 
is being printed, but why is put altering the length of the array?
Mar 24 2014
parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 03/24/2014 07:42 PM, Meta wrote:

 I'm not sure what I'm doing wrong... the following code prints nothing:

 void main()
 {
      import std.stdio, std.range;

      string str = "asdf";
      auto sink = new dchar[](str.length);
      auto fun = (dchar c) { sink.put(c); };
      foreach (dchar c; str)
      {
          fun(c);
      }
      writeln(sink);
 }

 If I print sink's length inside the foreach loop, its length is reduced
 by 1 each step, until it's 0. That explains why nothing is being
 printed, but why is put altering the length of the array?
Very many things can be output ranges depending on what operations they support: http://dlang.org/phobos/std_range.html#.put sink above is a slice, matching "if R defines put, r.front = e if r is an input range (followed by r.popFront())" in the above document. That's popFront() in that excerpt that is causing the loss of element here. I have a more detailed explanation of this under the "Using slices as OutputRange" section in the following chapter: http://ddili.org/ders/d.en/ranges.html So, one of the solutions here is to use a surrogate slice instead: auto sinkSurrogate = sink; auto fun = (dchar c) { sinkSurrogate.put(c); }; Now, sinkSurrogate will lose elements and sink will still be usable. Ali
Mar 24 2014