www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Why cannot scopes be used in template mixins?

reply Justin Johansson <no spam.com> writes:
For example:

private string THIS_MODULE_NAME = "abc.def";

mixin template MyCorporationStandardUnitTest()
{
	scope(success) {
		writeln( THIS_MODULE_NAME ~ " unittest passed");
	}

	scope(failure) {
		writeln( THIS_MODULE_NAME ~ " unittest failed");
	}
}


I think the D spec does not say this is allowed, but why not?

Thanks in advance for answers,

Justin
Oct 19 2010
next sibling parent reply Stanislav Blinov <blinov loniir.ru> writes:
  19.10.2010 14:18, Justin Johansson wrote(ln):
 For example:

 private string THIS_MODULE_NAME = "abc.def";

 mixin template MyCorporationStandardUnitTest()
 {
     scope(success) {
         writeln( THIS_MODULE_NAME ~ " unittest passed");
     }

     scope(failure) {
         writeln( THIS_MODULE_NAME ~ " unittest failed");
     }
 }


 I think the D spec does not say this is allowed, but why not?

 Thanks in advance for answers,

 Justin

Oct 19 2010
parent Justin Johansson <no spam.com> writes:
On 19/10/2010 10:31 PM, Stanislav Blinov wrote:
 19.10.2010 14:18, Justin Johansson wrote(ln):
 For example:

 private string THIS_MODULE_NAME = "abc.def";

 mixin template MyCorporationStandardUnitTest()
 {
 scope(success) {
 writeln( THIS_MODULE_NAME ~ " unittest passed");
 }

 scope(failure) {
 writeln( THIS_MODULE_NAME ~ " unittest failed");
 }
 }


 I think the D spec does not say this is allowed, but why not?

 Thanks in advance for answers,

 Justin


You would not use it if it was not appropriate.
Oct 19 2010
prev sibling next sibling parent Lutger <lutger.blijdestijn gmail.com> writes:
Justin Johansson wrote:

 For example:
 
 private string THIS_MODULE_NAME = "abc.def";
 
 mixin template MyCorporationStandardUnitTest()
 {
 scope(success) {
 writeln( THIS_MODULE_NAME ~ " unittest passed");
 }
 
 scope(failure) {
 writeln( THIS_MODULE_NAME ~ " unittest failed");
 }
 }
 
 
 I think the D spec does not say this is allowed, but why not?
 
 Thanks in advance for answers,
 
 Justin

Only declarations are allowed in templates, no statements.
Oct 19 2010
prev sibling parent reply Austin Hastings <ah08010-d yahoo.com> writes:
On 10/19/2010 6:18 AM, Justin Johansson wrote:
 For example:

 private string THIS_MODULE_NAME = "abc.def";

 mixin template MyCorporationStandardUnitTest()
 {
 scope(success) {
 writeln( THIS_MODULE_NAME ~ " unittest passed");
 }

 scope(failure) {
 writeln( THIS_MODULE_NAME ~ " unittest failed");
 }
 }


 I think the D spec does not say this is allowed, but why not?

 Thanks in advance for answers,

 Justin

(Note: I'm only using PL/D 2.0, so my answers are specific to that version on the DMD compiler.) Mixin templates may only contain declarations - not executable statements. For this, you want a string mixin. There are some things you could try. 1. I have some GPL code that does what you're trying to do, in a different way. Have a look at http://github.com/aghast/Leda/blob/master/source/leda/test/unit.d . It outputs TAP, instead of success/failure messages, but IMO that's a better solution because there are plenty of TAP harnesses around. 2. You could have a look at "scope classes" in the docs: http://www.digitalmars.com/d/2.0/class.html#auto (I know, "auto" makes no sense, but it's in the html source..) This indicates that a class is intended to be used RAII-style, such that the destructor is called. To use this, you'd probably have to catch Assertion failures, or put a hook in the unit test failure handler (see the core.* doc pages in your local install, since the net links aren't up on the dmd site). 3. You could use a string mixin. In order to get the module name added, you could generate the string in a function. I think there's a std* template that does compile-time formatting, but naturally googling on the obvious keywords doesn't work. So you'd so something like: mixin( function_to_generate_the_scope_statements( MODULE_NAME ) ); at the top of your code. (Note: mixing( "string" ) is different from mixin-templates, and *can* have statements and expressions, not just declarations.) Good luck, =Austin
Oct 19 2010
parent Justin Johansson <no spam.com> writes:
On 20/10/2010 8:45 AM, Austin Hastings wrote:
 Mixin templates may only contain declarations - not executable
 statements. For this, you want a string mixin. There are some things you
 could try.

 1. I have some GPL code that does what you're trying to do, in a
 different way.

 Have a look at
 http://github.com/aghast/Leda/blob/master/source/leda/test/unit.d . It
 outputs TAP, instead of success/failure messages, but IMO that's a
 better solution because there are plenty of TAP harnesses around.

 2. You could have a look at "scope classes" in the docs:

 http://www.digitalmars.com/d/2.0/class.html#auto (I know, "auto" makes
 no sense, but it's in the html source..)

 This indicates that a class is intended to be used RAII-style, such that
 the destructor is called.

 To use this, you'd probably have to catch Assertion failures, or put a
 hook in the unit test failure handler (see the core.* doc pages in your
 local install, since the net links aren't up on the dmd site).

 3. You could use a string mixin.

 In order to get the module name added, you could generate the string in
 a function. I think there's a std* template that does compile-time
 formatting, but naturally googling on the obvious keywords doesn't work.
 So you'd so something like:

 mixin( function_to_generate_the_scope_statements( MODULE_NAME ) );

 at the top of your code.

 (Note: mixing( "string" ) is different from mixin-templates, and *can*
 have statements and expressions, not just declarations.)


 Good luck,

 =Austin

 1. I have some GPL code that does what you're trying to do, in a
 different way.

Thanks Austin; you read my mind. :-) Kind regards, Justin
Oct 20 2010