Sunday, February 19, 2006
The Way of Meta - Part II
The Way of Meta
Exploring Ruby Metaprogramming Capabilities
Getting our Feet Wet
Tired of all this talk? Then it is time to dip our feet in the deep waters of rubesque metaprogramming. We are going to start our journey exploring the metaprogramming features that are illustrated in the pragmatic programmers' PickAxe book, while at the same time we will go through the less known libraries present in the ruby distribution. At the same time we will ask for some help to the wonderfully brief and clear 'Seeing Metaclasses Clearly' by Why the Lucky Stiff.
Out-of-the-Box Metaprogramming Mechanisms
Ruby provides several straight out of the box metaprogramming mechanisms with its core standard libraries. Although using these mechanisms can take you very quickly to unmanageable levels of complexity it is worth looking at them to have a feeling of what is possible. Later on we will encapsulate these mechanisms within our own metaprogramming protocol.
In many languages, the mechanism that allows your source code to refer to a library or to another piece of code is handled by the language in an opaque way. Not so in Ruby.
When using Ruby you are in charge of the code loading.
The 'load' command loads some ruby code, right where you are calling it.
The 'require' command adds a little check that prevents the loading of the same file twice from different points in the code.
Load and require are not special commands for the compiler, they are dynamically executed and can be embedded within blocks, control statements, etc. The name of the file that they load can also be constructed dynamically.
The load construct in particular allows you to reload code definitions any number of times if they get changed inside the file. It's now easy to see how your code could generate code files, maybe using a templating mechanism, and then load them back in the runtime.
There are two environment variables that can turn out to be helpful when dealing with dynamic source code loading.
$LOAD_PATH is an array of directories that are searched for source code by 'load' and 'require'.
$LOADED_FEATURES is an array containing the filenames of the files that have already been loaded.
Links to this post: