On Thu, Apr 19, 2012 at 7:25 AM, Christophe <span dir="ltr"><<a href="mailto:travert@phare.normalesup.org">travert@phare.normalesup.org</a>></span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
"Brad Anderson" , dans le message (digitalmars.D.learn:34902), a écrit :<br>
<div class="im">> Perhaps I'm just misunderstanding something about closures but<br>
> the following code seems to behave oddly:<br>
><br>
>      import std.stdio, std.range, std.algorithm, std.string;<br>
><br>
>      void main()<br>
>      {<br>
>          auto lst = ["a", "b"];<br>
>          auto rng = range_gen(lst);<br>
>          writeln(rng.take(5));<br>
>      }<br>
>      auto range_gen(string[] lst)<br>
>      {<br>
>          auto a = sequence!"n+1"().map!(a=>format("%s%d", lst[0],<br>
> a))();<br>
>          return chain(lst, a); // access violation<br>
>          //return a; // works<br>
>      }<br>
<br>
</div>My guess is that chain takes lst by reference, just like the delegates<br>
for map, wo both are working on the same slice instance. The chain first<br>
pops elements from lst, and then calls the mapped sequence. At that<br>
time, lst is empty.<br>
<br>
You can just copy lst before you give it to chain (or to map's delegate)<br>
to solve this bug:<br>
<div class="im"><br>
auto range_gen(string[] lst)<br>
{<br>
     auto a = sequence!"n+1"().map!(a=>format("%s%d", lst[0], a))();<br>
</div>     string[] lst2 = lst;<br>
     return chain(lst2, a); // access violation<br>
}<br>
<br>
</blockquote></div><br><div>Ah, that would make sense.  I'll test and make sure when I get home. Range consumption tricks me more often than I wish.  I'll eventually learn to look out for it more actively.</div><div>
<br></div><div>Regards,</div><div>Brad Anderson</div>