Bindings in Ruby

Do you see the binding?

What is a binding?

When using Embedded Ruby, Ruby programmers become aware of the importance of binding. In order to use ERB’s templating tool to generate HTML (or other language) documents using Ruby, a binding is required to take a snapshot of the current code and pass it to be executed. Let’s use this code snippet where we assume there is a Movie class with an array of information-laden movie objects made accessible by calling Movie.all:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
 def generate_movie_webpages
  html = File.read("lib/templates/movie.html.erb")
   template = ERB.new(html)
#From our movie.html.erb file we generate a new ERB template 

    @movies = Movie.all
    @movies.each do |movie|
      @movie = movie
      result = template.result(binding)
      File.write("_site/movies/#{movie.name}", result)
#For each movie object in our list, we generate a page based
#on the template and store it at a unique address.
    end
  end

Notice where binding came in there? It was in the loop, taking a snapshot of the code as it stood and passing it to the ERB execution method, template#result(). We’ve seen some of what it can do. But why do we have to use this, and where does it get its power from?

Where does binding come from?

To start our inquiry into its roots, here are some short definitions of binding:

“It squishes the universe into one singular object that I can then pass around.” - Avi Flombaum, Rubyista Extraordinaire

“Logic of a quantifier to be applied to a given variable so that the variable falls within its scope. For example, in an expression of the form: For every x, if x is a dog, x is an animal, the universal quantifier is binding the variable x.” - Oxford English Dictionary

This is a good start. It seems that binding grabs the universe of code as it is at that line of processing, packs it in a pill, and allows your template to ingest it for execution. But where exactly does binding come from? What kind of method or object is it? To help us out, I’ve reached into the Ruby Documentation.

“Objects of class Binding encapsulate the execution context at some particular place in the code and retain this context for future use. The variables, methods, value of self, and possibly an iterator block that can be accessed in this context are all retained. Binding objects can be created using Kernel#binding.” - Ruby-doc.org

Those first and last lines answer our question: Binding is a class that produces instances, and it belongs to Kernel. Kernel! The all important nugget at the center of our Ruby popcorn. Binding even has several public instance methods that allow you to examine what it contains. Binding.local_variables and Binding.local_variable_defined? are useful.

Bringing it all together:

Binding’s relation to Kernel explains its ability to pack variables, methods, the value of self, and possibly an iterator block into a single word. Binding gives the Pry gem its power, and it enables ERB templates to make the most of your Ruby code when generating code in other langauages.

Binding is an open lens into a universe of code. Binding is the world seen through a water droplet. Binding is encapsulation.

Do you see the binding now?

Painting: Jan Van Eyck’s Portrait of Giovanni Arnolfini and his Bride, Flemish, 1434

Copyright © 2015 David Perel