Presentation is loading. Please wait.

Presentation is loading. Please wait.

What’s New in the ABL in OpenEdge Release 11.6

Similar presentations


Presentation on theme: "What’s New in the ABL in OpenEdge Release 11.6"— Presentation transcript:

1 What’s New in the ABL in OpenEdge Release 11.6
Fernando Souza Principal Software Engineer November 2015

2 Agenda Single-line Comments XREF ABL Enums Object Serialization
Reflection RadForm Subclasses

3 Single-line Comments

4 Single-line Comments Starts with // Any text after the // is ignored
//This is a comment def var vch1 as char. // This is another comment def var vch2 // Simple comment as char format "x(30)". // RUN myproc.p. Single-line comments can be added on their own lines or following a statement as long as there is a space between the last token and the // that precedes the comment.

5 XREF

6 SEARCH tt1 ixnum TEMPTABLE WHOLE-INDEX
XREF Option in the COMPILER statement Index information for queries via SEARCH entry Prior to 11.6, only database tables or shared temp-tables In 11.6, it includes queries on non-shared temp-tables (“local”) SEARCH tt1 ixnum TEMPTABLE WHOLE-INDEX The XREF option on the COMPILE statement generates a file with a lot of information about the compilation of a given ABL file, which includes an entry named SEARCH for queries that allows you to see which index (if any) the compiler chose to resolve the query. The SEARCH entry can provide useful information to ABL developers. Knowing the selected index can help developers identify performance problems if an incorrect index or index bracket is specified. Prior to 11.6, that was only provided for queries on database tables or shared temp-tables. In 11.6, we extended the support for queries on non-shared temp-tables as well, that is, local temp-tables, so that developers can have the same type of information for queries on all temp-tables in their code, not only temp-tables that are defined as shared.

7 ABL Enums

8 ABL Enums Defined set of named values Defined in a .cls file
For example, directions: North, South, East, West Defined in a .cls file Enforced by the compiler Each named value has a numeric value associated with it Cannot be extended, implement interfaces or inherit from anything explicitly Serializable (can be passed between ABL clients and AppServer) An ABL enumeration type (or enum) allows you to define a set of strongly typed named constants, referred to as enum members, that specify the values that can be assigned to a variable. They provide a way for the application developer to define the valid values for a given variable. ABL enums can only contain a list of enum members, and not any data members (variables, properties), events, methods, constructors or destructor. ABL enums are defined in a .cls file (much like classes). For that reason, their use in the ABL is very similar to how you would reference and use a class. ABL enums also provide some built-in functionality that is specific to enums. An ABL enumeration type is strongly-typed and provides compiler-time validation. You can define variables of ABL enumeration types and can assign values that are defined in the enum to them. They can also be used to define parameters for procedures, functions and methods, and also return types for functions/methods. ABL enums cannot be extended (that is, they are final). And they cannot inherit from any other class explicitly. ABL enums are implicitly serializable, so you can pass them between ABL clients and AppServers.

9 Defining an ABL Enum Type
Direction.cls Direction Progress.Lang.Enum Progress.Lang.Object ENUM Direction: DEFINE ENUM North South East West. END ENUM. You define an ABL enum with the ENUM statement, in a file with the same name as the enum and .cls extension. The ENUM statement does not allow options like INHERITS, IMPLEMENTS, FINAL, etc (which are provided by the CLASS statement). The DEFINE ENUM statement is the only statement allowed in an ABL enum and it allows you to define the list of named values associated with that enum. Each name in the list is separated by space. The END [ ENUM] statement is used to end the ABL enum definition. The keyword ENUM in END ENUM is optional. ABL enums implicitly inherits from Progress.Lang.Enum, which provides some methods that are common for all ABL enums. You can only set one of the defined values to a variable defined as that enum type.

10 Defining an ABL Enum Type (Cont’d)
Colors.cls ENUM Colors: DEFINE ENUM Orange Red White Gray Grey = Gray. END ENUM. You can also define multiple members to be equivalent, for instance, for different spellings or values that represent the same thing. In the example above, the members Gray and Grey represent the same value and can be used interchangeably.

11 Defining Values for Enum Members
Can explicitly assign numeric values for one or more members INT64 value ENUM Colors: DEFINE ENUM Red = 2 Blue = 4 Gray = 6 Grey = Gray. END ENUM. Each enum member gets assigned a numeric value internally, starting with value 1 and incremented by 1 for each member subsequently defined. You can explicitly assign values to different enum members as long as the values can be represented as INT64 values. This may be helpful when you want to define a set of values to match the definitions of some external library/API you are working with. You can also set members to be equivalent to other pre-defined members. For instance, in the example above, Gray and Grey are equivalent.

12 def var eDirection as Direction. def var myObj as myClass. …
Accessing Enums Use type-name syntax def var eDirection as Direction. def var myObj as myClass. eDirection = Direction:North. RUN validateDirection (INPUT eDirection). myObj:redirect (INPUT-OUTPUT eDirection). This example shows a few things: 1 – You can specify an ABL enum type as the data type for a variable. 2 – To access the member of an ABL enum, you use the type-name syntax. i.e. Direction:North. Note that you cannot call NEW() on an ABL enum type. 3 - You can pass an ABL enum to a procedure, function or method.

13 ABL Enums - CASE Statement
Enum type for CASE and WHEN option(s) must match PROCEDURE validateDirection: def input parameter peDir as Direction. case peDir: when Direction:South then … when Direction:North then .. when Direction:East then …. when Direction:West then … end case. END PROCEDURE. In this example, you can see that the parameter type can also be an ABL enum type. The CASE statement was enhanced to support enums. The restriction is that you reference the same enum type in the CASE statement and the WHEN option, that is, you cannot mix different enum types in the CASE statement. For instance, if you define another enum called Colors, they cannot be used in that same CASE statement. Although not shown in the example, you can still use the OTHERWISE option to deal with any values not specified, should new values be added to the enum type.

14 ABL Enums - Comparisons
Enum types for operands in comparison operators must match. def var eColor as Colors. if eColor eq Colors:White or eColor eq Colors:Red then ... else if eColor ne Colors:Black then … You can also use enums in comparisons. For example, the IF statement and the EQ, NE operators are shown in the example above. The same restriction applies here: the enum types for both operands of a comparison operator must match exactly.

15 ABL Enums – Comparisons (Cont’d)
Comparing equivalent named values def var eColor as Colors. eColor = Colors:Grey. <..> // This resolves to TRUE as Grey and Gray are defined // as equivalent by the enum type if eColor eq Colors:Gray then . This is an example to show that if enum members are defined to be equivalent, they can be used in the ABL interchangeably. The expression in the IF statement shown in the example above results to TRUE since Grey is the same as Gray in the enum definition.

16 Methods for ABL Enums Implicitly inherits from Progress.Lang.Enum
GetValue() ToString() CompareTo() Equals() All regular ABL enums inherit from Progress.Lang.Enum, which provides a set of methods specific for ABL enums. GetValue() returns the internal value associated with the enum member. ToString() returns the name of the member as defined by the ABL enum. CompareTo() allows you to compare two instances of the same enum type and check if the value is less than, greater than or equal. The value compared is the internal numeric value associated with each enum instance. Equals() allows you to check if two enum instances are the same, as long as they are the same type.

17 ABL Enums - GetValue and ToString
def var eColor as Colors. eColor = Colors:Red. tblName.intField = eColor:GetValue(). // or INT(eColor) tblName.charField = eColor:ToString(). // or STRING(eColor) You can call the GetValue() or ToString() method on ABL enums to get the numeric value or the member name for the instance the method is being called on. You can alternatively call the INT() or INT64() ABL functions instead of GetValue(). The STRING() function returns the same value as the ToString() method.

18 Getting Enum Instance from Name/Value
All ABL enums have a GetEnum method which is strongly-typed GetEnum(member-name as char) GetEnum(numeric-value as int64) def var eColor as Colors. eColor = Colors:GetEnum(tblName.intField). eColor = Colors:GetEnum(tblName.charField). All ABL enums have a method called GetEnum with 2 overloads which can be used to turn a value or name into an enum instance. The method is part of the ABL enum definition and it is strongly-typed, that is, its return type is the enum type it is being called from. Therefore, you can call it to get an instance from a value or name and still get the compiler to make sure the types are compatible. Obviously, the compiler can’t verify that the value specified is a valid value or member name – that validation is done at runtime instead.

19 Defining an ABL Flag Enum Type
Permissions.cls Permission Progress.Lang.FlagsEnum Progress.Lang.Enum Progress.Lang.Object ENUM Permissions FLAGS: DEFINE ENUM None = 0 Read Write ReadWrite = Read,Write Create Delete. END ENUM. You can also define an ABL enum as a special type of enum, called a flag enum. When you define a variable as a flag enum type, it can hold the value of one or more members at any given time, that is, multiple flags can be set at a given time. ABL flag enums inherits from Progress.Lang.FlagEnums, which in turn inherits from Progress.Lang.Enum. Therefore, ABL flag enums provides the same methods provides for all ABL enums and some additional methods that are specific to flag enums, such as to set and unset one or more values from a variable. As with regular enums, you can define a member that is equivalent to one of more pre-defined members. In the example above, the ReadWrite member is defined to have both the Read and Write flags set. The same support for CASE, IF, expressions, etc as shown in previous slides for regular ABL enums is also applicable for ABL flag enums. Note that we recommend that you set an enum member for the value zero (0) if you may have no flags set on a particular case, so that you can use it in comparisons.

20 Methods for ABL Flag Enums
Implicitly inherits from Progress.Lang.FlagsEnum Method: IsFlagSet() All ABL flag enum types contains the following strongly-typed methods: SetFlag() UnsetFlag() ToggleFlag() ToString() may return a comma-separated list of flags set All ABL flag enums inherit from Progress.Lang.FlagsEnum, which provides a method called IsFlagSet() specific for ABL flag enums. All ABL flag enums also provide 3 methods that provide an easy way for setting, unsetting and toggling a flag. The ToString() method can be called for any ABL enum. When called for a flag enum, it may return a comma-separated list, if multiple flags are set. The parameters passed into these methods must be of the exact same enum type as the enum type they are being called from. The next slides talk about these methods.

21 ABL Flag Enums : Setting Flag
Set one or more flags for a flag enum type in one of two ways: SetFlag() method Bitwise OR operator def var ePerm as Permissions. ePerm = Permissions:Read. ePerm = ePerm:SetFlag(Permissions:Write). ePerm = ePerm OR Permissions:Delete. You can set flags for a flag enum either with the SetFlag() method that is available to all ABL flag enums, or the bitwise OR operator. You must specify members of the exact same enum type. In the example above, the ePerm variable is initially set with the Read. The SetFlag() method is called to combine that flag with the Write flag and assign it to the ePerm variable. In the above example, after SetFlag() executes, it will have the Read,Write flags set. The OR operator is used to combine those two flags with the Delete flag, that is, after that statement is executed, ePerm has the Read,Write and Delete flags set.

22 ABL Flag Enums: Check if Flag is Set
Check if one or more flags are set for a flag enum type in one of two ways: IsFlagSet() method Bitwise AND operator def var ePerm as Permissions. <…> if ePerm:IsFlagSet(Permissions:Read) then... if (ePerm AND Permissions:Read) eq Permissions:Read then ... When you need to check if a flag is set, you can either use the IsFlagSet() method that is available to all ABL flag enums, or the bitwise AND operator. You must specify members of the exact same enum type. The IsFlagSet() method returns true or false depending on whether the flag(s) specified is/are set in the instance where the method is called from. You can also use the AND operator on an enum. Note that the result is another enum instance. The IF statement requires a logical expressions that resolves to true or false. That is why you need to add the equality operator to make that expression satisfy the requirements of the IF statement.

