Thread overview
delegates with references to local strings
Jun 02, 2012
Tobias Pankrath
Jun 02, 2012
bearophile
Jun 02, 2012
Tobias Pankrath
Jun 02, 2012
Artur Skawina
June 02, 2012
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.


June 02, 2012
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
June 02, 2012
Thank you. That works.
June 02, 2012
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