E81066: a trait's 'operator close' is abstract (no body) - a trait holds no properties, so it has nothing to close; the class that holds the resource closes it in its own 'operator close'
What went wrong
A trait declares an 'operator close' with a body. A trait's operator close is abstract: it has no body. A trait holds no properties, so it has nothing of its own to close, and a body there would run inside every class that has the trait. The class that holds a resource declares its own operator close and closes the resource there.
Worked examples
Compilable examples demonstrating this error and the correct fix:
- ek9 -q 1860 (Which of my types must declare their own operator close, and what may that close do?)
- ek9 -q 1520 (When does EK9 close a closeable value, and where may I keep one?)
How to fix it
Remove the body from the trait's operator close, and write the close in the class that holds the resource. The [EXAMPLE] section below shows a trait whose close prints, then a 'Releasable' trait with a bodyless close and a 'Resource' class that overrides it with the work.
Common causes
- Giving a trait a "default" close so that implementing classes need not write one.
- Logging or tidying up in a trait's close; do it in the class's close.
- A trait extending a closeable trait and overriding its close with a body.
See also
Examples
Every example is compiled by the EK9 compiler: the first fails exactly as captioned, the others fix it.
Fails with E81066: a trait's 'operator close' is abstract (no body) - a trait holds no properties, so it has nothing to close; the class that holds the resource closes it in its own 'operator close'
#!ek9 defines module error.e81066.bad defines trait <?- VALID: a trait's operator close with no body is abstract -?> Releasable operator close as pure <?- VALID: the same, with 'abstract' written out -?> ExplicitlyReleasable operator close as pure abstract <?- BAD: a trait's operator close with a body -?> LoggingReleasable operator close as pure stdout <- Stdout() stdout.println("closing") <?- BAD: even a body that only checks something -?> CheckingReleasable operator close as pure require true <?- BAD: a trait extending a closeable trait and adding a close body -?> ExtendedReleasable with trait of Releasable override operator close as pure require true defines class <?- VALID: the class with the trait implements the close itself -?> Resource with trait of Releasable name as String? default private Resource() Resource() -> resourceName as String name: resourceName default operator ? override operator close as pure require name?
Fixed: Leave the trait's close abstract; the class that holds the resource closes it
#!ek9 defines module error.e81066.good defines trait Releasable operator close as pure defines class Resource with trait of Releasable name as String? default private Resource() Resource() -> resourceName as String name: resourceName default operator ? override operator close as pure stdout <- Stdout() stdout.println(`closing ${name}`)
Questions and answers
These Q&A entries show E81066 and its fix: