For better and for worse, few languages are as closely associated with the practice of metaprogramming as Ruby. Ruby’s metaprogramming capabilities, especially as leveraged in the Ruby on Rails web app framework, are one of the language’s greatest attractions for many programmers—and also one of its greatest sources of criticism.
Metaprogramming, at core, is about using code to read, modify, and generate new code… which is then executed, in turn. This can result in some impressive power for expressive domain-specific “little languages”—like the Rake dialect for project automation scripts. It can also result in unmaintainable code full of “spooky action at a distance”.
When learning about Ruby’s metaprogramming tools, it’s important to understand the philosophy they stem from. While Ruby takes ideas from many programming languages, including Perl, Smalltalk, Eiffel, C, and Python, there’s one language that Matz has always said is its greatest inspiration: the seminal dynamic functional programming language Lisp.
To grok Ruby nature, then, we need to grok Lisp nature. And at the core of Lisp philosophy is the idea of building the language up to the level of the domain, using the power of metaprogramming. In Lisp, you don’t write Lisp code about inventory management. You construct an inventory management language, using Lisp as the medium.
That’s the philosophy we see at work in the Ruby on Rails framework: with its copious additions to the Ruby core classes; with its internal Domain-Specific Languages (DSLs) such as the little language for request routing: Rails is not just a framework, but a Ruby dialect for enterprise web applications.
Metaprogramming is what enables a lot of this language-building. So if we want to program “with the grain” of Ruby, it’s important to understand how to leverage metaprogramming facilities. How to create the language we need for the task at hand… and how to avoid the gotchas.
This garden path collects many Graceful.Dev topics about metaprogramming from over the years, into a suggested course of study. You’ll learn how to use Ruby introspection methods to examine and change a program’s live object model. How to generate new methods on the fly, and how to leverage Ruby’s modules and refinements for targeted, constrained enhancements to your coding experience. And most importantly, you’ll learn techniques for mitigating some of the worst pitfalls of metaprogramming.
This course is a Graceful.Dev Garden Path, which means it is a guided pathway through a collection of (mostly) self-contained topics. Its status is: growing, meaning that there is a significant amount of material here already, and more is expected in the future.
Prerequisites: Metaprogramming is a fairly advanced topic, so you may want to complete the Ruby Fluency Garden Tour before starting on this path.