23 ABL Flag Enums: Other operations
Unset one or more flags for a flag enum type in one of two ways: UnsetFlag() method Bitwise NOT operator Toggle one or more flags for a flag enum type in one of two ways: ToggleFlag() method Bitwise XOR operator Flag enums also support two other operations: - unset a flag, which you can do with the UnsetFlag() method that is available to all ABL flag enums, or the bitwise NOT operator (in conjunction with the bitwise AND operator). For example: ePerm = ePerm AND (NOT Permissions:Read). The example above will perform an AND operation with the value of ePerm and combine it with the result from the NOT expression (which will have that flag unset), and set it to the variable. Toggle a flag. This allows you to either set a flag, if it’s unset, or unset it if it is already set. You can use this to handle situation where 2 (or more) flags cannot be set at the same time. For instance, assuming an enum called Options with 2 members, Option1 and Option2: def var eOptions as Options. def var exclusiveFlags as Options. exclusiveFlags = Options:Option1 OR Options:Option2. // initial value eOptions = Options:Option1. eOptions = eOptions:ToggleFlag(exclusiveFlags). // Now, eOptions has the Option2 flag set, and Option1 unset. // Now, eOptions has the Option1 flag set, and Option2 unset.

24 ABL Flag Enums: Dynamic Access
DYNAMIC-ENUM ToObject() static method in Progress.Lang.Enum DYNAMIC-ENUM ( enum-type-name, member-name-or-value) ToObject(enum-type-name, member-name) ToObject(enum-type-name, numeric-value) You can get access to an enum dynamically in two ways: the new DYNAMIC-ENUM function ToObject() method in the Progress.Lang.Enum class, which all ABL enums inherit from (directly or otherwise). This is the OOABL way, but since the return type is the base-class Progress.Lang.Enum, you may need to CAST it if you want to reference it as a stronger type. Both of them take the enum type name as a character expression (fully qualified name) and either the name of the enum member or the int64 value that represents an enum member.

25 ABL Enums: Reflection Progress.Lang.Class provides additional methods
Get comma-separated list of enum member names Get comma-separated list of enum values GetEnumNames() GetEnumValues() The Progress.Lang.Class class, which provides support for reflection, now contains methods that are specific for enum types. Among them: - GetEnumNames(), which returns a comma-separated list of all the enum member names defined by the enum type. GetEnumValues(), which returns a comma-separated list of all the numeric values for the enum members defined by the enum type. The values are returned in the same order, so you can match them up by position in the comma-separated list.

26 .NET Enums Support for .NET enums enhanced to provide:
Logical operators (EQ, NE, LT, LE, GT, GE) Bitwise operators (OR, AND, XOR and NOT) CASE statement DYNAMIC-ENUM Reflection support NOTE: Progress.Util.EnumHelper class is not necessary anymore. Support for .NET enums has existed in the ABL fro a while and it was provided via a helper class, Progress.Util.EnumHelper, which provided methods for manipulating enums and perform logical and bitwise operations. We enhanced the support for .NET enums in the ABL so now you can take advantage of the functionality provided for ABL enums when you are working with .NET enums as well (as listed above). The Progress.Util.EnumHelper is provided for backward compatibility only.

27 Object Serialization

28 Object Serialization 11.4 introduced object serialization via parameter passing between ABL client and AppServer Serialization and deserialization can now be done programmatically Formats supported : binary and JSON Class must be marked as SERIALIZABLE Object graph is serialized In 11.4, we introduced object serialization via remote calls to an AppServer, so that you could throw errors from the AppServer to an ABL client and pass parameters between ABL clients and AppServers. In 11.6, we are introducing functionality so that developers can programmatically serialize and deserialize OOABL objects. This can be useful in cases where you want to save some data into disk and reload it at a later time (such as when the application restarts). The data can be serialized in either binary or JSON format. As with parameter passing, the class must be marked as SERIALIZABLE before it can be serialized. Note that ABL enums are serializable by default. The whole object graph is serialized, that is, objects that are referenced by data members are also serialized.

