Hello folks!
When downcasting object pointers, I often wish there was a way to check the cast before.
Peter has already told, in one of the next alpha releases of GPC there will be a new downcast-operator named 'as' firing a runtime error in case of an invalid downcast; like this:
... tBar = object ( tFoo ) ...; ... foo: pFoo; ... with foo^ as tBar do (* if "foo^" isn't a tBar actually, the 'as' *) ... (* interrupts the program with a runtime error. *)
Nevertheless I'd like to have a way to check the validity _before_ casting, thus preventing the runtime error in cases where I don't want the program to be interrupted.
Currently, I'd suggest the following additional functions in GPC itself:
Function getObjectType ( obj: object ): "type"; Function isOfObjectType ( obj: object; runtimeType: "type" ): boolean;
Example:
... p: pObject; ... p:= new ( pBar, init ); ... getObjectType ( p^ ) ... (* returns "tBar" *) ... ... isOfObjectType ( p^, pFoo ) ... (* returns "true", since tBar *) (* is derived from tFoo. *)
For downcasting, I'd only need the latter one, but the first function seems useful to me, too.
Alternatively, I could need a mechanism to absorb the runtime error fired by "as" before it interrupts the program. Something like this:
foo: pFoo; ... with foo^ as tBar do ...; catchRuntimeError ( @procedureToHandleRuntimeError, parameters );
Anyway, when implementing a catchRuntimeError mechanism in GPC, it would not seem reasonable to me to just do it for this special kind of runtime error; thus, here we'd need a general exception handling mechanism to catch and handle _any_ runtime error without interrupting the program.
Hope this description of my ideas wasn't too confuse...
Yours
Markus
Peter: Will 'as' only be for use in a 'with' clause, or will it be more general, like this:
bar:= foo as pBar;
If possible, I'd prefer the more general version.
Markus Gerwinski wrote:
Peter: Will 'as' only be for use in a 'with' clause, or will it be more general, like this:
bar:= foo as pBar;
If possible, I'd prefer the more general version.
The general version is what is planned.
Peter
Markus Gerwinski wrote:
Nevertheless I'd like to have a way to check the validity _before_ casting, thus preventing the runtime error in cases where I don't want the program to be interrupted.
Currently, I'd suggest the following additional functions in GPC itself:
Function getObjectType ( obj: object ): "type";
There's (BP compatible) `TypeOf (ObjectType or ObjectVariable)' (returns a pointer which should be considered meaningless except for the fact that it's the same for same types), so you could check `if TypeOf (foo^) = TypeOf (tBar)', but this will fail on subtypes of tBar.
Function isOfObjectType ( obj: object; runtimeType: "type" ): boolean;
That's `obj is type'. The status of `is' is the same as of `as' (i.e., don't hold your breath)...
Frank
On 18 Mar 01, at 12:49, Markus Gerwinski wrote:
Hello folks!
When downcasting object pointers, I often wish there was a way to check the cast before.
Peter has already told, in one of the next alpha releases of GPC there will be a new downcast-operator named 'as' firing a runtime error in case of an invalid downcast; like this:
... tBar = object ( tFoo ) ...; ... foo: pFoo; ... with foo^ as tBar do (* if "foo^" isn't a tBar actually, the 'as' *) ... (* interrupts the program with a runtime error. *)
Nevertheless I'd like to have a way to check the validity _before_ casting, thus preventing the runtime error in cases where I don't want the program to be interrupted.
Delphi has the "is" operator. Here is an excerpt from the help file;
"The 'is' operator, which performs dynamic type checking, is used to verify the actual runtime class of an object. The expression
object is class
returns True if object is an instance of the class denoted by class or one of its descendants, and False otherwise. (If object is nil, the result is False.) If the declared type of object is unrelated to classÂthat is, if the types are distinct and one is not an ancestor of the otherÂa compilation error results. For example,
if ActiveControl is TEdit then TEdit(ActiveControl).SelectAll;
This statement casts a variable to TEdit after first verifying that the object it references is an instance of TEdit or one of its descendants."
And this is what the Delphi help file says about the "as" operator;
"The as operator performs checked typecasts. The expression
object as class
returns a reference to the same object as object, but with the type given by class. At runtime, object must be an instance of the class denoted by class or one of its descendants, or be nil; otherwise an exception is raised. If the declared type of object is unrelated to classÂthat is, if the types are distinct and one is not an ancestor of the otherÂa compilation error results. "
Currently, I'd suggest the following additional functions in GPC itself:
Function getObjectType ( obj: object ): "type"; Function isOfObjectType ( obj: object; runtimeType: "type" ): boolean;
Example:
... p: pObject; ... p:= new ( pBar, init ); ... getObjectType ( p^ ) ... (* returns "tBar" *) ... ... isOfObjectType ( p^, pFoo ) ... (* returns "true", since tBar *) (* is derived from tFoo. *)
For downcasting, I'd only need the latter one, but the first function seems useful to me, too.
Alternatively, I could need a mechanism to absorb the runtime error fired by "as" before it interrupts the program.
In Delphi, from what the help file says, the program should not compile if the typecasting is wrong. GPC could do the same.
Best regards, The Chief -------- Prof. Abimbola A. Olowofoyeku (The African Chief) Author of: Chief's Installer Pro for Win32 http://www.bigfoot.com/~African_Chief/chief32.htm Email: African_Chief@bigfoot.com