how to understand Ruby/Rails code? (noting various mixins/includes) Is there a tool to assist here?

Hi all,

Every rails app / gem / plugin I download the code for I seem to spend
a good deal of time trying to make sense of the code due to the way
Rails / Ruby is very dynamic. There are various code files that are
really just ready to be "mixed in" to other files (e.g. with the class
methods & instance methods ready to go). Just trying to make sense of
the final object structure and where methods resides seems to be a
challenge. The latest one I've been looking at are things like
AuthLogic and Paperclip.

QUESTION 1: Is there a tool that could assist here? I'm thinking of
one that could do things like walk the code base and then:

* Give a hierarchy structure where various files methods are loaded
into which objects

* Given sample walk throughs of methods hit in which files for a given
controller/action (e.g. like how the java IDEs can auto-sequence
diagrams)

* Perhaps something that analyses code and then added comments to the
various files highlighting where that files methods will reside in
terms of the final object structure.

QUESTION 2: Should of nothing be available for the above, and tips/
tricks people have re understanding a new plugin/gem codebase?

thanks

I've had good luck figuring out the flow of things using Kernel.caller
in logging statements added to Rails/plugin/gem code.

FWIW,

QUESTION 1: Is there a tool that could assist here? I'm thinking of
one that could do things like walk the code base and then:

* Give a hierarchy structure where various files methods are loaded
into which objects

* Given sample walk throughs of methods hit in which files for a given
controller/action (e.g. like how the java IDEs can auto-sequence
diagrams)

* Perhaps something that analyses code and then added comments to the
various files highlighting where that files methods will reside in
terms of the final object structure.

A lot of this is doubtful - there are plenty of ways to fiddle with
modules in Ruby that won't be detectable until runtime; the ultimate
example would be a line like:

self.send(:include, @some_ivar.constantize)

which, while not recommended, is certainly possible.

QUESTION 2: Should of nothing be available for the above, and tips/
tricks people have re understanding a new plugin/gem codebase?

This came up a while back at the local Ruby Brigade; here's some links
that might be useful.

http://gist.github.com/76951
Short demo of some basic "where is this defined" that's built-in.

http://github.com/spicycode/inspector
A more powerful library for tracing things down in code.

--Matt Jones

thanks Matt

Do you happen to know how to use these? Gist for example, should I be
able to run this from ./script/console? Like would you have to be in
the right scope/context to ensure it works I guess. For example for
AuthLogic there is an "acts_as_authentic" method, but if you're not
sure where this gets mixed in to how would Gist help out here?

Cheers
Greg

First off, note that the linked Gist is just a way to show a nice,
color-highlighted snippet of source code - the *code* is what's
relevant there, not the tool.

In any case, the two methods I linked previously are more of a last
resort, when you're looking for who's defining (for instance) a method
with a dynamic name, or stomping on your AR accessor methods.

The first tool you should be reaching for is a good multi-file search
tool; I happen to use "Grep in Project" for Textmate, but most
reasonable IDEs will have something equivalent. In the case of
acts_as_authentic, start by tracking down the definition of the method
(it's in lib/authlogic/acts_as_authentic/base.rb) and then look for
who's pulling in the module it's defined in (in this case, the
statements at the very end of the same file).

The other very handy tool in this kind of source chasing is the 'gem
open' command - http://github.com/adamsanderson/open_gem . It makes
poking around in gem source far easier.

Hope this helps!

--Matt Jones

thanks - then open_gem lead is handy

If I had more time I'd consider trying to write a tool like the
"annotate_model" plug in that parses through the code (e.g. authlogic
in this case) and annotates above the methods where they will be mixed
into (e.g. "will be an instance method for all objects that inherit
from ActiveRecord:Base)

cheers