Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search

Run Time Object Type Identification

 [1/4] from: phil:hayes:cnutarch at: 2-Oct-2001 13:14

Is it possible to implement something like RTTI to identify object types without having to implement the 'type' var? E.g. obj1: make object! [ type: "obj1" ] obj2: make object! [ type: "obj2" ] o1: make obj1 [] o2: make obj2 [] switch/default o2/type [ "obj1" [ print "obj1" ] "obj2" [ print "obj2" ] ] [ print "Unknown" ] Phil

 [2/4] from: greggirwin:starband at: 2-Oct-2001 10:08

Hi Phil, I think the best approach will depend on what it is you need to accomplish. Because objects are cloned, they are very independent. If you want to categorize objects, you could add the 'type or 'kind word as you did in your example. If you want to find if they support one or more interface mechanisms, it should be easy to write a little function to do that (can-do? supports? supports-all?). I'm too much of a newbie to suggest what is best, but my gut tells me that adding type-info blocks to all objects, to support RTTI, is something to reserve for cases where you really need it, rather than making it a general rule. --Gregg

 [3/4] from: joel:neely:fedex at: 2-Oct-2001 20:19

Hi, Phil, Phil Hayes wrote:
> Is it possible to implement something like RTTI to identify > object types without having to implement the 'type' var? >
Not as far as I know. REBOL objects aren't "types" at all, just namespaces that can have whatever content/behavior you want. There's no real notion of class/subclass/inheritance/instance/type that would support the concept of run-time-type-identification. However ...
> E.g. > obj1: make object! [ type: "obj1" ]
<<quoted lines omitted: 7>>
> print "Unknown" > ]
... lots of OO folks aren't really too thrilled with RTTI, because of the potential for "object abuse", such as writing code that decides how to treat the object based on its type. The OO purist would suggest that such behavior be defined within each object so that it can "do the right thing" for itself. For example:
>> obj1: make object! [saytype: [print "type1"]] >> obj2: make object! [saytype: [print "type2"]] >> obj3: make object! [x: 10 y: 12 z: -7] >> announce: func [ob [object!] /local announcer] [
[ either announcer: in ob 'saytype [ [ do announcer [ ][ [ print "unknown" [ ] [ ]
>> announce obj1
>> announce obj2
>> announce obj3
unknown or, for another variation,
>> announce-me: func [ob [object!]] [
[ if error? try [ [ do ob/saytype [ ][ [ print "unknown" [ ] [ exit [ ]
>> announce-me obj1
>> announce-me obj2
>> announce-me obj3
unknown Of course, SAYTYPE could have been a function, but that's beside the main point here, which is that either ANNOUNCE or ANNOUNCE-ME is now independent of how many objects/types there are. It only cares about whether the specified capability is defined for the object at hand. Would this type (pardon the pun ;-) of approach work for you? -jn- -- ; Joel Neely [joel--neely--fedex--com] 901-263-4460 38017/HKA/9677 REBOL [] foreach [order string] sort/skip reduce [ true "!" false head reverse "rekcah" none "REBOL " prin "Just " "another " ] 2 [prin string] print ""

 [4/4] from: dankelg8:cs:man:ac at: 3-Oct-2001 15:21

Here's a function that checks if an object spec implements an interface... It's very simple but it can be useful. This replaces make object! I've just called the function 'implements, but Gregg's ideas are probably better. Gisle implement: func [ "Returns a new object after checking that it conforms to an interface" [catch] interface [object!] "All fields in this object must be implemented" impl [block!] "A block that would normally be passed to make object!" /local result args-rule args args' f1 f2 ][ result: make object! impl args-rule: [copy args [[to /local] | [to end]] to end] foreach word first interface [ if not find first result word [ throw make error! join "Object must implement " word ] if function? f1: get in interface word [ if not function? f2: get in result word [ throw make error! reform [ word "is of type" type? :f2 newline "Should be:" type? :f1 ] ] parse filter copy third :f1 func [x] [not string? x] args-rule args': args parse filter copy third :f2 func [x] [not string? x] args-rule if not-equal? args' args [ throw make error! reform [ "Object implements function" word "with arguments" mold args newline "Should be:" mold args' ] ] if not find third :f2 string! [ args: copy/deep third :f1 foreach item args [ if all [block? item datatype? item/1][ map item func [x] [to-word mold x] ] ] set in result word func args second :f2 ] ] ] result ] map: func [series [series!] ff [any-function!]][ forall series [change/only series ff first series] head series ] filter: func [series [series!] pred [any-function!]] [ while [not tail? series][ either pred first series [series: next series] [remove series] ] head series ] On Tue, 2 Oct 2001, Gregg Irwin wrote:

  • Quoted lines have been omitted from some messages.
    View the message alone to see the lines that have been omitted