29 Object Serialization Flow
Object Instance Serializer Stream Before we continue, this is a high-level flow of how object serialization works. An object instance is passed to a serializer object, which is responsible for generating the serialized data in the format desired. The serializer then passes the data to a stream object, which is then responsible for the storage of the serialized data. That can be a file, a database field, or any other type of storage. When deserializing an object, the serializer asks the stream object for data and then it reconstructs the object in memory. Storage

30 Stream Classes for Supporting Serialization
For serialization support: Progress.IO.OutputStream (abstract) Progress.IO.FileOutputStream Write( mData as memptr, offset as int64, len as int64) FileOutputStream(fileName as char) FileOutputStream(fileName as char, appendMode as logical) New built-in classes are provided to support object serialization. These classes are provided as the interface for handling where and how the serialized data is stored into or retrieved from. The Progress.IO.OutputStream class is an abstract class that can be implemented by developers and provides an interface for handling the writing out of the data provided via object serialization. That allows developers to have control over how and where the serialized data is stored. For instance, a file, a database field, etc. The data is passed to the stream object via a memptr. The Progress.IO.FileOutputStream class inherits from Progress.IO.OutputStream and provides out-of-the-box support for writing the data to a file.

31 Stream Classes for Supporting Serialization (Cont’d)
For deserialization support: Progress.IO.InputStream (abstract) Progress.IO.FileInputStream Read( mData as memptr, offset as int64, len as int64) FileInputStream(fileName as char) Similarly, the Progress.IO.InputStream class is an abstract class that can also be implemented by developers and provides an interface for reading the data during object deserialization. The data is passed via a memptr. The Progress.IO.FileInputStream class is the counterpart of the FileOutputStream class, and provides support for reading from a file.

32 Binary Serialization Same rules defined for parameter passing to / from AppServer With a few exceptions, all public, protected and private data members are serialized Class API must match during deserialization More efficient but may be less flexible The rules for passing OOABL objects as parameters to and from the AppServer are the same for binary serialization. In general, all public, protected and private data members are serialized. You cannot serialize .NET types, MEMPTRs that came from an external library/dll, among other things. During object deserialization, the class API must be the same as it was when the object was serialized. If not, the deserialization will fail. This method is more efficient because the data is stored in the file in storage format so there is no conversion. But it is less flexible because the class API must match exactly during deserialization.

33 Serializing Object - Binary Format
Progress.IO.BinarySerializer Provides binary serialization and deserialization Serialize() calls Write() method on class that inherits from OutputStream class passing serialized data Serialize(objectRef as Progress.Lang.Object, oStream as Progress.IO.OutputStream) The Progress.IO.BinarySerializer class provides the functionality for serializing and deserializing OOABL objects. The Serialize() method serializes the object in binary format and then calls the Write() method on the class that inherits from OutputStream, which is responsible for handling the storage of the serialized data. The Write() method may get called multiple times with chunks of data.

34 Deserializing Object - Binary Format
Progress.IO.BinarySerializer Deserialize() calls Read() method on class that inherits from InputStream class to get the deserialized data Deserialize(inStream as Progress.IO.InputStream) The Deserialize() method reads the data out of the InputStream and reconstructs the object, returning a reference to the newly created object. Note that the return type of the Deserialize method is Progress.Lang.Object. The Deserialize method calls the Read() method on the class that inherits from InputStream to read the data. It may read the data in chunks.

35 Binary Serialization Example
using Progress.IO.*. def var oCustBE as CustomerBE. def var binSerializer as BinarySerializer. def var oStream as FileOutputStream. <…> binSerializer = new BinarySerializer(). oStream = new FileOutputStream("oCust.bin"). binSerializer:Serialize(oCustBE, oStream). This is an example that shows how to serialize an object of type CustomerBE (which is assumed to be marked as SERIALIZABLE) in binary form to a file named oCust.bin. Note that you can replace the instance of FileOuputStream with a class that inherits from Progress.IO.OuputStream and have a custom stream object that handles the storage of the data into something other than a file, or maybe does something more to the data (for example, encrypting it).

