Delegate function access to classes local variable

Colin Grogan grogan.colin at gmail.com
Sun Nov 10 12:03:05 PST 2013


On Friday, 8 November 2013 at 13:19:05 UTC, Colin Grogan wrote:
> On Friday, 8 November 2013 at 13:14:33 UTC, Timon Gehr wrote:
>> On 11/08/2013 01:43 PM, Colin Grogan wrote:
>>> Hi folks,
>>>
>>> I'm having some issue getting a delegate function access to a 
>>> classes
>>> member variable.
>>>
>>> At object construct time, I'm passing in a delegate function, 
>>> and a list
>>> of parameters after.
>>> The parameters are saved to a variable called vars.
>>> Should I then not be able to access that vars variable from 
>>> inside my
>>> delegate function?
>>>
>>> I guess some code is a better explanation:
>>> import std.stdio;
>>> void main()
>>> {
>>>    Column!string col1 = new Column!string( {return "test"; }, 
>>> "Hello, ");
>>>    Column!string col2 = new Column!string( {return vars[0]; },
>>> "World"); // Compilation fail!! Delegate cant see vars[0]
>>
>> It is not even in scope here.
>>
>>>    writef("%s", col1.nextValue);
>>>    writefln("%s", col2.nextValue);
>>> // I want it to print "Hello, World" here
>>> }
>>>
>>> public class Column(Vars...){
>>>    private Vars vars;
>>>    public string delegate() func;
>>>
>>>    public this(string delegate() func, Vars vars){
>>>        this.vars = vars;
>>>        this.func = func;
>>>    }
>>>
>>>    public string nextValue(){
>>>        return this.func();
>>>    }
>>> }
>>>
>>>
>>> The compilation error is:
>>> source/app.d(5): Error: undefined identifier vars
>>>
>>> This has been wrecking my head for a couple days now, I'm 
>>> half way
>>> resigned to the fact it cant work but said I'd ask here to be 
>>> sure.
>>>
>>> Thanks!
>>
>> import std.stdio;
>> void main(){
>>    Column!string col1 = new Column!string((ref m)=>"Hello, ", 
>> "test");
>>    Column!string col2 = new Column!string((ref m)=>m.vars[0], 
>> "World");
>>    writef("%s", col1.nextValue);
>>    writefln("%s", col2.nextValue);
>> }
>>
>> public class Column(Vars...){
>>    struct Members{ Vars vars; }
>>    private Members members;
>>    alias members this;
>>    string delegate(ref Members) func;
>>
>>    this(string delegate(ref Members) func, Vars vars){
>>        this.vars = vars;
>>        this.func = func;
>>    }
>>
>>    string nextValue(){
>>        return func(members);
>>    }
>> }
>
>
> Ah, brilliant! I like that construct.
> Thank you!

My optimism may have been premature.
After trying this out today, I havent been able to pass in 
anything more complex than a 1 line to the constructor.

For example,
     Column!(int, int) randonNumberColumn = new Column!(int, 
int)((ref m)=>to!string(uniform(m.vars[0], m.vars[1])), 1, 10);

will work.
However,
     Column!(int, int) incrementalNumberColumn = new Column!(int, 
int)((ref m)=>{m.vars[0]+=m.vars[1]; return 
to!string(m.vars[0]-m.vars[1]);}, 1,2);

wont.

Maybe my syntax is just wrong or this is simply a limitation?

Also, if you could explain what the => operator is doing there 
that would be great. I couldnt find the info on it in the docs...


More information about the Digitalmars-d-learn mailing list