CSC/ECE 517 Fall 2010/ch1 1c JF

From Expertiza_Wiki
Revision as of 00:37, 9 September 2010 by Jmfoste2 (talk | contribs)
Jump to navigation Jump to search

Reflective Language Features vs Reflective Packages

Introduction

Reflection allows a program to access information about its objects (introspection) and to modify program behavior based on that information (intercession 3). Some languages, like Ruby and SmallTalk, are inherently reflective, while other languages, like C# and Java, implement reflective language by including a reflective package. In a reflective language, information about an object or class is accessed directly. In languages with reflective packages, the information is accessed by creating another object that can access that information. There are many features that reflection gives a language. Implementation for these features differs depending on whether it is an inherently reflective language, or a language with a reflective package.

Introspective Features

One of the most powerful features that reflection provides is the ability, given an object, to know what kind of object it is, and what methods it contains. In a reflective language, like Ruby, that is done by directly querying the object. For example, with the given class:

class Sample
  #empty class
end
s = Sample.new

The call:

puts s.class

will list "Sample" as the class and the call:

puts s.methods

will list the methods that Sample has (which will include all the methods in Sample's superclass – Object).


In a language with a reflective package, like Java, a separate object must be created and that object contains the information. For example, with the given class:

import java.lang.reflect.*;

public class Sample {
//Empty class
}

The class information can be found by invoking:

Sample samp = new Sample();
Class sampClass = s.getClass();
System.out.println(sclass.getName());

and the method list can be found with:

Method[] meth = sampClass.getMethods();
for (int i = 0; i < m.length; i++){
   System.out.println(meth[i]);
}

In Java, a Class object is created to access class information, and a method object is created for method information.

Intercessive Features

Reflective languages allow method calls to be made dynamically. Again, in an inherently reflective language, these calls are made directly on the object. However, with a reflective package, the calls are directed through an additional object layer. For example, in Ruby, this code:

class Sample
  def printOne
    puts 1
  end
  
  def printTwo
    puts 2
  end
  
  def printThree
    puts 3
  end
end

s = Sample.new

option="printOne"
s.send(option)

option="printThree"
s.send(option)

will print "1" and then "3". The call:

s.send(option)

is the same, but the "option" value has changed and that is what determines the method that is called. This same behavior can happen in languages with dynamic packages. For example, in Java, this code:

import java.lang.reflect.*;

public class Sample {
	
	public void printOne(){
		System.out.println("1");
	}
	
	public void printTwo(){
		System.out.println("2");
	}
	
	public void printThree(){
		System.out.println("3");
	}
	
	public static void main(String args[]){
		Sample s = new Sample();
		Class sampClass = s.getClass();
		String option = "printOne";
		try {
			Method m = sampClass.getMethod(option);
			m.invoke(s, null);
		} catch (NoSuchMethodException nsme){
			nsme.printStackTrace();
		} catch (IllegalAccessException iae){
			iae.printStackTrace();
		} catch (InvocationTargetException ite){
			ite.printStackTrace();
		}
		option = "printThree";
		try {
			Method m = sampClass.getMethod(option);
			m.invoke(s, null);
		} catch (NoSuchMethodException nsme){
			nsme.printStackTrace();
		} catch (IllegalAccessException iae){
			iae.printStackTrace();
		} catch (InvocationTargetException ite){
			ite.printStackTrace();
		}
	}
}

will result in the same behavior ("1" and then "3" are printed, with the only thing changing the "option" string), but to achieve it a Class object was created to retrieve information about the original object, and a Method object was created to retrieve method information from the Class object.

References

[1] Reflection-Oriented Programming

[2] Procedural Reflection in Programming Languages

[3] Evolving a Reflective Language Lessons Learned from Implementing Traits

[4] Java Reflection Explained Simply

[5] Using Java Reflection

[6] Thomas, Dave with Chad Fowler and Andy Hunt. Programming Ruby. North Carolina: The Pragmatic Bookshelf, 2005.