36 Binary Deserialization Example
binSerializer = new BinarySerializer(). inStream = new FileInputStream("oCust.bin"). oCustBE = CAST(binSerializer:Deserialize(inStream), CustomerBE). The above is an excerpt based on the previous example that shows how you would deserialize the data from the file generated in the previous example back into an object instance. Since Deserialize’s return type if Progress.Lang.Object, you must use CAST to assign it to a stronger type.

37 JSON Serialization By default only public data members are serialized
Can specify one or more non-public data members to be serialized via new syntax Deserialization less strict – API doesn’t have to exactly match Common use case is to interact with external systems Less efficient but more flexible Only public data members are serialized when you perform JSON serialization. You can include one or more non-public data members in the serialization via new syntax (described in the next slide). The serialization and deserialization is based on the data member names and data types, so the class API does not have to exactly match when you deserialize the data (in contrast to binary serialization). For that reason, it is more flexible but less efficient than binary serialization and the data is not stored in storage format and conversions to and from character form must be performed. A common use case for JSON serialization is when you need to interact with external systems that expect the data in JSON format.

38 Serialization of Non-Public Data Members
SERIALIZABLE keyword added to: DEFINE VARIABLE DEFINE PROPERTY DEFINE TEMP-TABLE DEFINE DATASET DEFINE [ PRIVATE | PROTECTED | PUBLIC ] [ STATIC | ABSTRACT ] [ OVERRIDE ] [ SERIALIZABLE ] PROPERTY property-name To include non-public data members in the JSON serialization, you can now add the SERIALIZABLE keyword to its definition. The keyword is allowed when defining a variable, property, temp-table and dataset as a data member (in a class only).

39 Serializing Object - JSON Format
Progress.IO.JsonSerializer Provides serialization and deserialization in JSON format Serialize() and Deserialize() methods JsonSerializer (input formatted as logical) The Progress.IO.JsonSerializer class provides the functionality for serializing and deserializing OOABL objects in Json format. The constructor for JsonSerializer takes a logical input parameter that allows you to instruct the Serialize() method to format the Json string in a hierarchical manner using extra white space, carriage returns, and line feeds. Similar to the BinarySerializer class, the JsonSerializer class provides the Serialize() and Deserialize() methods which work in conjunction with the OutputStream and InputStream objects.

40 JSON Serialization Example
using Progress.IO.*. def var oCustBE as CustomerBE. def var jSerializer as JsonSerializer. def var oStream as FileOutputStream. <…> jSerializer = new JsonSerializer(yes). oStream = new FileOutputStream("oCust.json"). jSerializer:Serialize(oCustBE, oStream). This is an example that shows how to serialize an object of type CustomerBE (which is assumed to be marked as SERIALIZABLE) in JSON format to a file named oCust.json. Note that you can replace the instance of FileOuputStream with a class that inherits from Progress.IO.OuputStream and have a custom stream object that handles the storage of the data into something other than a file.

41 JSON Deserialization Example
jSerializer = new JsonSerializer(false). inStream = new FileInputStream("oCust.json"). oCustBE = CAST(jSerializer:Deserialize(inStream), CustomerBE). The above is an excerpt based on the previous example that shows how you would deserialize the data from the file generated in the previous example back into an object instance.

