Reflection, ObjectSpace, and Distributed Ruby
One of the many advantages of dynamic languages such as Ruby is the
ability to
introspect---to examine aspects of the program from
within the program itself. Java, for one, calls this
feature
reflection.
The word ``reflection''
conjures up an image of looking at oneself in the mirror---perhaps
investigating the relentless spread of that bald spot on the top of
one's head. That's a pretty apt analogy: we use reflection to examine
parts of our programs that aren't normally visible from where we stand.
In this deeply introspective mood, while we are contemplating our
navels and burning incense (being careful not to swap the two tasks),
what can we learn about our program? We might discover:
- what objects it contains,
- the current class hierarchy,
- the contents and behaviors of objects, and
- information on methods.
Armed with this information, we can look at particular objects
and decide which of their methods to call at runtime---even if the class of
the object didn't exist when we first wrote the code. We can also
start doing clever things, perhaps modifying the program as it's
running.
Sound scary? It needn't be. In fact, these reflection capabilities let
us do some very useful things. Later in this chapter we'll look at
distributed Ruby and marshaling, two reflection-based technologies
that let us send objects around the world and through time.