The Introspective Reflection Library

   The  introspective reflection library is a set of objects and classes that allow a program to access information about itself at compile or run time. For example, the program can know the class of an object, the methods and  instance variables of that class, the parameter names and types of each method, and so on.

There is only one way a program can access information about itself at compile time: by sending messages to built-in object TheCompiler. This class object has the following methods:

    LiteralStringNo is a class of the Abstract Syntax Tree of the compiler that represent values of class String.
     Each class in the system is described by an object of ClassInfo or one of its subclasses. To get the object of ClassInfo that describes a class Person we do

var ci : ClassInfo;

ci = Person.getAssociatedClassInfo();
  // print "Person"
Out.writeln( ci.getName() );

    The class of an object can be got by calling method getClassObject:

var p : Person;
var any : AnyClassObject;
any = p.getClassObject();
  // print "Person"
Out.write( any.getAssociatedClassInfo().getName() );

The methods of a class are got in the following way:

var ci : ClassInfo;
var p : Person;
var iter : DS.Iter(ClassMethodInfo);
ci = p.getClassInfo();
iter = ci.getMethods();
while iter.more() do 
    Out.writeln( );

    Instead of using the ClassInfo hierarchy to get information  about classes, one can access information about individual objects, which includes class objects:

var ac : Account;
var objInfo : ObjectInfo;
objInfo = ac.getInfo();
  // list the names of all instance variables of the object
var iter : DS.Iter(ObjectInstanceVariableInfo);
iter = objInfo.getInstanceVariables();
while iter.more() do
    Out.writeln( );
var objMethodInfo : ObjectMethodInfo;
  // get info about method "getBalance" of object ac
objMethodInfo = objInfo.getMethod("getBalance", nil);
  // calls method "getBalance" of object ac. The balance
  // returned is printed

Out.writeln( objMethodInfo.invoke(nil) );

The exceptions this code could generate were not considered.




Some classes of the Introspective Reflection Library 


    The hierarchies of MethodInfo, InstanceVariableInfo , and  AnyObjectInfo are shown in the table above. A subclass is put below a superclass and two columns at the right of it.

    One can create and use an array whose element type will only be known  at run time without using the reflection library. This is possible because all arrays are subclasses of class AnyArray . See the following code.

var any : Any = integer;
var anArray : AnyArray;
  // creates a 10-element integer array
anArray = array(any)[].new(10);
anArray.set(5, 0); // anArray[0] = 5;
anArray.set(3, 1); // anArray[1] = 3;
Out.writeln( anArray.get(0) ); // print 5

    If any does not refer to a class object at run time, an exception will be thrown. All the classes of the introspective reflection library are described in The Green Report .

What is new ?

    None of the functionalities of the introspective reflection library is new. However, the library is well organized in a set of classes with several inheritance hierarchies. Each method was carefully examined to discover in which class it should be put. There is a sharp contrast between The Green IRL and The Java Reflection API, which has several flaws:

The Green IRL has some interesting points:

      proc invoke( vetArgs : array(Any)[] )
which does not requires the object as parameter (only the arguments in vetArgs). Then a call to invoke of ObjectMethodInfo is faster than a call to invoke of ClassMethodInfo which requires another parameter:
      proc invoke( obj : Any; vetArgs : array(Any)[] )
This is important for efficient shell implementation;

     var anArray : AnyArray;
     anArray = array(any)[].new(10);

any should refer to a class object at run time or an exception will be thrown. Class AnyArray has methods get and set for handling array elements.