42 JSON Example “CustNum": 1000, “CustName": “Test", "prods:datasets": {
"prods:version" : 1, "prods:objId" : 1, “CustomerBE": { “CustNum": 1000, “CustName": “Test", "prods:datasets": { “DsetDetails": { “TTDetails": [ “favColor": “orange” } ] This is an example of the JSON string generated for a class CustomerBE with a few properties and a temp-table that is part of a dataset. This implies that the dataset and temp-table were marked as SERIALIZABLE since they can’t be public.

43 Reflection

44 Reflection Used for inspecting and making decisions about execution at runtime Progress.Lang.Class provided limited support Release 11.6 introduces: Support for accessing information about the elements of a class New built-in classes for Reflection We had some limited support for reflection in the ABL. Reflection allows you to get information about classes and its members and optionally use that information to make decisions at runtime which may modify program execution. Prior to 11.6, reflection support was provided via the Progress.Lang.Class class which allowed you to get some information about the class and invoke methods or access and update properties dynamically, but you had to know what to call beforehand. In 11.6, we extended the support for reflection which allows you to get information about members of a class, and then you can act on them. For example, you can check if a specific method with a specific set of parameter is available and then you can invoke it. Or you can get information about all the overloads of a given method, get information about its signature and decide which one you want to invoke. We added new built-in classes to provide the additional functionality, which will be described in the next slides.

45 Progress.Lang.Class methods
Return GetConstructor GetConstructors Progress.Reflect.Constructor GetMethod GetMethods Progress.Reflect.Method GetProperty GetProperties Progress.Reflect.Property GetVariable GetVariables Progress.Reflect.Variable GetEvent GetEvents Progress.Reflect.Event GetInterfaces Progress.Lang.Class The Progress.Lang.Class class now contains a set of new methods that allows you to get information about the different members of a class. GetConstructor and GetConstructors allow you to get information about constructor(s). GetConstructor returns an instance of type Progress.Reflect.Constructor for a given constructor (if one exists) given a set of parameters. GetConstructors returns an array of Progress.Reflect.Constructor instances for constructors (based on some input you have to provide). Similarly, there are method for getting information about methods, properties, variables, events and interfaces.

46 GetMethods GetMethods()
Returns array with information about methods of a class Public non-static GetMethods() All methods work in a very similar fashion, so let’s take a look at GetMethods (most of it will apply to the other methods too). We provide GetMethods() that allows you to get information about all public non-static methods of a class (and its super classes).

47 GetMethods(flags as Progress.Reflect.Flags)
GetMethods with Flags Returns information about a method of a class based on flags New built-in flag enum Progress.Reflect.Flags Access Mode Scope Class level Public Static DeclaredOnly Protected Instance Private But what if you do not want to look at the public non-static methods only or you only want the methods that belong to the class you are reflecting on, and not in any of its super classes? We provide an overload for GetMethods() that allows you to have more control over which methods are returned. That is accomplished by a new built-in ABL flag enum type named Progress.Reflect.Flags. Those flags allow you to choose what methods GetMethods() should look at in three groups: Public, Private or Protected Static or Instance DeclaredOnly So you choose the access mode for the methods you are looking for, then you must choose either static or instance. Optionally you can choose that you only want to look at methods that are defined in the class represented by the Progress.Lang.Class instance you are calling it from. The default behavior is that it will llok for the methods in all the classes in the hierarchy. GetMethods(flags as Progress.Reflect.Flags)

48 USING Progress.Reflect.*. def var pclObj as Progress.Lang.Class.
GetMethods Example USING Progress.Reflect.*. def var pclObj as Progress.Lang.Class. def var methFlags as Flags. def var methObjArray as Method extent. plcObj = Progress.Lang.Class:GetClass("myCls"). methFlags = Flags:Public OR Flags:Static. methObjArray = plcObj:GetMethods(methFlags). This is an example that shows how to get all methods in myCls.cls and its hierarchy that are defined as public static methods.

49 params as Progress.Lang.ParameterList)
GetMethod Returns information about a method of a class Public non-static GetMethod( name as char, params as Progress.Lang.ParameterList) plcObj = Progress.Lang.Class:GetClass("myCls"). paramObj = new ParameterList(0). methObj = plcObj:GetMethod("ProcessInfo", paramObj). GetMethod() returns information about a method given its name and the set of parameters. This only returns information about non-static public methods. The ‘params’ parameter is an instance of Progress.Lang.ParameterList that describes the signature of the method you are looking for. In the example above, assume we have a class named myCls, and you want to find a method called ProgressInfo that takes no parameters. You first get a Progress.Lang.Class instance by calling the GetClass() method, then get a Progress.Lang.ParameterList instance with 0 parameters, and call the GetMethod() method passing the method name and the ParameterList instance. If no such method exists, you get the unknown value back, otherwise you get an instance of type Progress.Reflect.Method that describes the method.

50 params as Progress.Lang.ParameterList)
GetMethod with Flags Returns information about a method of a class based on flags GetMethod( name as char, flags as Progress.Reflect.Flags, params as Progress.Lang.ParameterList) But what if what you are looking for is a public static method, or you only want the method if it belongs to the class you are reflecting on, and not in any of its super classes? We provide an overload for GetMethod() that allows you to have more control over which method is returned. That is accomplished by the new built-in ABL flag enum type named Progress.Reflect.Flags, described in a previous slide.

