Thread overview
Why cannot scopes be used in template mixins?
Oct 19, 2010
Justin Johansson
Oct 19, 2010
Stanislav Blinov
Oct 19, 2010
Justin Johansson
Oct 19, 2010
Lutger
Oct 19, 2010
Austin Hastings
Oct 20, 2010
Justin Johansson
October 19, 2010
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
October 19, 2010
 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
>
How would that behave when mixed in class/struct definition?
October 19, 2010
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
>>
> How would that behave when mixed in class/struct definition?

You would not use it if it was not appropriate.


October 19, 2010
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.
October 19, 2010
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
October 20, 2010
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