Reflection allows your program to inspect and access all or some of your program's declarations dynamically at runtime. More...
Classes: | |
Constants: |
|
Functions: |
|
To enable reflection, you must at least import the reflection module.
In addition, you must provide a 'reflection filter' to specify which modules are to be reflected. This is done using the REFLECTION_FILTER app config setting, which should contain the set of modules you want to be reflected. In addition, the reflection filter may use the '*' wildcard character to match 'any text' in a module path.
The simplest way to set the reflection filter is to use the wildcard character '*' on its own, eg:
#
REFLECTION_FILTER
=
"*"
'reflect everything!
Import
reflection
However, this will cause all modules to be reflected, which in the case of even moderately sized programs will incur major overhead both in terms of compilation time and runtime app size. Instead, it's best to set the filter to only specify the modules you need reflected.
Multiple reflection filters may be specified using the ';' separator character, eg:
#
REFLECTION_FILTER
=
"myapp.gadgets;myapp.listeneres"
'reflect both the myapp.gadgets and myapp.listeners modules
The reflection filter may also be appended to using the preprocessor += operator, eg:
REFLECTION_FILTER
=
"myapp.gadgets"
'reflect the myapp.gadgets module...
REFLECTION_FILTER
+=
"myapp.listeners"
'...and the myapp.listeners module.
Using the '*' wildcard, sets of 'submodules can be specified, eg:
REFLECTION_FILTER
=
"myapp.gadgets;myapp.gadgets.*"
'reflect the myapp.gadgets module AND any myapp.gadgets submodules.
Declarations that appear at 'module scope' - that is, declarations that do not appear within a class - are fully qualified by the module they appear in.
For example, the DrawImage function that appears in the mojo.graphics module is named "mojo.graphics.DrawImage".
This is the name returned by the various Name() methods, and is the name you should use with the GetConst, GetGlobal, GetFunction and GetClass functions.
As a convenience, you can also use unqualified names with the Get functions as long as there is only one unique declaration with the given name.
For example, GetFunction( "mojo.graphics.DrawImage" ) and GetFunction( "DrawImage" ) will return the same FunctionInfo object, as long as DrawImage is only declared in one module.
Declarations that appear at class scope are not qualified.
Non-object values of type int, float, string and array must be 'boxed' before they are passed to reflection methods such as SetValue and Invoke.
To do this, use the BoxInt, BoxFloat, BoxString functions. These functions all return a 'box' Object which is suitable for use with SetValue and Invoke.
Similarly, reflection methods such as GetValue and Invoke that return non-object values will return boxed values.
To unbox these values, use the UnboxInt, UnboxFloat and UnboxString functions.
Here's an example of boxing and unboxing in action:
#
REFLECTION_FILTER
=
"*"
Import
reflection
Global
MyGlobal
:=
123
Function
Main
()
'Get GlobalInfo for MyGlobal
Local
g
:=
GetGlobal
(
"MyGlobal"
)
'Read and unbox value of MyGlobal
Local
n1
:=
UnboxInt
(
g.GetValue
() )
'Print it...
Print
"n1="
+
n1
'Box and write value of MyGlobal
g.SetValue
(
BoxInt
(
n1
*
2
) )
'Read, unbox and dump...
Local
n2
:=
UnboxInt
(
g.GetValue
() )
Print
"n2="
+
n2
End
Boxing and Unboxing arrays is slightly trickier - you must use the Box and Unbox functions declared in the ArrayBoxer class to do this. Here's an example:
#
REFLECTION_FILTER
=
"*"
Import
reflection
Global
MyGlobal
:
Int
[]
Function
Main
()
'create an int array
Local
intArray
:
Int
[]=[
1
,
2
,
3
,
4
,
5
]
'box it...
Local
boxedArray
:=
ArrayBoxer
<
Int
>.
Box
(
intArray
)
'set value of MyGlobal
GetGlobal
(
"MyGlobal"
).
SetValue
(
boxedArray
)
'dump array
For
Local
i
:=
Eachin
MyGlobal
Print
i
Next
'reassign MyGlobal
MyGlobal
=[
6
,
7
,
8
,
9
,
10
]
'read value of MyGlobal
boxedArray
=
GetGlobal
(
"MyGlobal"
).
GetValue
()
'Unbox it...
intArray
=
ArrayBoxer
<
Int
>.
Unbox
(
boxedArray
)
'dump unboxed array
For
Local
i
:=
Eachin
intArray
Print
i
Next
End
Returns the class of an array.
The elementType parameter is case sensitive, and must be the fully qualified name of the element type.
The elementType parameter may itself be an array, in which case the returned class represents a multidimensional array.
This is actually the class of the objects used to box arrays, since arrays aren't objects and therefore don't have a class.
Returns the class of a 'bool'.
This is actually the class of the objects used to box bools, since bools aren't objects and therefore don't have a class.
Creates a box object with the given value.
Box objects can be passed to the SetValue methods of FieldInfo and GlobalInfo objects, and used as parameters for the Invoke methods of MethodInfo and FunctionInfo objects.
Box objects are also returned by the GetValue methods of ConstInfo, FieldInfo and GlobalInfo objects, and by the Invoke methods of MethodInfo and FunctionInfo objects.
See also UnboxBool
Creates a box object with the given value.
Box objects can be passed to the SetValue methods of FieldInfo and GlobalInfo objects, and used as parameters for the Invoke methods of MethodInfo and FunctionInfo objects.
Box objects are also returned by the GetValue methods of ConstInfo, FieldInfo and GlobalInfo objects, and by the Invoke methods of MethodInfo and FunctionInfo objects.
See also UnboxFloat
Creates a box object with the given value.
Box objects can be passed to the SetValue methods of FieldInfo and GlobalInfo objects, and used as parameters for the Invoke methods of MethodInfo and FunctionInfo objects.
Box objects are also returned by the GetValue methods of ConstInfo, FieldInfo and GlobalInfo objects, and by the Invoke methods of MethodInfo and FunctionInfo objects.
See also UnboxInt
Creates a box object with the given value.
Box objects can be passed to the SetValue methods of FieldInfo and GlobalInfo objects, and used as parameters for the Invoke methods of MethodInfo and FunctionInfo objects.
Box objects are also returned by the GetValue methods of ConstInfo, FieldInfo and GlobalInfo objects, and by the Invoke methods of MethodInfo and FunctionInfo objects.
See also UnboxString
Returns the class of a 'float'.
This is actually the class of the objects used to box floats, since floats aren't objects and therefore don't have a class.
Returns the ClassInfo object with the given name, or Null if no object is found.
See also GetClasses, ClassInfo
Returns the ClassInfo object with the given name, or Null if no object is found.
See also GetClasses, ClassInfo
Returns the FunctionInfo object with the given name and parameter types, or Null if no object is found.
See also GetFunctions, FunctionInfo
Returns an array of all reflected functions.
See also GetFunction, FunctionInfo
Returns the GlobalInfo object with the given name, or Null if no object is found.
See also GetGlobals, GlobalInfo
Returns an array of all reflected globals.
See also GetGlobal, GlobalInfo
Returns the class of an 'int'.
This is actually the class of the objects used to box ints, since ints aren't objects and therefore don't have a class.
Returns the class of a 'string'.
This is actually the class of the objects used to box strings, since strings aren't objects and therefore don't have a class.
Unboxes a bool. The box must have been previously created with BoxBool.
See also BoxBool
Unboxes a float. The box must have been previously created with BoxFloat.
See also BoxFloat
Unboxes an int. The box must have been previously created with BoxInt.
See also BoxInt
Unboxes a string. The box must have been previously created with BoxString.
See also BoxString