# Erb and scope

**URL:** <https://www.ruby-forum.com/t/erb-and-scope/97141>\
**Category:** Ruby\
**Created:** [December 11, 2005, 12:11pm UTC](https://www.ruby-forum.com/t/erb-and-scope/97141 "2005-12-11T12:11:51Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![wybo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/cc9497/32.png) [@wybo](https://www.ruby-forum.com/u/wybo)\
**Post date:** [December 11, 2005, 12:11pm UTC](https://www.ruby-forum.com/t/erb-and-scope/97141/1 "2005-12-11T12:11:51Z")

</div>

Why does this not work (bar-\>undefined) and what’s a better way to do  
it?:

require ‘erb’

FOO = ‘Hello \<%= bar %\>’  
class Foo  
def doit  
bar = ‘World!’  
puts ERB.new(FOO).result  
end  
end

Foo.new.doit

I need to use $bar instead of bar to get it going…

---

<div class="post-metadata">

**Author:** ![wybo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/cc9497/32.png) [@wybo](https://www.ruby-forum.com/u/wybo)\
**Post date:** [December 11, 2005, 12:28pm UTC](https://www.ruby-forum.com/t/erb-and-scope/97141/2 "2005-12-11T12:28:30Z")

</div>

On Sunday 11 December 2005 12:08, Wybo D. wrote:

> Why does this not work (bar-\>undefined) and what’s a better way to  
> do it?:
> 
> require ‘erb’
> 
> FOO = ‘Hello \<%= bar %\>’  
> class Foo  
> def doit  
> bar = ‘World!’  
> puts ERB.new(FOO).result

replace above line with:

```
  puts ERB.new(FOO).result(binding)

```

> end  
> end
> 
> Foo.new.doit

Regards,  
Stefan

---

<div class="post-metadata">

**Author:** ![wybo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/cc9497/32.png) [@wybo](https://www.ruby-forum.com/u/wybo)\
**Post date:** [December 11, 2005, 1:33pm UTC](https://www.ruby-forum.com/t/erb-and-scope/97141/3 "2005-12-11T13:33:50Z")

</div>

Wybo D.:  
[erb]

> I need to use $bar instead of bar to get it going…

@bar will do it, too, and that’s maybe the best way to do it.

Malte

---

<div class="post-metadata">

**Author:** ![wybo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/cc9497/32.png) [@wybo](https://www.ruby-forum.com/u/wybo)\
**Post date:** [December 11, 2005, 1:37pm UTC](https://www.ruby-forum.com/t/erb-and-scope/97141/4 "2005-12-11T13:37:54Z")

</div>

On Sun, 11 Dec 2005, Stefan L. wrote:

> > ```
> > puts ERB.new(FOO).result
> > 
> > ```
> 
> replace above line with:
> 
> ```
> puts ERB.new(FOO).result(binding)
> 
> ```

That helps (although I don’t understand it yet, but I’ll find out),  
thanks!

---

<div class="post-metadata">

**Author:** ![wybo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/cc9497/32.png) [@wybo](https://www.ruby-forum.com/u/wybo)\
**Post date:** [December 11, 2005, 3:17pm UTC](https://www.ruby-forum.com/t/erb-and-scope/97141/5 "2005-12-11T15:17:33Z")

</div>

On Dec 11, 2005, at 13:32, Malte M. wrote:

> Wybo D.:  
> [erb]
> 
> > I need to use $bar instead of bar to get it going…
> 
> @bar will do it, too, and that’s maybe the best way to do it.

[Other poster suggests passing binding.]

I have always wondered why erb does not provide in addition the  
possibility to pass a regular hash. In general I don’t want to design  
my objects or scopes around a template. Is there a rationale behind  
that?

– fxn

---

<div class="post-metadata">

**Author:** ![wybo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/cc9497/32.png) [@wybo](https://www.ruby-forum.com/u/wybo)\
**Post date:** [December 11, 2005, 5:08pm UTC](https://www.ruby-forum.com/t/erb-and-scope/97141/6 "2005-12-11T17:08:38Z")

</div>

On Dec 11, 2005, at 6:36 AM, Wybo D. wrote:

> On Sun, 11 Dec 2005, Stefan L. wrote:
> 
> > > ```
> > > puts ERB.new(FOO).result
> > > 
> > > ```
> > 
> > replace above line with:
> > 
> > ```
> > puts ERB.new(FOO).result(binding)
> > 
> > ```
> 
> That helps (although I don’t understand it yet, but I’ll find out),  
> thanks!

ERb templates are resolved in the scope of some “binding”. They have  
access to the variables in that binding. There is a private method  
on Object (universally available) called binding(), which just  
returns a Binding object for the current scope. By handing that to  
ERb, you can control what it can access.

Hope that helps.

James Edward G. II

---

<div class="post-metadata">

**Author:** ![wybo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/cc9497/32.png) [@wybo](https://www.ruby-forum.com/u/wybo)\
**Post date:** [December 11, 2005, 5:27pm UTC](https://www.ruby-forum.com/t/erb-and-scope/97141/7 "2005-12-11T17:27:44Z")

</div>

On Dec 11, 2005, at 7:49 AM, Xavier N. wrote:

> I have always wondered why erb does not provide in addition the  
> possibility to pass a regular hash. In general I don’t want to  
> design my objects or scopes around a template. Is there a rationale  
> behind that?

I imagine the reason is because ERb uses eval() under the hood and  
the tool eval() gives us is Binding. We should be able to use that  
to do pretty much what you want though:

> > require “erb”  
> > =\> true
> 
> > class Template  
> > def initialize( variables )  
> > variables.each { |name, value| instance\_variable\_set("@#  
> > {name}", value) }
> 
> > end

?\> def resolve( template )

> > ```
> > ERB.new(template).result(binding)
> > 
> > ```
> > 
> > end  
> > end  
> > =\> nil
> 
> > t = Template.new(:one\_var =\> “One”, :two\_var =\> “Two”)  
> > =\> #\<Template:0x3253dc @two\_var=“Two”, @one\_var=“One”\>
> 
> > t.resolve(“This is ERb using \<%= @one\_var %\> and \<%= @two\_var %\>.”)  
> > =\> “This is ERb using One and Two.”

James Edward G. II
