digitalmars.D.learn - Delegate function access to classes local variable
- Colin Grogan (39/39) Nov 08 2013 Hi folks,
- Dicebot (4/15) Nov 08 2013 Delegate refers to context it was created in. Your delegates are
- Colin Grogan (5/20) Nov 08 2013 Ok, that clarifies that then :(
- Timon Gehr (22/57) Nov 08 2013 import std.stdio;
- Colin Grogan (3/78) Nov 08 2013 Ah, brilliant! I like that construct.
- Colin Grogan (16/100) Nov 10 2013 My optimism may have been premature.
- Timon Gehr (16/28) Nov 10 2013 This will work:
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!
Nov 08 2013
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.
Nov 08 2013
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: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?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.
Nov 08 2013
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); } }
Nov 08 2013
On Friday, 8 November 2013 at 13:14:33 UTC, Timon Gehr wrote:On 11/08/2013 01:43 PM, Colin Grogan wrote:Ah, brilliant! I like that construct. Thank you!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); } }
Nov 08 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: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...On 11/08/2013 01:43 PM, Colin Grogan wrote:Ah, brilliant! I like that construct. Thank you!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); } }
Nov 10 2013
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.)
Nov 10 2013