Bindings
Now, what’s this binding
thing used in our code?
html = ERB.new(template).result(binding)
Obviously we do not define a local variable, so it needs to be a method. Let’s google that: Ruby binding
The first result goes to the Ruby documentation, saying (some rather cryptic stuff stripped for our purpose):
“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, […] that can be accessed in this context are all retained. Binding objects can be created using Kernel#binding […]. These binding objects can be passed [around].”
Hmmmmm, let’s re-read that, and think about it.
First of all, Kernel
is something we have never mentioned so far. It is a
Ruby module
that is included into the class Object
. That means that, whenever you create
any object, this module, and thus all of its methods, will be included. Since
Ruby’s top level scope is also an object, binding
is defined there too. This
is also, by the way, the secret reason why methods like p
, puts
, and so
on are available everywhere: they’re defined in Kernel
.
Now, what’s this execution context the documentation is talking about?
Remember when we talked about scopes in the context of methods? That’s the same as the Ruby documentation means by “execution context”. It is that empty room or space that Ruby enters whenever it starts your program, or enters a method. If you define a local variable, then this variable will be visible within this scope, or room, or “execution context”, but not outside of it.
Now the binding
keeps exactly this knowledge: what variables are defined,
and what objects they are referring to. And the binding
itself is an object
that can be passed around.
If you find this confusing don’t worry:
All of this is knowledge that many Ruby programmers don’t need, or at least very rarely use themselves. Advanced programming techniques aside (like “meta programming”) rendering ERB templates is the one single situation where you’d ever need it. And, on top of this, as a Sinatra or Rails developer you also never need it because both Sinatra and Rails ship tools that hide this weird stuff from you.
For now, the one thing you can remember is that by calling binding
and
passing the result to the ERB instance, you simply pass access to the two
local variables name
and messages
, so they can be used inside your ERB
template.
Does this make sense?
Then maybe it’s a good time for an exercise on ERB.