CSC/ECE 517 Fall 2010/ch1 1c JF: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
No edit summary
No edit summary
 
(18 intermediate revisions by the same user not shown)
Line 1: Line 1:
'''Reflective Language Features vs Reflective Packages'''
'''Reflective Language Features vs Reflective Packages'''


== Introduction ==
=Introduction: Reflection, Reflective languages and Reflective packages=


[http://en.wikipedia.org/wiki/Reflection_(computer_science) Reflection] allows a program to access information about its objects ([http://en.wikipedia.org/wiki/Type_introspection introspection]) and to modify program behavior based on that information (intercession [http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.153.6604 3]). Some languages, like Ruby and Objective-C, are inherently reflective, while other languages, like C# and Java, implement reflective language by including a reflective packageIn a reflective language, information about an object or class is accessed directlyIn languages with reflective packages, the information is accessed by creating another object that can access that informationThere are many features that reflection gives a languageImplementation for these features differs depending on whether it is an inherently reflective language, or a language with a reflective package.
[http://en.wikipedia.org/wiki/Reflection Reflection] is an aspect of a computer languages that allows "computations to observe and modify properties of their own behavior."[1] It was first explained in Brian Cantwell Smith's 1982 paper ''Procedural Reflection in Programming Langauges''[2]. A reflective language is a programming language that has been architected to allow reflectionThis means the language was constructed to "'reason' effectively and consequentially about its own inference process."[2] Reflection provides languages with versatility [5] and flexibility [3]Languages that are not reflective can incorporate some of the features of reflection by using reflective packagesFor example, Java includes a reflective package called "java.lang.reflect." 


= Introspective Features =
=Reflective Language Features vs Reflective Packages=


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 containsIn a reflective language, like Ruby, that is done directly. For example:
The features of a reflective language can be broadly categorized as either introspection or intercession. "Introspection is the ability for a program to observe and therefore reason about its own stateIntercession is the ability for a program to modify its own execution state or alter its own interpretation or meaning."[4]


Introspection is what allows the program to "know" information about itself. This can include an object knowing what kind of object it is, and what methods it has. Intercession is what allows a program to change behavior based on that information.  This can include calling methods dynamically, which means that the actual method that is called on an object is decided when the program is running, and not when the program is compiled.  Another introspective feature granted by reflection is the ability for, when methods are added to an object when the program is running, these methods can be called.
While the behavior between a program written in a reflective language and a program written with a reflective package will be similar, how the features are implemented will differ.  In a reflective language, you can access the information about an object or class from the object or class.  In a language with a reflective package, functionality is provided through intermediary objects.  For the following examples, [http://en.wikipedia.org/wiki/Ruby_(programming_language) Ruby] will be used to illustrate how the features of reflection are implemented in a reflective language and [http://en.wikipedia.org/wiki/Java_(programming_language) Java] will be used to illustrate how the features of reflection are implemented in 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
  class Sample
   #empty class
   #empty class
  end
  end
  s = Sample.new
  samp = Sample.new
  puts s.class
The call:
puts s.methods
  puts samp.class
 
will list "Sample" as the class and the call:
will return "Sample" as the class and a list of the methods that Sample has (which will include all the methods in Sample's superclass – Object).
puts samp.methods
However, in a language with a reflective package, like Java, a separate object must be created and that object contains the information.  For example:
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, the package is not automatically included in the functionality.  It must be imported with:
import java.lang.reflect.*;
Also, for any given object ''A'', a separate class object ''B'', is created and ''B'' contains the information about ''A''.  For example, with the given class:


import java.lang.reflect.*;
  public class Sample {
  public class Sample {
  //Empty class
  //Empty class
}
//Main in another class or same class
public static void main(String args[]){
Sample s = new Sample();
Class sclass = s.getClass();
System.out.println(sclass.getName());
Method[] m = sclass.getMethods();
for (int i = 0; i < m.length; i++){
System.out.println(m[i]);
}
}
  }
  }


will also return the class and methods for the "Sample" object, but it has to go through the "Class" object to get to that information.
The class information can be found by invoking:


= Intercessive Features =
Sample samp = new Sample(); //Create an instance of Sample
 
Class sampClass = samp.getClass(); //Create a class object for instance of Sample
Reflective languages allow method calls to be made dynamicallyAgain, 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.
System.out.println(sampClass.getName()); //Display class name
For example, in Ruby, this code:
and the method list can be found with:
Method[] meth = sampClass.getMethods(); //Return array of method objects for Class object of Sample instance
  for (int i = 0; i < meth.length; i++){
    System.out.println(meth[i]); //Display methods
}
As shown in the above examples, both Ruby and Java have the same reflective feature - the ability for an object or class to "know" about itself.  However, in Java, a Class object is created to access class information, and method information for the object is stored in method objects that can be accessed via the Class object. In Ruby, that information is accessed directly from the object or class in question.


==Intercessive features==
Another important feature granted by reflection, is the ability for dynamic implementation of code. This can take many forms, including object creation and method calling at runtime. Again, in an inherently reflective language, these calls are made directly on the object.  However, when a language has a reflective package to handle reflective features, the calls are directed through a separate object.
For example, in Ruby, this class:
  class Sample
  class Sample
   def printOne
   def printOne
     puts 1
     puts 1
   end
   end
 
   def printTwo
   def printTwo
     puts 2
     puts 2
   end
   end
 
   def printThree
   def printThree
     puts 3
     puts 3
   end
   end
  end
  end
   
defines three methods that print different numbers depending on which method is called.  Without reflection, calls to these methods could not be changed at runtime. However, reflection allows the method calls to depend on string values that do not have to be initialized until runtime as seen in the following code:
  s = Sample.new
  samp = Sample.new #Create an instance of the Sample class
  option="printOne"
  option="printOne"
  s.send(option)
  samp.send(option) #printOne method is called
  option="printThree"
  option="printThree"
  s.send(option)
  samp.send(option) #printThree method is called
 
What is printed from this code depends on the value of "option", which might not have a value until runtime.  In this code, the call:
 
samp.send(option)


will print "1" and then "3".  The call:
is the same, but the "option" value has changed and that is what determines the method that is called.  This same feature exists in languages with reflective packages, but again it is accessed indirectly.  For example, in Java, a similar class:
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 class Sample {
Line 83: Line 84:
  public void printThree(){
  public void printThree(){
  System.out.println("3");
  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.  
handles reflection by accessing the method through a Class object and Method object:
 
Sample samp = new Sample();
Class sampClass = samp.getClass();
String option = "printOne";
Method meth = sampClass.getMethod(option);
meth.invoke(sampClass, null);
option = "printThree";
meth = sampClass.getMethod(option);
meth.invoke(sampClass, null);
The result of this code is the same as the Ruby code, 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.
 
Some of the more dynamic intercessive features that reflection gives a programming language are possible because of the dynamic nature of the language.  For example, in Ruby, a method can be added to an object that ''has already been instanced''.  Given a class "Sample", this code:
 
samp = Sample.new
def samp.anothermethod
  puts "This is a new method"
end
 
will create a method on the instance of Sample.  Reflection is what allows that method to be accessed so that the call:
 
samp.anothermethod
 
will display "This is a new method".  If another Sample object is created, this new object will not have access to the anothermethod method because that method was only added to a specific instance of the Sample class. In Java, methods cannot be created on existing objects (because it is a statically typed language), so this kind of reflection is not possible.
 
=Conclusion=
 
Reflection allows the creation of more versatile and flexible programs through both introspective and intercessive features. These features include the ability for a program to know about itself, and to act on that information. As shown through the use of Ruby as a representative of a reflective language and Java as a representative of a language with a reflective package, these features are implemented differently.


= References =
= References =
[1] [http://www.cs.indiana.edu/~jsobel/rop.html Reflection-Oriented Programming]
[1] [http://www.cs.indiana.edu/~jsobel/rop.html Sobel, J.M. and Daniel P. Friedman 1996 ''Reflection-Oriented Programming'' Indiana University, Bloomington, IN]
 
[2] [http://dspace.mit.edu/handle/1721.1/15961 Smith, Brian Caldwell 1982 ''Procedural Reflection in Programming Languages'' MIT Press, Cambridge, MA]
 
[3] [http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.153.6604 Ducasse, Stéphane and Rmod Inria Lille Nord and Marcus Denker and Adrian Lienhard 2009 ''Evolving a Reflective Language Lessons Learned from Implementing Traits'' European Smalltalk User Group]
 
[4] [http://www.dreamsongs.com/Files/clos-book.pdf D. Bobrow, R. Gabriel, and J. White. CLOS in context—the shape of the design space. In A. Paepcke, editor, ''Object-Oriented Programming: the CLOS perspective'', pages 29–61. MIT Press, 1993.]


[2] [http://dspace.mit.edu/handle/1721.1/15961 Procedural Reflection in Programming Languages]
[5] [http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.32.5011 Anh Nguyen-tuong and Steve J. Chapin and Andrew S. Grimshaw and Charlie Viles. 1998 ''Using Reflection for Flexibility and Extensibility in a Metacomputing Environment'' ORNL Central Research Library, Northrop Grumman Information Technologies Alexandria, VA ]


[3] [http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.153.6604 Evolving a Reflective Language Lessons Learned from Implementing Traits]
= Additional Information =


[4] [http://www.ciaranmchale.com/download/java-reflection-explained-simply-manual-8up.pdf Java Reflection Explained Simply]
[http://www.ciaranmchale.com/download/java-reflection-explained-simply-manual-8up.pdf McHale, Ciaran 2008 ''Java Reflection Explained Simply'']


[5] [http://java.sun.com/developer/technicalArticles/ALT/Reflection/ Using Java Reflection]
[http://java.sun.com/developer/technicalArticles/ALT/Reflection/ Using Java Reflection]


[6] Thomas, Dave with Chad Fowler and Andy Hunt. ''Programming Ruby.'' North Carolina: The Pragmatic Bookshelf, 2005.
[http://ruby-doc.org/docs/ProgrammingRuby/ Thomas, Dave with Chad Fowler and Andy Hunt. ''Programming Ruby.'' North Carolina: The Pragmatic Bookshelf, 2005.]

Latest revision as of 23:32, 20 September 2010

Reflective Language Features vs Reflective Packages

Introduction: Reflection, Reflective languages and Reflective packages

Reflection is an aspect of a computer languages that allows "computations to observe and modify properties of their own behavior."[1] It was first explained in Brian Cantwell Smith's 1982 paper Procedural Reflection in Programming Langauges[2]. A reflective language is a programming language that has been architected to allow reflection. This means the language was constructed to "'reason' effectively and consequentially about its own inference process."[2] Reflection provides languages with versatility [5] and flexibility [3]. Languages that are not reflective can incorporate some of the features of reflection by using reflective packages. For example, Java includes a reflective package called "java.lang.reflect."

Reflective Language Features vs Reflective Packages

The features of a reflective language can be broadly categorized as either introspection or intercession. "Introspection is the ability for a program to observe and therefore reason about its own state. Intercession is the ability for a program to modify its own execution state or alter its own interpretation or meaning."[4]

Introspection is what allows the program to "know" information about itself. This can include an object knowing what kind of object it is, and what methods it has. Intercession is what allows a program to change behavior based on that information. This can include calling methods dynamically, which means that the actual method that is called on an object is decided when the program is running, and not when the program is compiled. Another introspective feature granted by reflection is the ability for, when methods are added to an object when the program is running, these methods can be called.

While the behavior between a program written in a reflective language and a program written with a reflective package will be similar, how the features are implemented will differ. In a reflective language, you can access the information about an object or class from the object or class. In a language with a reflective package, functionality is provided through intermediary objects. For the following examples, Ruby will be used to illustrate how the features of reflection are implemented in a reflective language and Java will be used to illustrate how the features of reflection are implemented in 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
samp = Sample.new

The call:

puts samp.class

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

puts samp.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, the package is not automatically included in the functionality. It must be imported with:

import java.lang.reflect.*;

Also, for any given object A, a separate class object B, is created and B contains the information about A. For example, with the given class:

public class Sample {
//Empty class
}

The class information can be found by invoking:

Sample samp = new Sample(); //Create an instance of Sample
Class sampClass = samp.getClass(); //Create a class object for instance of Sample
System.out.println(sampClass.getName()); //Display class name

and the method list can be found with:

Method[] meth = sampClass.getMethods(); //Return array of method objects for Class object of Sample instance
for (int i = 0; i < meth.length; i++){
   System.out.println(meth[i]); //Display methods
}

As shown in the above examples, both Ruby and Java have the same reflective feature - the ability for an object or class to "know" about itself. However, in Java, a Class object is created to access class information, and method information for the object is stored in method objects that can be accessed via the Class object. In Ruby, that information is accessed directly from the object or class in question.

Intercessive features

Another important feature granted by reflection, is the ability for dynamic implementation of code. This can take many forms, including object creation and method calling at runtime. Again, in an inherently reflective language, these calls are made directly on the object. However, when a language has a reflective package to handle reflective features, the calls are directed through a separate object. For example, in Ruby, this class:

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

defines three methods that print different numbers depending on which method is called. Without reflection, calls to these methods could not be changed at runtime. However, reflection allows the method calls to depend on string values that do not have to be initialized until runtime as seen in the following code:

samp = Sample.new #Create an instance of the Sample class
option="printOne"
samp.send(option) #printOne method is called
option="printThree"
samp.send(option) #printThree method is called

What is printed from this code depends on the value of "option", which might not have a value until runtime. In this code, the call:

samp.send(option)

is the same, but the "option" value has changed and that is what determines the method that is called. This same feature exists in languages with reflective packages, but again it is accessed indirectly. For example, in Java, a similar class:

public class Sample {
	
	public void printOne(){
		System.out.println("1");
	}
	
	public void printTwo(){
		System.out.println("2");
	}
	
	public void printThree(){
		System.out.println("3");
	}
}

handles reflection by accessing the method through a Class object and Method object:

Sample samp = new Sample();
Class sampClass = samp.getClass();
String option = "printOne";
Method meth = sampClass.getMethod(option);
meth.invoke(sampClass, null);
option = "printThree";
meth = sampClass.getMethod(option);
meth.invoke(sampClass, null);

The result of this code is the same as the Ruby code, 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.

Some of the more dynamic intercessive features that reflection gives a programming language are possible because of the dynamic nature of the language. For example, in Ruby, a method can be added to an object that has already been instanced. Given a class "Sample", this code:

samp = Sample.new
def samp.anothermethod
  puts "This is a new method"
end

will create a method on the instance of Sample. Reflection is what allows that method to be accessed so that the call:

samp.anothermethod

will display "This is a new method". If another Sample object is created, this new object will not have access to the anothermethod method because that method was only added to a specific instance of the Sample class. In Java, methods cannot be created on existing objects (because it is a statically typed language), so this kind of reflection is not possible.

Conclusion

Reflection allows the creation of more versatile and flexible programs through both introspective and intercessive features. These features include the ability for a program to know about itself, and to act on that information. As shown through the use of Ruby as a representative of a reflective language and Java as a representative of a language with a reflective package, these features are implemented differently.

References

[1] Sobel, J.M. and Daniel P. Friedman 1996 Reflection-Oriented Programming Indiana University, Bloomington, IN

[2] Smith, Brian Caldwell 1982 Procedural Reflection in Programming Languages MIT Press, Cambridge, MA

[3] Ducasse, Stéphane and Rmod Inria Lille Nord and Marcus Denker and Adrian Lienhard 2009 Evolving a Reflective Language Lessons Learned from Implementing Traits European Smalltalk User Group

[4] D. Bobrow, R. Gabriel, and J. White. CLOS in context—the shape of the design space. In A. Paepcke, editor, Object-Oriented Programming: the CLOS perspective, pages 29–61. MIT Press, 1993.

[5] Anh Nguyen-tuong and Steve J. Chapin and Andrew S. Grimshaw and Charlie Viles. 1998 Using Reflection for Flexibility and Extensibility in a Metacomputing Environment ORNL Central Research Library, Northrop Grumman Information Technologies Alexandria, VA

Additional Information

McHale, Ciaran 2008 Java Reflection Explained Simply

Using Java Reflection

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