Question

If I have a class:

class KlassWithSecret
  def initialize
    @secret = 99
  end
end

and run:

puts KlassWithSecret.new.instance_eval { @secret }

it prints 99, but if I run:

puts KlassWithSecret.new.instance_eval do
  @secret
end

It returns an error: `instance_eval': wrong number of arguments (0 for 1..3) (ArgumentError)

Why can't I use do/end blocks with instance_eval?

P.S. I am using Ruby 2.1.0.

Was it helpful?

Solution

It's because when you pass block with curly braces, it is passed to instance_eval method. But if you pass it with do-end, it's passed to puts method, so instance_eval doesn't get block and raises an error.

OTHER TIPS

Enclose expression supplied to puts in parenthesis because lower precedence of do..end block.

puts( KlassWithSecret.new.instance_eval do
  @secret
end )

or use brace syntax of block

puts KlassWithSecret.new.instance_eval {
  @secret
}

This is because when you use do..end block, the block is passed to the puts function. The code with do..end block will work if you write it like this

puts(KlassWithSecret.new.instance_eval do
  @secret
end)
a = Proc.new {@secret}
puts KlassWithSecret.new.instance_eval(&a)
# 99

It say that puts KlaccWithSecret do @secret end does not gain the Proc(block).

Ruby(2.0.0) works. Code:

KlassWithSecret.new.instance_eval do
  p @secret
end
# 99

no problem.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top