4

I'm kind of confused about how scoping works in Ruby. Which Ruby scoping rules prevent the following code from printing out the value of x?

#!/usr/bin/ruby

x = 5
def test
    puts "x = #{x}"
end

test    # => undefined local variable or method `x' for main:Object

The equivalent Python script does print the value of x:

#!/usr/bin/python

x = 5
def test():
    print "x = %s" % x

test()  # => x = 5

2 Answers 2

5

This is so called "scope gate". There are three gates in ruby: definition of a method, a class or a module. Meaning that inside that definition locals from outer scope are not visible.

This is so because when scope changes, current set of bindings gets replaced by a new set of bindings and cannot be easily accessed.

See "Metaprogramming Ruby: Program Like the Ruby Pros" for more information.

Sign up to request clarification or add additional context in comments.

1 Comment

3

See "Ruby classes, include, and scope" for more information about Ruby's scoping and scope gating.

There are a few ways to provide visibility to your test function. One is to make the variable an instance variable:

#!/usr/bin/ruby

@x = 5
def test
    puts "x = #{@x}"
end

And another is to use a closure with lambda:

#!/usr/bin/ruby

x = 5
test = lambda do
    puts "x = #{x}"
end

test.call

or Proc.new()

#!/usr/bin/ruby

x = 5
test = Proc.new do
    puts "x = #{x}"
end

test.call

For the differences between lambda and Proc.new, see "When to use lambda, when to use Proc.new?".

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.