Thread overview | |||||||||
---|---|---|---|---|---|---|---|---|---|
|
November 08, 2013 Delegate function access to classes local variable | ||||
---|---|---|---|---|
| ||||
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] 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! |
November 08, 2013 Re: Delegate function access to classes local variable | ||||
---|---|---|---|---|
| ||||
Posted in reply to Colin Grogan | On Friday, 8 November 2013 at 12:43:37 UTC, Colin Grogan wrote:
> 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]
> writef("%s", col1.nextValue);
> writefln("%s", col2.nextValue);
> // I want it to print "Hello, World" here
> }
Delegate refers to context it was created in. Your delegates are created in `main()` scope/context and thus can only access its stack frame. You can't access caller context from delegates.
|
November 08, 2013 Re: Delegate function access to classes local variable | ||||
---|---|---|---|---|
| ||||
Posted in reply to Colin Grogan | 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); } } |
November 08, 2013 Re: Delegate function access to classes local variable | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dicebot | On Friday, 8 November 2013 at 13:10:10 UTC, Dicebot wrote:
> On Friday, 8 November 2013 at 12:43:37 UTC, Colin Grogan wrote:
>> 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]
>> writef("%s", col1.nextValue);
>> writefln("%s", col2.nextValue);
>> // I want it to print "Hello, World" here
>> }
>
> Delegate refers to context it was created in. Your delegates are created in `main()` scope/context and thus can only access its stack frame. You can't access caller context from delegates.
Ok, that clarifies that then :(
Is there any alternative to using delegates for this behaviour? i.e. passing a function at object construct time, and let that function have access to the objects members?
|
November 08, 2013 Re: Delegate function access to classes local variable | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | 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!
|
November 10, 2013 Re: Delegate function access to classes local variable | ||||
---|---|---|---|---|
| ||||
Posted in reply to Colin Grogan | 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... |
November 10, 2013 Re: Delegate function access to classes local variable | ||||
---|---|---|---|---|
| ||||
Posted in reply to Colin Grogan | On 11/10/2013 09:03 PM, Colin Grogan wrote: > 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? > This will work: 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); > 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... (ref m)=>exp is the same as (ref m){ return exp; } http://dlang.org/expression.html#Lambda (hence (ref m)=>{return exp; } which is the same as (ref m)=>(){ return exp; } is the same as (ref m)=>()=>exp the return type of this expression is 'string delegate()' instead of string and therefore the compiler rejects your code.) |
Copyright © 1999-2021 by the D Language Foundation