www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - delegates with references to local strings

reply "Tobias Pankrath" <tobias pankrath.net> writes:
consider this:


------------
import std.stdio;
import std.string;

alias void delegate() dlgt;

int main()
{
         dlgt[] dgs;
         string[] lines = ["line A", "line B", "line C"];
         foreach(line; lines)
         {
                 writeln(line);
                 dgs ~=  { writeln(line); };
         }

         foreach(dg; dgs) { dg(); }
         return 0;
}

-----------

It prints every line in line and stores a delegate that does the 
same.
The output is:

line A
line B
line C
line C
line C
line C

I want it to print every line twice. How can I store the string 
of the current iteration with a delegate? I tried dup'ing into a 
local, which didn't help.

Thank you for your advice.
Jun 02 2012
next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Tobias Pankrath:

 How can I store the string of the current iteration with a 
 delegate?

You need to create a closure (D main returns 0 automatically): import std.stdio, std.string; void main() { auto lines = ["line A", "line B", "line C"]; void delegate()[] delegates; foreach (line; lines) { writeln(line); delegates ~= ((in string myLine) => { writeln(myLine); })(line); } foreach (deleg; delegates) deleg(); } Bye, bearophile
Jun 02 2012
prev sibling next sibling parent "Tobias Pankrath" <tobias pankrath.net> writes:
Thank you. That works.
Jun 02 2012
prev sibling parent Artur Skawina <art.08.09 gmail.com> writes:
On 06/02/12 14:01, Tobias Pankrath wrote:
 consider this:
 
 
 ------------
 import std.stdio;
 import std.string;
 
 alias void delegate() dlgt;
 
 int main()
 {
         dlgt[] dgs;
         string[] lines = ["line A", "line B", "line C"];
         foreach(line; lines)
         {
                 writeln(line);
                 dgs ~=  { writeln(line); };
         }
 
         foreach(dg; dgs) { dg(); }
         return 0;
 }
 
 -----------
 
 It prints every line in line and stores a delegate that does the same.
 The output is:
 
 line A
 line B
 line C
 line C
 line C
 line C
 
 I want it to print every line twice. How can I store the string of the current
iteration with a delegate? I tried dup'ing into a local, which didn't help.

dgs ~= (string l) { return { writeln(l); }; }(line); This isn't really much different from http://d.puremagic.com/issues/show_bug.cgi?id=2043 but I'm not convinced the compiler should be cloning the variables here (ie if that "bug" really is a bug); it certainly can be surprising though. artur
Jun 02 2012