Dynamic type
In a variable declaration or function parameter,
you can declare the type as the type Dynamic.
The Dynamic type permits
any type of object to be assigned to that variable. The fully qualified
name is dynamic.Dynamic.
At first glance, this might be similar to using the Object type, which is the base
class of all reference types. However, there are important differences.
By declaring the Dynamic type for the variable
or function argument, you can programmatically access any property or
method without requiring compile-time confirmation of its existence.
For example, get the Name
or Age property from an
object even if it does not exist at compile time. In contrast, if you
use the Object type, the
Gosu compiler validates any property or method on the Object class itself, which does
not have many properties or methods.
On its own, the dynamic feature can be used for dynamic programming styles where property names and method names may not be known at compile type. To dynamically get properties, set properties, and invoke methods, you can optionally implement special methods on the target class directly on the declaring class or with a Gosu enhancement.
The following table lists the special
methods you may implement on classes who objects are accessed by variables
declared with the dynamic.Dynamic
type. In the following table, the term UNHANDLED
refers to value gw.lang.reflect.IPlaceholder.UNHANDLED.
Dynamic type method name |
Description |
|---|---|
|
Gets a property by
its name specified as an argument. If the property is unknown, return
the value |
|
Similar to Gosu calls this method if some code sets a property and either of the following is true:
|
|
Sets a property by
its name specified as an argument, with the value in the second argument.
If the property is unknown, return the value |
|
Similar to Gosu calls this method if some code sets a property and either of the following is true:
|
|
Invokes a method by
its name specified as an argument, with the parameter list in the second
argument as an array of |
|
Similar to Gosu calls this method if some code invokes a method and either of the following is true:
|
The following example defines a simple
object with a dynamic property getter method. In the example, the $getProperty method handles two
property names explicitly, and then returns UNHANDLED for any other property
names. Note that for the unhandled property name, Gosu automatically
calls the $getMissingProperty
method.
In real-world code, the $getProperty method might get
the value from a java.util.Map,
from a related subobject, from a calculation, or even from an external
system:
package doc.example
uses gw.lang.reflect.IPlaceholder
uses dynamic.Dynamic
class DynamicGetter {
// Handle any property name. Dynamically return
// values for two values, and return UNHANDLED for others
public function $getProperty(fieldName: String): Object {
print("$getProperty called with field: " + fieldName)
if (fieldName == "StreetAddress") {
return "123 Main Street"
} else if (fieldName == "FirstName") {
return "John"
} else {
return IPlaceholder.UNHANDLED
}
}
// Handle any unhandled requests for missing property names
public function $getMissingProperty(fieldName: String): Object {
print("$getMissingProperty called with field: " + fieldName)
return ("fakeValue")
}
}
The following code uses the dynamic object and gets a property from it:
uses doc.example.DynamicGetter
uses dynamic.Dynamic
var obj : Dynamic = new DynamicGetter()
print("---")
print("Dynamically get a known property...")
print("RESULT = " + obj.StreetAddress)
print("---")
print("Dynamically get a missing property...")
print("RESULT = " + obj.OtherField)
This code prints the following:
---
Dynamically get a known property...
$getProperty called with field: StreetAddress
RESULT = 123 Main Street
---
Dynamically get a missing property...
$getProperty called with field: OtherField
$getMissingProperty called with field: OtherField
RESULT = fakeValue
The dynamic type works well with the IExpando interface and Expando objects. Use these objects
together to create dynamic property getters and setters and store data
in a java.util.Map object.
See also
