This is a read-only archive!

Ruby: instance_eval constant scoping broken

This bit me at work today.

class Foo
  CONST = 1
  def test(&b)
    instance_eval &b
  end

  private
  def foo
    puts "FOO"
    puts CONST
  end
end

Foo.new.test do
  foo
  puts CONST
end

Output:

chester@compy ~ $ ruby --version
ruby 1.8.5 (2006-08-25) [i486-linux]
chester@compy ~ $ ruby test.rb
FOO
1
test.rb:18: uninitialized constant CONST (NameError)
    from test.rb:6:in `instance_eval'
    from test.rb:6:in `test'
    from test.rb:16

This has been changed in 1.9 though, it seems.

chester@compy ~ $ ruby1.9 --version
ruby 1.9.0 (2006-06-08) [i486-linux]
chester@compy ~ $ ruby1.9 test.rb
FOO
1
1

This post by Matz seems to verify that. Looks like they changed scoping rules for constants. As a workaround we have to fully-qualify our constants. i.e. this works in 1.8:

Foo.new.test do
  foo
  puts Foo::CONST
end
June 28, 2007 @ 2:22 PM PDT
Cateogory: Programming
Tags: Ruby