2.7.2 Implementing Dynamic

Classes can implement Dynamic and Dynamic<T> which enables arbitrary field access. In the former case, fields can have any type, in the latter, they are constrained to be compatible with the parameter type:

class ImplementsDynamic
  implements Dynamic<String> {
  public var present:Int;
  public function new() {}
}

class Main {
  static public function main() {
    var c = new ImplementsDynamic();
    // valid, present is an existing field
    c.present = 1;
    // valid, assigned value is a String
    c.stringField = "foo";
    // error, Int should be String
    //c.intField = 1;
  }
}

Implementing Dynamic does not satisfy the requirements of other implemented interfaces. The expected fields still have to be implemented explicitly.

Classes that implement Dynamic (with or without type parameter) can also utilize a special method named resolve. If a read access is made and the field in question does not exist, the resolve method is called with the field name as argument:

class Resolve implements Dynamic<String> {
  public var present:Int;
  public function new() {}
  function resolve(field:String) {
    return "Tried to resolve " +field;
  }
}

class Main {
  static public function main() {
    var c = new Resolve();
    c.present = 2;
    trace(c.present);
    trace(c.resolveMe);
  }
}

Take the Haxe Survey!