12.4. Star implementations and overrides

You can pass * as a name for implementations or overrides. In such cases, the provided closure become the dispatch targets for all methods that do not have an implementation or override. Note that providing both a star implementation and a star override is an error.

Let us see a concrete example:

let carbonCopy = list[] # (1)
let conf = map[
  ["extends", "java.util.ArrayList"],
  ["overrides", map[
    ["*", |super, name, args| { # (2)
      if name == "add" {
        if args: length() == 2 {
          carbonCopy: add(args: get(1))  # (3)
        } else {
          carbonCopy: add(args: get(1), args: get(2)) # (4)
        }
      }
      return super: spread(args)  # (5)
    }
  ]]
]]
let list = AdapterFabric(): maker(conf): newInstance()
list: add("bar")
list: add(0, "foo")
list: add("baz")  # (6)

(1)

We create an empty list, more on that later.

(2)

A star override takes 3 parameters: the parent class implementation, the method name and the arguments into an array (the element at index 0 is the receiver).

(3)

We copy into carbonCopy.

(4)

Same here, but we dispatch to a different method

(5)

We just call the parent class implementation of whatever method it is. Note that spread allows to dispatch a closure call with an array of arguments.

(6)

At this point carbonCopy contains ["foo", "bar", "baz"] (and so does list, too).

The case of star implementation is similar, except that the closure takes only 2 parameters: |name, args|.