9.2. Augmenting classes

Defining an augmentation is a matter of adding a augment block in a module:

module foo

augment java.lang.String {
  function wrap = |this, left, right| -> left + this + right
}

function wrapped = -> "abc": wrap("(", ")")

More specifically:

  1. a augment definition is made on a fully-qualified class name, and
  2. an augmentation function takes the receiver object as its first argument, followed by optional arguments, and
  3. there can be as many augmentation functions as you want, and
  4. there can be as many augmentations as you want.

It is a good convention to name the receiver this, but you are free to call it differently.

Also, augmentation functions can take variable-arity arguments, as in:

augment java.lang.String {

  function concatWith = |this, args...| {
    var result = this
    foreach(arg in args) {
      result = result + arg
    }
    return result
  }
}

# (...)
function varargs = -> "a": concatWith("b", "c", "d")

It should be noted that augmentations work with class hierarchies too. The following example adds an augmentation to java.util.Collection, which also adds it to concrete subclasses such as java.util.LinkedList:

augment java.util.Collection {
  function plop = |this| -> "plop!"
}

# (...)
function plop_in_a_list = -> java.util.LinkedList(): plop()