tehAnswer
tehAnswer

Reputation: 1018

instance_eval doesn't work as expected

I'm trying to build a tinny DSL using the approach that Russ Olsen exposes in his book, Eloquent Ruby. However it is not working for me. Let's consider the following code:

class SayHello
  def initialize
    @message = "Hello."
    instance_eval(yield) if yield
  end

  def say_it
    puts @message
  end
end

SayHello.new { say_it }

The error I get is:

say_hello.rb:12:in `block in <main>': undefined local variable or method `say_it' for main:Object (NameError)
    from say_hello.rb:4:in `initialize'
    from say_hello.rb:12:in `new'
    from say_hello.rb:12:in `<main>'

But... when you use instance_eval method, the value of self shouldn't be assigned to the object that calls the method?

Thanks in advance!

Upvotes: 0

Views: 104

Answers (1)

David Grayson
David Grayson

Reputation: 87531

When the block runs, you want self to be equal to your SayHello instance instead of the main object.

I Googled for "ruby change self for a block" and found a good answer which makes me think you should change your code to:

class SayHello
  def initialize(&p)
    @message = "Hello."
    instance_eval(&p) if block_given?
  end

  def say_it
    puts @message
  end
end

SayHello.new { say_it }

Upvotes: 5

Related Questions