My favorites | Sign in
Project Home Downloads Wiki Issues Source
Search
for
DefaultProperties  
Description of the new default properties feature of Visage
Updated Oct 17, 2010 by steveonjava

Introduction

Visage programs are very descriptive of the UI due to the Object Literal syntax, but this also introduce a very high level of nesting in typical programs. The goal of the default properties feature was to create a simplified syntax that makes it easier to read nested data structures.

Details

With the default properties support you can take code that looks like this:

Stage {
  scene: Scene {
    contents: Rectangle {
      width: 100
      height: 100
    }
  }
}

and reduce it to this:

Stage {
  Scene {
    Rectangle {
      width: 100
      height: 100
    }
  }
}

So how did the compiler know that the "scene" and "content" labels were optional? This is because those class variables were created using the new "default" keyword like this:

public class Stage {
  public-init default var scene:Scene;
}

public class Scene {
  public-init default var content:Node[];
}

Multiple Defaults

Each class can have 1 and only 1 variable declared as the default. Declaring multiple defaults will result in a compiler error like the following:

C:\dev\project\SomeClass.fx:50: Variables entries and centered both have the default modifier.
Only one class variable can be declared as the default.
    public default var centered:Number;

Mixing With Labeled Variables

It is valid to have a class with multiple variables, only one of which is the default. For example, you could declare a class like the following:

public class Text {
  public default var content:String;
  public var fontSize:Integer;
  public var fontName:String;

and use it as follows:

Text {
  "Visage default properties rock!"
  fontSize: 24
  fontName: "Arial Black"
}

If you declare variables before the default, they will be scoped at the block level and be available to all the properties. To declare private variables, add a label before the default variable.

Subclassing

If a subclass also defines a default variable, it will shadow the superclass default. For example, the following code:

class SuperDefault {
  public default var contents:String[];
}

class ShadowDefault extends SuperDefault {
  public default var shadow:String[];
}

def sd = ShadowDefault {
  ["a", "b", "c"]
}
println("contents: {sd.contents.toString()}, shadow: {sd.shadow.toString()}");

will set the value for "shadow" rather than "contents", resulting in the following output:

contents: [ ], shadow: [ a, b, c ]

Compatibility

This change is not backwards compatible due to the addition of the "default" keyword to the language syntax. However, this is an easy change (rename) that will fix most programs. It also does not affect existing compiled binaries.

These changes themselves are binary compatible with previous compiler releases. This means that you can compile code using defaults against compiler versions that do not use this feature. Also, the resulting class files can be run on older compiler binaries.

Comment by eamonnxm...@gmail.com, Nov 8, 2010

Does "default" need to be a reserved word? I would have thought it would be like "init", which is a keyword but not reserved, so that you can still have an identifier called "init".


Sign in to add a comment
Powered by Google Project Hosting