$var global scope

English.rb has a list of all the standard global variables.

@var scoped to instance

usually defined like this:

  class Example
    attr_reader :iv
    def initialize
      @iv = 123
    end
  end
  ex = Example.new
  ex.iv   # 123
@@var scoped to class

but don't use it. better to have @x scoped to the Class object like this:

  class Example
    @civ = 123
    class << self
      attr_reader :civ
    end
  end
  Example.civ     # 123

or

  
  class Example
    def self.count
      @count ||= 0
    end
    def self.count=(n)
      @count = n
    end
    def initialize
      self.class.count += 1
    end
  end
  x = Example.new
  y = Example.new
  puts Example.count    # 2

The reason for this is that @@var belongs to the class hierarchy, not to the class:

    class Parent
      @@var = 1
    end
    class Child < Parent
      @@var = 2
    end
    class Parent
      puts @@var   # shows 2, since these @@var's are not distinct
    end
var local scope

There is a separate local scope for:

  • top level
  • class and module definitions (executed at definition)
  • method definitions (executed at each method call)

For example, the top, class, and module variables are not available inside methods.

block scope

Blocks have access to their container's scope but also start their own scope. Local variables first used inside a block are scoped to the block.

To ensure that a block variable is not used in its container, it can be defined as block-local (1.9+).

    x = 99
    4.times.do |i ; x|
      # x is block-local so it is not the same as the x in x = 99
    end
    

Block parameters are scoped to the block. If a block parameter has the same name as a variable in the container's scope, they are distinct so the variable from the container can't be seen inside the block.

    x = 98
    i = 99
    4.times.do |i ; x|
      # x is block-local       so it is not the same as the x in x = 98
      # i is a block parameter so it is not the same as the i in i = 99
    end
  

Because a block has its container's scope in addition to its own, defining a Proc with a block includes the container's scope at the time of definition of the Proc in its block, that is, a Proc acts a closure.