51 GetMethod with Flags - Example
Return public static method “ProcessInfo” with a single logical input parameter plcObj = Progress.Lang.Class:GetClass("myCls"). paramObj = new ParameterList(1). paramObj:SetParameter(1, “logical”, “input”, NO). methFlags = Flags:Public OR Flags:Static. methObj = plcObj:GetMethod("ProcessInfo", methFlags, paramObj). This is an example that shows how to find out if there is a public, static method called ProcessInfo() that is defined by myClass or any of its super classes, and takes an input parameter of type logical.

52 Progress.Reflect.Method
Properties Methods Name NumParameters ReturnType ReturnTypeName ReturnExtent AccessMode IsStatic GetParameters Invoke ToString Once you get an instance of Progress.Reflect.Method from GetMethods() or GetMethod(), you can get information about the method via its properties and methods. The above list is just a sample of properties and methods available in the Progress.Reflect.Method class. You can get information on the name of the method, the number of parameters, return type (via an enum of type Progress.Reflect.DataType), the return type name for OOABL types (that is the class name), the number of extents for the return value, the access mode of the method and whether the method is static. The GetParameters() method returns an instance of Progress.Reflect.Parameter with information about each parameter defined for the method. You can call Invoke() on it to execute the method on a given instance. ToString() returns a string with the method name and signature.

53 Other Progress.Reflect Classes
Similar functionality for other types of members Progress.Reflect.Property and Progress.Reflect.Variable Get() and Set() Progress.Reflect.Constructor Invoke() - instantiate object The other methods in Progress.Lang.Class to return information on properties, variables and constructors behave in a very similar way to how GetMethod() and GetMethods() behave, but each one of these will have their own specific functionality. You can call Get() or Set() on a Progress.Reflect.Property or Progress.Reflect.Variable instance, to get or set the value of a variable or property, respectively. You can call invoke() on a Progress.Reflect.Constructor instance to invoke the constructor, that is, instantiate a class.

54 RadForm Subclasses

55 RadForm Subclasses Telerik's UI for WinForms includes three form classes: RadForm RadRibbonForm ShapedForm Telerik provides 3 types of Windows Forms.

56 RadForm Subclasses (Cont’d)
We provide subclasses that extend Telerik’s forms: Progress.Windows.OERadForm Progress.Windows.OERadRibbonForm Progress.Windows.OEShapedForm Progress.Windows.MDIChildRadForm Progress.Windows.MDIChildRadRibbonForm Progress.Windows.MDIChildShapedForm Similarly to how we provide Progress.Windows.Form as a subclass of System.Windows.Forms.Form, we are providing subclasses for the three form classes provided by Telerik. These subclasses contain fixes for bugs in the super classes and extensions to its capabilities and to provide better integration with OpenEdge. Just to name a few, these are some of the functionality that is provided by the OpenEdge subclasses: - A disabled System.Windows.Forms.Form will not show the system wait cursor. Dialog boxes do not follow the expected disposal model. Support for TOP-ONLY and WINDOW-DELAYED-MINIMIZE when mixing ABL windows and .NET forms.

57


Download ppt "What’s New in the ABL in OpenEdge Release 11.6"

Similar presentations


Ads by Google