Write me a generic Formatter of type T that captures a prefix variable from the enclosing scope and uses it inside the overridden format method.
← Generics · Ref: Q1235
Dynamic classes that extend a generic type can ALSO capture variables from the enclosing scope. The captured variables are listed in the parentheses before 'extends', and become fields on the dynamic class. They can be used inside the overridden methods alongside the type-substituted parameters.
GENERIC ABSTRACT FORMATTER
Formatter of type T as abstract format() as abstract -> arg0 as T <- rtn as String? override operator ? as pure <- rtn as Boolean: true
DYNAMIC CLASS WITH CAPTURE
prefix <- "Item" formatter <- (prefix) extends Formatter of Integer as class override format() -> arg0 as Integer <- rtn as String: `${prefix}: ${$arg0}` default operator ?
The parentheses '(prefix)' declare which outer variables to capture. They become fields on the anonymous class and are visible inside the overridden methods. The generic type parameter T is replaced by Integer at the same time.
USAGE
stdout.println(formatter.format(42))
This combines TWO features in one expression: generic type extension AND closure-style capture. The captured prefix coexists with the substituted Integer parameter.
See Q1234 for basic generic extension without capture. See Q601 for dynamic functions with capture. See Q197 for extending generics.
Example
defines module qa.genericsdeep.formattercapture defines class Formatter of type T as abstract format() as abstract -> arg0 as T <- rtn as String? override operator ? as pure <- rtn as Boolean: true defines program FormatterCaptureDemo() stdout <- Stdout() prefix <- "Item" formatter <- (prefix) extends Formatter of Integer as class override format() -> arg0 as Integer <- rtn as String: `${prefix}: ${$arg0}` default operator ? stdout.println(formatter.format(42))
Common mistakes
E50001 — If you reference an outer-scope variable inside the dynamic class body but do not list it in the capture parentheses, the variable is not resolved (E50001) because it is never brought into the dynamic class's scope. List it in the capture parentheses, e.g. (prefix), to make it available. See ek9 -h E50001 for details.
Incorrect:
() extends Formatter of Integer as class
Correct:
(prefix) extends Formatter of Integer as class
Other ways to ask this
- Create a dynamic class extending a generic type that captures a local variable.
- Show me how generic dynamic classes combine with variable capture in EK9.
- Implement a parameterised Formatter that captures a prefix and formats Integer values.
- Build a generic formatter dynamic class that uses an outer-scope variable.
Coming from another language?
Java: anonymous inner class capturing effectively-final outer variables. Kotlin: object expression with closure over outer scope. Scala: anonymous subclass with closure. JavaScript: class extending a generic-like base that closes over outer variables. EK9: explicit '(capturedVar)' syntax makes capture intentional and visible.
Keywords: dynamic class, capture, of type, anonymous, closure, inline, extends, generic