e853cf861b
This patch adds an 'Event' class which may be used to issue various notifications to other MuranoPl classes in an Event-driven manner. Any object which is going to emit the notifications should declare the instances of this new class as its public Runtime properties. The objects going to subscribe for the notifications should pass themselves into the 'subscribe' method of the Event along with the names of their methods which will be used to handle the notification. The specified handler methods must be present in the subscriber class (if the method name is missing it will be defaulted to the 'handle%Eventname%') and has at least one standard (i.e. non-vararg or kwarg) argument. The class going to emit the notification should call the 'notify' method of the event and pass itself as the first argument. All the optional parameters of the event may be passed as varargs/kwargs of the 'notify' call and will be passed all the way to the handler methods. Since this approach relies on the reflection this patch also fixes a bug #1596647 since its fix is required for the argument reflection to work properly. It also documents new reflection capabilities which were added as part of the bugfix. Targets-blueprint: application-development-framework Closes-Bug: #1596647 Change-Id: Ifa7053e4c7b8456030e8df743f57ed812104b064
6.1 KiB
6.1 KiB
Reflection capabilities in MuranoPL.
Reflection provides objects that describes MuranoPL classes and packages.
The first important function is typeinfo
. Usage:
$typeInfo: typeinfo($someObject)
Now $typeInfo
variable contains instance of type of
$someObject
(MuranoClass
instance).
MuranoPL provide following abilities to reflection:
Types
Property | Description |
---|---|
name |
name of MuranoPL class |
version |
version (SemVer) of MuranoPL class. |
ancestors |
list of class ancestors |
properties |
list of class properties. See properties_reflection |
package |
package information. See package_reflection |
methods |
list of methods. See methods_reflection |
type |
reference to type, which can be used as argument in engine functions |
Example
- $typeInfo: typeinfo($)
...
# log name, version and package name of this class
- $log.info("This is "{class_name}/{version} from {package}",
class_name => $typeInfo.name,
version => str($typeInfo.version),
package => $typeInfo.package.name))
- $log.info("Ancestors:")
- For: ancestor
In: $typeInfo.ancestors
Do:
#log all ancestors names
- $log.info("{ancestor_name}", ancestor_name => $ancestor.name)
# log full class version
- $log.info("{version}", version => str($typeInfo.version))
# create object with same class
- $newObject = new($typeInfo.type)
Properties
Property introspection
Property | Description |
---|---|
name |
name of property |
hasDefault |
boolean value. True, if property has default value, False otherwise |
usage |
Usage property's field. See property_usage for
details |
declaringType |
type - owner of declared property |
Property access
Methods | Description |
---|---|
$property.setValue($target, $value) |
set value of $property for object $target
to $value |
$property.getValue($target) |
get value of $property for object
$target |
Example
- $typeInfo: typeinfo($)
...
# select first property
- $selectedPropety: $typeInfo.properties.first()
# log property name
- $log.info("Hi, my name is {p_name}, p_name => $selectedProperty.name)
# set new property value
- $selectedProperty.setValue($, "new_value")
# log new property value using reflection
- $log.info("My new value is {value}", value => $selectedProperty.getValue($))
# also, if property static, $target can be null
- $log.info("Static property value is {value},
value => $staticProperty.getValue(null))
Packages
Property | Description |
---|---|
types |
list of types, declared in package |
name |
package name |
version |
package version |
Example
- $typeInfo: typeinfo($)
...
- $packageRef: $typeInfo.package
- $log.info("This is package {p_name}/{p_version}",
p_name => $packageRef.name,
p_version => str($packageRef.version))
- $log.info("Types in package:")
- For: type_
In: $packageRef.types
Do:
- $log.info("{typename}", typename => type_.name)
Methods
Methods properties
Property | Description |
---|---|
name |
method's name |
declaringType |
type - owner of declared method |
arguments |
list of method's arguments. See arguments_reflection |
Method invoking
Methods | Description |
---|---|
$method.invoke($target, $arg1, ... $argN, kwarg1 => value1, ..., kwargN => valueN) |
call $target 's method $method with $arg1 ,
..., $argN positional arguments and kwarg1 ,
.... kwargN named arguments |
Example
- $typeInfo: typeinfo($)
...
# select single method by name
- $selectedMethod: $typeInfo.methods.where($.name = sampleMethodName).single()
# log method name
- $log.info("Method name: {m_name}", m_name => $selectedMethod.name)
# log method arguments names
- For: argument
In: $selectedMethod.arguments
Do:
- $log.info("{name}", name => $argument.name)
# call method with positional argument 'bar' and named `baz` == 'baz'
- $selectedMethod.invoke($, 'bar', baz => baz)
Method arguments
Property | Description |
---|---|
name |
argument's name |
hasDefault |
True if argument has default value, False otherwise |
declaringMethod |
method - owner of argument |
usage |
argument's usage type. See method_arguments for details |
- $firstArgument: $selectedMethod.arguments.first()
# store argument's name
- $argName: $firstArgument.name
# store owner's name
- $methodName: $firstArgument.declaringMethod.name
- $log.info("Hi, my name is {a_name} ! My owner is {m_name}",
a_name => $argName,
m_name => $methodName)