The Ruby Object Model and Metaprogramming

by: Dave Thomas

Published 2008-12-26
Internal code v-dtrubyom
Print status In Print
Pages
User level
Keywords ruby screencast, ruby screencasts, ruby metaprogramming, ruby video tutorial, ruby training
Related titles
ISBN
Other ISBN
BISACs COM060080 COMPUTERS / Web / General
COM060080 COMPUTERS / Web / General
COM060080 COMPUTERS / Web / General

Highlight

Metaprogramming lets you program more expressively. This makes your code easier to write and easier to maintain and extend. Learn both the <em>hows</em> and <em>whys</em> of metaprogramming Ruby from Dave Thomas, one of the most experienced Ruby programmers in the western world.

Description

Initially, metaprogramming Ruby can seem really difficult. There are all these unfamiliar terms: singletons, self, metaclasses, and so on. And things never seem to work quite right the first time—Hmm… maybe it’ll work if I change class_eval to instance_eval

Well, the good news is that it really isn’t that complex. You just have to understand the underlying model, and everything falls into place. Dave Thomas has been digging into that model for the last ten years, and has a fresh (and simple) way of looking at it. Now you’ll be able to see <em>why</em> metaprogramming works, and <em>how</em> to do it for yourself.

It doesn’t matter if you’ve been programming Ruby for a month or for five years. We bet that you’ll learn plenty new in each of these episodes, as Dave digs into both the <em>how</em> and the <em>why</em> of the Ruby object model and metaprogramming.

<ul class="movie-list"> <li> <strong>Dave talks about the series in this free preview.</strong>

<br/> (3 mins, <a href="https://s3.amazonaws.com/screencasts.pragprog.com/v-dtrubyom-intro.m4v" target="_blank">QuickTime</a> | <a href="https://s3.amazonaws.com/screencasts.pragprog.com/v-dtrubyom-intro.ogg" target="_blank">Ogg</a>)

</li> <li> <strong>Watch some free extracts from Episodes 2 and 3.</strong>

<br/> (9 mins, <a href="https://s3.amazonaws.com/screencasts.pragprog.com/v-dtrubyom-sample.m4v" target="_blank">QuickTime</a> | <a href="https://s3.amazonaws.com/screencasts.pragprog.com/v-dtrubyom-sample.ogg" target="_blank">Ogg</a>)

</li> </ul>

Contents and Extracts

<ul> <li>Episode 1: Objects and Classes (29 minutes)
<p>
Just what is a Ruby object, and how can Ruby move you away from <em>class-oriented development</em> and back to <em>object-oriented development</em>? Learn about: </p> <ul style="padding-bottom: .5em;"> <li>the internals of objects, </li> <li>how classes really aren’t anything special, </li> <li>what self does, and the two ways it can get changed </li> <li>the method call mantra: “one to the right, then up,” </li> <li>singleton methods and ghost classes, </li> <li>why class methods don’t exist, </li> <li>how classes get their names, </li> <li>how the concept of the <em>current class</em> interacts with def </li> </ul> </li> <li>Episode 2: Sharing Behavior (39 minutes)
<p>
One of the primary goals of good design is to put the right behavior in the right place without duplication. We’ll see three ways Ruby excels at this: </p> <ul> <li>Using <em>prototype-based programming</em>, where you can create hierarchies of objects with controlled sharing of both state and behavior, and without a class definition in sight. </li> <li>using <em>inheritance</em> (but you can only watch this section after you’ve watched the included Public Safety announcement on why inheritance is normally a bad idea). We’ll also look at what happens when you do class << <em>object</em> (and why it’s nothing whatsoever to do with inheritance). </li> <li>using <em>modules and mixins</em>, the sweet spot of Ruby programming. How to using include and extend, and how to create modules that mix in both instance and class methods. </li> </ul> <p> Episodes 1 and 2 are the foundation for the rest of the screencast. </p> </li> <li>Episode 3: Dynamic Code (31 minutes)
<p>
Metaprogramming is sometimes defined as “writing code that writes code.” Here we’ll see just how to do that in Ruby. </p> <ul style="padding-bottom: .5em;"> <li>Blocks and the two kinds of block-objects </li> <li>How bindings capture execution context </li> <li>How blocks can act as closures, and why that’s vital to metaprogramming </li> <li>Writing methods that define other methods using nested defs </li> <li>Using define_method </li> <li>Writing your own accessor methods </li> </ul> </li> <li>Episode 4: instance_eval and class_eval (29 minutes)
<p>
Two of the workhorse methods of metaprogramming are instance_eval and class_eval. They allow you to execute chunks of code dynamically. Here we’ll see how to use them. </p> <ul style="padding-bottom: .5em;"> <li>How instance_eval and class_eval differ </li> <li>When to use one versus the other </li> <li>Breaking down barriers </li> <li>Creating methods on the fly, but without using closures </li> <li>Defining stuff in classes given a class object </li> <li>Writing DSLs in a block structure </li> </ul> </li> <li>Episode 5: Nine Examples of Metaprogramming (36 minutes)
<p>
Here’s where all the theory and practice comes together! We’ll take a simple problem and find nine different ways of attacking it using metaprogramming techniques. </p> <ul style="padding-bottom: .5em;"> <li>Adding behavior directly inside the class </li> <li>Using subclassing to add behavior </li> <li>Subclassing with a generator using Class.new </li> <li>Using a ghost class </li> <li>Ghost class with a generator using class_eval </li> <li>Rewrite the method with alias_method </li> <li>Rewrite using a module </li> <li>Rewrite using bind </li> <li>Writing a DSL in a block </li> </ul> </li> <li>Episode 6: Some Hook Methods (35 minutes)
<p>
Ruby hook methods are a way for your application to hook itself into the execution of the Ruby interpreter. Using hook methods is crucial for some kinds of metaprogramming, and they can make your code more flexible. In this episode, we’ll see how to use two powerful hook methods: inherited and const_missing. </p> <ul style="padding-bottom: .5em;"> <li>Overriding hook methods to intercept and deal with certain Ruby interpreter events during the lifetime of your application </li> <li>Decoupling code using inherited to keep track of subclasses </li> <li>Implementing enumerated types with const_missing </li> <li>Using const_missing to autoload classes based on the names of files </li> <li>Applying const_missing in both global and localized situations </li> <li>How to chain an overridden hook method to its original hook method </li> <li>Using const_set to define constants </li> <li>Two practical uses for hook methods </li> </ul> </li> <li>Episode 7: More Hook Methods (53 minutes)
<p>
We’ll pick up where we left off in the last episode by looking at two more Ruby hook methods: included and method_added. But we’ll also take it a step further. We’ll use these hook methods to develop a metaprogramming library that traces the execution of a Ruby program. Along the way we’ll see all the various subtle (and important!) things you need to think about when you’re trying to write a general-purpose metaprogramming library. </p> <ul> <li>Using included to intercept when a module is included in a class, and use it to set up another hook method in a different context </li> <li>Using method_added to track when a new method is defined on a class, and trace the method’s execution </li> <li>Refactoring the tracing to support blocks </li> <li>Using method objects to bypass naming issues </li> <li>Adding tracing to methods that have already been added </li> <li>Suppressing tracing for certain methods </li> <li>Using Thread.current to define thread-local variables </li> <li>Differences between Ruby 1.8 and 1.9 </li> <li>Practical examples (and corner cases) of metaprogramming </li> </ul> </li> </ul> <h3>Audience</h3>

These screencasts assume you have some basic Ruby knowledge.