Domain-Specific Languages
The goal of metaprogramming in Ruby is often the creation of domain-specific languages, or DSLs. A DSL is just an extension of Ruby’s syntax (with methods that look like keywords) or API that allows you to solve a problem or represent data more naturally than you could otherwise. For our examples, we’ll take the problem domain to be the output of XML formatted data, and we’ll define two DSLs—one very simple and one more clever—to tackle this problem.[*]
Simple XML Output with method_missing
We begin with a simple class named XML
for generating XML output. Here’s an
example of how the XML
can be
used:
pagetitle = "Test Page for XML.generate" XML.generate(STDOUT) do html do head do title { pagetitle } comment "This is a test" end body do h1(:style => "font-family:sans-serif") { pagetitle } ul :type=>"square" do li { Time.now } li { RUBY_VERSION } end end end end
This code doesn’t look like XML, and it only sort of looks like Ruby. Here’s the output it generates (with some line breaks added for legibility):
<html><head> <title>Test Page for XML.generate</title> <!-- This is a test --> </head><body> <h1 style='font-family:sans-serif'>Test Page for XML.generate</h1> <ul type='square'> <li>2007-08-19 16:19:58 -0700</li> <li>1.9.0</li> </ul></body></html>
To implement this class and the XML generation syntax it supports, we rely on:
Ruby’s block structure
Ruby’s parentheses-optional method invocations
Ruby’s syntax for passing hash literals to methods without curly braces ...
Get The Ruby Programming Language now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.