Using feature literals

Gosu feature literals provide a way to statically refer to a type’s features such as methods and properties. You can use feature literals to pass class property and method members to API methods. Gosu validates feature literals at compile time, preventing common errors that might occur if you pass members by using their names as String values. To refer to the feature of a type or object, you use the # operator after the type or object, followed by the feature name. The syntax is similar to the feature syntax of the Javadoc @link syntax.

You can use feature literals in API methods, such as in the following types of layers.

  • Mapping layers, where you are mapping between properties of two types
  • Data-binding layers
  • Type-safe object paths for a query layer
Consider the following Gosu class.
class Employee {
  var _boss : Employee as Boss
  var _name : String as Name
  var _age : int as Age

  function update(name : String, age : int) {
    _name = name
    _age = age
  }

  function greeting() {
    print("Hello world")
  }
}
Given this class, you can refer to its features by using the # operator.
// Get property feature literal
var nameProp = Employee#Name

// Get method feature literal
var updateFunc = Employee#update(String, int)

These variables contain feature literal references. By using these references, you can access the underlying property or method information.

You can define or use Gosu methods that use feature literals as arguments or return values.

Chaining feature literals by using feature literal syntax

Feature literals support type-safe chaining, so this code is valid.
var bossesNameRef = anEmp#Boss#Name

The chained feature literal refers to the name of the boss of the object in the anEmp variable.

Binding a property to an instance by using feature literal syntax

You can bind a feature literal to a specific object instance. This technique is the equivalent of using the compile-time type to request the property by name for a particular instance of the object.

Using the feature literal code from the previous example, this code creates a reference to a property on an employee instance.
var anEmp = new Employee() { :Name = "Joe", :Age = 32 }

// Get the property feature literal for a specific instance
var namePropForAnEmp = anEmp#Name

Binding argument values by using feature literal syntax

You can bind argument values in method references that use feature literal syntax.

Using this technique, you can refer to a method invocation with a particular set of arguments. Note that the second line in the following example does not invoke the update method. Instead, it gets a reference that you can use later to refer to the method on that instance.
var anEmp = new Employee() { :Name = "Joe", :Age = 32 }
var updateFuncForAnEmp = anEmp#update("Ed", 34)

print(anEmp.Name) // Prints "Joe". Code has not yet invoked the method reference.

Using feature literal syntax to convert method references to blocks

You can convert a method reference to a block by using the toBlock method.

The following example creates a block object for a call to the update method on the anEmp object.
var aBlock = anEmp#update("Ed", 34).toBlock()

You can use this technique to pass a method reference as an argument to a method that takes a block parameter.