First project: questions on how-to, and on language features

Marc Schütz via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sun Jan 24 04:26:23 PST 2016


On Sunday, 24 January 2016 at 06:07:13 UTC, Alex Vincent wrote:
> (1) It's not clear how to specify certain parts of a module or 
> library as non-exportable.  Is that possible?  Is it desirable?
>  (It's not that important, yet, but still...)

Yes, definitely. By default symbols in a module are `public`, but 
you can mark them as `private`. These aren't accesible from other 
modules:

     module test;

     void foo() { }        // public, because there's no annotation
     private bar() { }     // private
     void bar2() { }       // public again

     private:              // everything from here on is private
     void bla() { }
     void blubb() { }

>
> (2) In the unittest code, I have a block that I want to rewrite 
> using assertThrown, but I can't figure out from either the book 
> or the website the correct usage.  What's the right way to 
> specify a StringException with a particular message I expect to 
> receive?

Here's the relevant documentation:
https://dlang.org/phobos/std_exception.html#.assertThrown
https://dlang.org/phobos/std_exception.html#.collectExceptionMsg

`assertThrown()` doesn't allow to check the message directly, it 
can only check whether a particular type of exception has been 
thrown:

     assertThrown!StringException(throw new 
StringException("test"));

Instead, you can use `collectExceptionMsg()` to check both the 
message and the exception type:

     assert(
         collectExceptionMsg!StringException(throw ...) == "test"
     );

>
> (4) How should the scope(exit) and scope(failure) guard 
> statements intermix with preconditions and postconditions?

Pre- and postconditions are supposed to run before you enter the 
function, or after you left it, respectively. Therefore, and 
scope() blocks in the function body would already have completed 
when the postcondition is entered. OTOH, scope() blocks only run 
if control flow has passed through them. In a precondition, this 
hasn't happened yet, and therefore they will not run.

If you mean whether you can use scope() blocks in pre- and 
postconditions, yes, you can. The will then run when you leave 
the pre- and postcondition. But usually, pre- and postconditions 
only consist of very little code that's not supposed to do any 
serious work, so they are less likely to be used there.

Or, looking at it from a different angle: A scope() block only 
runs at the end of the lexical scope / block it appears in. Pre- 
and postconditions are not part of the function body, or vice 
versa. Therefore, see above.

>
> (5) My append() function has a postcondition that currently 
> depends on debug-only members of the class being set in the 
> precondition.  This seems artificial - not the part about 
> setting these variables in the precondition, but having the 
> variables defined on the class to begin with.  If they were 
> defined only for the lifetime of the function's execution, 
> starting in the precondition, this would be more natural.  Is 
> there a Right Way to define function-only debug variables for 
> use in postconditions?  If not, would this be a valid use-case 
> to consider amending the language specification to clarify?

I'm not an expert in contract programming, but as I see it, your 
precondition doesn't actually check anything, you're kinda 
abusing them as preparation for your postcondition. That's likely 
not the way it's supposed to be. I see what you're trying to 
achieve, and I believe it's legitimate to check for... You could 
either just move the assert()s into the function body just before 
the end, where you have access to the local variables (but you 
could easily miss an early return), or put them into a 
scope(exit) block (but then you could accidentally check it too 
early). Your best bet here is probably to check it in a unittest, 
although they are for a slightly different purpose, strictly 
speaking.



More information about the Digitalmars-d-learn mailing list