www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Code repetition

reply IntegratedDimensions <IntegratedDimensions gmail.com> writes:
I have some code like

void foo()
{
     // setup stuff
     int x;
     scope(exit) something;

     //
     x = 34;
}

....


void foon()
{
     // setup stuff
     int x;
     scope(exit) something;

     //
}



All the setup stuff is virtually identical in each foo. There are 
slight differences such as a return value.


I would like to abstract the code code so that it can be handled 
in one place.

I have not found a way to do this in D. Template mixins do not 
work because of the arbitrary expressions. Putting the code in a 
template/function/lambda does not work because of the scopes 
which will be called when the main function exists.

A string mixin is too messy since it treats the code as a string 
losing all syntax highlighting, etc.

I'd love to have something like a template mixin where I can just 
do

mixin template fooSetup(ret)
{
     // setup stuff
     int x;
     scope(exit) something;

}


and

void foo()
{
    fooSetup(3);
}


void foo4()
{
    fooSetup(13);
}

and everything behave as it should. I'm guessing this is going to 
be impossible to achieve in D?
May 26 2018
next sibling parent IntegratedDimensions <IntegratedDimensions gmail.com> writes:
I guess I should have mentioned that basically this is like a C 
macro.
May 26 2018
prev sibling next sibling parent Malte <no valid.mail> writes:
On Sunday, 27 May 2018 at 06:47:38 UTC, IntegratedDimensions 
wrote:
 A string mixin is too messy since it treats the code as a 
 string losing all syntax highlighting, etc.

 I'd love to have something like a template mixin where I can 
 just do

 mixin template fooSetup(ret)
 {
     // setup stuff
     int x;
     scope(exit) something;

 }


 and

 void foo()
 {
    fooSetup(3);
 }


 void foo4()
 {
    fooSetup(13);
 }

 and everything behave as it should. I'm guessing this is going 
 to be impossible to achieve in D?
Well, if you want to have the same power as Cs textual replacement, you need string mixins. Often you can replace it with templates, but that depends on the application. I would avoid it if you can though, but more for debugging and not because of syntax highlighting. void main() { import std.stdio; int y = 1; mixin(fooSetup(3)); writeln("x is ",x); x = 5; } string fooSetup(int val) { import std.conv; return q{ int x = }~val.to!string~q{; scope(exit) { writeln("x was ", x); writeln("y was ", y); } }; }
May 27 2018
prev sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Sunday, 27 May 2018 at 06:47:38 UTC, IntegratedDimensions 
wrote:
 Putting the code in a template/function/lambda does not work 
 because of the scopes which will be called when the main 
 function exists.
I think you might just be using the wrong kind of function. --- import std.stdio; // the helper does the setup then calls another function for specific stuff void helper(void delegate(ref int) specialized) { // setup stuff int x; scope(exit) writeln("exit ", x); // specialized stuff abstracted out specialized(x); } void foo() { helper( (ref x) { x = 34; }); } void main() { foo(); } ---
 A string mixin is too messy since it treats the code as a 
 string losing all syntax highlighting, etc.
Configure your editor so the q{ code... } strings don't highlight as a string and you get that at least.
May 27 2018
parent IntegratedDimensions <IntegratedDimensions gmail.com> writes:
On Sunday, 27 May 2018 at 13:20:08 UTC, Adam D. Ruppe wrote:
 On Sunday, 27 May 2018 at 06:47:38 UTC, IntegratedDimensions 
 wrote:
 Putting the code in a template/function/lambda does not work 
 because of the scopes which will be called when the main 
 function exists.
I think you might just be using the wrong kind of function. --- import std.stdio; // the helper does the setup then calls another function for specific stuff void helper(void delegate(ref int) specialized) { // setup stuff int x; scope(exit) writeln("exit ", x); // specialized stuff abstracted out specialized(x); } void foo() { helper( (ref x) { x = 34; }); } void main() { foo(); } ---
Yeah, this should work. Was hoping there was just a simple way to pull the code out but I guess this provides the best alternative. Thanks.
May 27 2018