> The enabling feature of Lisp which makes its macros possible is
> homoiconicity

It makes things easier and more elegant. Basically, you could also use
a parser of sorts (ruby 1.9 comes with ripper), make your
transformations, and then generate a string or sexp that is then
evaluated. One could use e.g. the polyglot gem to let source files be
read by such a macro pre-processor. In comparison to the lisp approach
that would be terribly complicated and fragile though.

I know of 2-3 efforts to implement macros in ruby. Maybe the OP would
be interested in those approaches.

It could also be interesting to compare lisp macros with template
haskell, camlp5 and similar approaches that, if I'm not mistaken, seem
to solve similar problems.