Arti has to dig into all sorts of odd corners in Rails.
Here are some of the low-level methods it employs to harvest information:
Although Rails favors convention over configuration,
it actually uses both.
Some configuration files (e.g., fixtures) are written in YAML
possibly with Embedded Ruby
YAML is easy to parse;
Embedded Ruby inclusions, however, may be context-sensitive.
If so, it may be easier to use introspection (see below).
Other configuration files may be written in Ruby (and variations thereon).
Again, loading the files and introspecting the information
is often easier than parsing and analyzing the Ruby code.
Convention (eg, file names)
Many of Rails' conventions have to do with naming.
In particular, application files and directories are named
according to a complex set of rules.
By examining these names,
we can determine relationships and roles
and even make guesses about purposes.
Many Rails classes and models support introspection;
all we have to do is ask our questions in the right way.
Basically, this means loading up any necessary files,
then running exploratory methods.
It is possible to write Ruby scripts that bring in libraries,
but this is tricky and somewhat inconvenient.
Also, because it relies on "internal" implementation details,
it could be brittle in the face of changing Rails versions, etc.
So, Arti uses a combination of Capistrano and script/console
to load and access the relevant methods.
This also has the benefit of allowing introspection
to be done on the target machine.
Things that cannot be determined from static analysis,
or even introspection, can often be found by run-time tracing.
There are several ways to approach this, including:
- code modification (eg, to log events)
- metaprogramming (eg, Spect)
Each of these has benefits and drawbacks.
If code modification is done on the production code base,
performance or even functionality could be affected.
Rubinius, although very promising, is not yet able to run Rails.
DTrace is only available on certain operating systems
(eg, Solaris 10, Mac OS X 10.5).
Metaprogramming, in the context of script/console
is a very general, powerful, and safe approach.
It can be done on any OS platform,
using any Ruby interpreter,
and leaves the code base unchanged.
As discussed in Parse Trees
there are tools to parse Ruby code and generate S-expressions
These Sexps can then be examined to find method calls and definitions
(including placement-sensitive oddballs
such as private
, and public
and variable use.
This wiki page is maintained by Rich Morin
an independent consultant specializing in software design, development, and documentation.
Please feel free to email
comments, inquiries, suggestions, etc!