Rajkaran Mishra
Rajkaran Mishra

Reputation: 4932

IRB - NameError: undefined local variable or method for main:Object

I was trying to understand how the ERB works in the IRB.

>> require 'erb'
=> true

>> weekday = Time.now.strftime('%A')
=> "Wednesday"

>> simple_template = "Today is <%= weekday %>."
=> "Today is <%= weekday %>."

>> renderer = ERB.new(simple_template)
=> #<ERB:0x287f568 @safe_level=nil, @src="#coding:IBM437\n_erbout = ''; _erbout.concat \"Today is \"; _erbout.concat(( weekday ).to_s); _erbout.concat \".\"; _erbout.force_encoding(__ENCODING__)", @encoding=#<Encoding:IBM437>, @filename=nil, @lineno=0>

>> puts output = renderer.result()
NameError: undefined local variable or method `weekday' for main:Object
        from (erb):1:in `<main>'
        from C:/Ruby22/lib/ruby/2.2.0/erb.rb:863:in `eval'
        from C:/Ruby22/lib/ruby/2.2.0/erb.rb:863:in `result'
        from (irb):5
        from C:/Ruby22/bin/irb:11:in `<main>'

I was not able to figure out the reason of the above error cause I can see the variable is returning it's value.

>> weekday
=> "Wednesday"

Now when I took the code and put it in a file, it ran fine. Please explain.

Upvotes: 1

Views: 2421

Answers (4)

marcusshep
marcusshep

Reputation: 1964

1.8.7-p376 :004 > require 'erb'
=> true 

1.8.7-p376 :005 > @weekday = Time.now.strftime('%A')
=> "Wednesday" 

1.8.7-p376 :006 > simple_template = "Today is <%= @weekday %>."
=> "Today is <%= @weekday %>." 

1.8.7-p376 :007 > renderer = ERB.new(simple_template)
=> #<ERB:0x10e46a8e8 @src="_erbout = ''; _erbout.concat \"Today is \"; _erbout.concat(( @weekday ).to_s); _erbout.concat \".\"; _erbout", @filename=nil, @safe_level=nil> 

1.8.7-p376 :009 > puts output = renderer.result()
Today is Wednesday.
=> nil 

You want to make weekday an instance variable, by perpending an @. Like so, @weekday = Time.now.strftime('%A')

Upvotes: 0

Aleksei Matiushkin
Aleksei Matiushkin

Reputation: 120990

Make it an instance variable: ERB looks up instance variables:

@weekday = Time.now.strftime('%A')
ERB.new("Today is <%= @weekday %>.").result
#⇒ "Today is Wednesday."

Upvotes: 0

tadman
tadman

Reputation: 211540

It looks like you're referencing this blog post about ERB which isn't correct. The ERB rendering method needs to receive a binding which defines where to get local variables from:

renderer.result(binding)

It's worth noting that article uses a lot of practices considered non-standard in Ruby, like including empty argument lists in method definitions and calls.

Upvotes: -1

SteveTurczyn
SteveTurczyn

Reputation: 36860

The line

puts output = renderer.result()

doesn't have access to your context so it can't see the variable weekday You need to pass the current context (the "binding")

Try instead

puts output = renderer.result(binding)

Upvotes: 2

Related Questions