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