Type introspection

From Wikipedia, the free encyclopedia

In computing, type introspection is a capability of some object-oriented programming languages to determine the type of an object at runtime. This is a notable capability of the Objective-C language, and is a common feature in any language that allows object classes to be manipulated as first-class objects by the programmer. Type introspection can be used to implement polymorphism.


Contents

[edit] Examples

[edit] Ruby

Type introspection is a core feature of Ruby as well. In Ruby, the Object class (ancestor of every class) provides Object#instance_of? and Object#kind_of? methods for checking the instance's class. The latter returns true when the particular instance the message was sent to is an instance of a descendant of the class in question. To clarify, consider the following example code (you can immediately try this with irb):

$ irb
irb(main):001:0> A=Class.new
=> A
irb(main):002:0> B=Class.new A
=> B
irb(main):003:0> a=A.new
=> #<A:0x2e44b78>
irb(main):004:0> b=B.send 'new'
=> #<B:0x2e431b0>
irb(main):005:0> a.instance_of? A
=> true
irb(main):006:0> b.instance_of? A
=> false
irb(main):007:0> b.kind_of? A
=> true

In the example above, the Class class is used as any other class in Ruby. Two classes are created, A and B, the former is being a superclass of the latter, then one instance of each class is checked. The last expression gives true because A is a superclass of the class of b. In the example below the syntactic sugar provided by Ruby is used to define classes (and leads to the same result):

$ irb
irb(main):001:0> class A; end
=> nil
irb(main):002:0> class B < A; end
=> nil
irb(main):003:0> a=A.new
=> #<A:0x2e4c33c>
irb(main):004:0> b=B.new
=> #<B:0x2e4a974>
irb(main):005:0> a.instance_of? A
=> true
irb(main):006:0> b.instance_of? A
=> false
irb(main):007:0> b.kind_of? A
=> true

Or you can directly ask for the class of any object, and "compare" them (code below assumes having executed the code above):

irb(main):008:0> A.instance_of? Class
=> true
irb(main):009:0> a.class
=> A
irb(main):010:0> a.class.class
=> Class
irb(main):011:0> A > B
=> true
irb(main):012:0> B <= A
=> true

[edit] Objective-C

In Objective-C, for example, both the generic Object and NSObject (in Cocoa/OpenStep) provide the method isMemberOfClass: which returns true if the argument to the method is an instance of the specified class. The method isKindOfClass: analogously returns true if the argument inherits from the specified class.

For example, say we have a Puppy and Kitten class inheriting from Animal, and a Vet class.

Now, in the desex method we can write

- desex: (id) to_desex
{
   if([to_desex isKindOfClass:[Animal class]])
   {
      //we're actually desexing an Animal, so continue
      if([to_desex isMemberOfClass:[Puppy class]])
         desex_dog(to_desex);
      else if([to_desex isMemberOfClass:[Kitten class]])
         desex_cat(to_desex);
      else
         error();
   }
   else
   {
      error();
   }
}

Now, when desex is called with a generic object (an id), the function will behave correctly depending on the type of the generic object.

[edit] C++

C++ supports type introspection via the typeid operator. To enable this operator, the code must be compiled with RTTI.

Andrei Alexandrescu showed how to wrap the typeid operator in a Equality Comparable and LessThan Comparable class in his book Modern C++ programming. Code is available in the Loki library.

#include "loki/TypeInfo.h"
#include <boost/shared_ptr.hpp>
#include <map>
 
class TypeToTypedInstanceMap
{
public:
  template <class T> 
  void put(boost::shared_ptr<T> ptr)
  {
    map_[Loki::TypeInfo(typeid(T))] = ptr;
  }
 
  template <class T> 
  boost::shared_ptr<T> get()
  {
    return static_cast<boost::shared_ptr<T> >(map_[Loki::TypeInfo(typeid(T))]);
  }
private:
  std::map<Loki::TypeInfo, boost::shared_ptr<void> > map_;
};

http://www.aoc.nrao.edu/~tjuerges/ALMA/ACS/Docs/ACS_docs/cpp/lokiTypeInfo_8h-source.html

http://www.sgi.com/tech/stl/LessThanComparable.html

http://www.sgi.com/tech/stl/EqualityComparable.html

[edit] See also


Languages