<dblack / candle.superlink.net> wrote in message
news:Pine.LNX.4.44.0208151402090.9010-100000 / candle.superlink.net...
> Hi --
>
> This has gotten bizarrely long.  But I think it's OK as an
> explanation.

I didn't track this thread, but today I independently tried to write up the
scoping rules for Ruby. I think they are very complex and difficult to
explain. Any given expression is working in a context of about 5 different
kinds of scope at the same time.

This is perhaps a weakness of Ruby - it makes an otherwise very easy
language very hairy in some aspects. Or is it because of this that most
things are easy - such as being able to have temporary variables in a class
definition?

Below is what I wrote - which ended up being just examples because other
attempts of description got rather complex. Disclaimer - it may not be
correct and the terms are certainly not official Ruby terms.

Mikkel



{chapter Scopes}

{section Introduction}

Ruby is a simple language, except the scopes in the Ruby language can be
somewhat complex.

In a Ruby file it is valid to assign an expression to a variable:

x = 3 * 7

It is also possible to define function (or method or message depending on
terminology):

def foo
  y = 2 * 7
end

The variable x assigned outside the function foo is not visible inside the
function. The variable y defined inside the function is not visible outside
the function.

However:

@a = 2

def double_a
  @a + @a
end

double_a # -> 4

Variables starting with @ are visible both inside and outside of functions.

This chapter will explain the non-trivial scoping rules of Ruby.

{section Everything is an object}

In Ruby almost everything is an object.

An basic object is a collection of member variables and member functions. At
any member variables and member functions can be added, removed or assigned
/ redefined.

A class has two basic objects: the prototype object and the static object.
In addition a class has child classes and child modules and a base class.

Ruby has some elaborate syntax to access these various objects, but it
really simplifies issues if it is remembered that a class really is two
objects.


class Foo

  @a = 2 #this is a static object member variable

  def Foo.hello
    #this is a static object method
    puts @a #same @a as above
  end

  def bar
    # this is a prototype object method
    @a = 4
    # the prototype access the @a in the instance
    # of the object redirecting the call to the prototype.
    @@b = 8

    #@@b is a member of the prototype object.
    #there is only one instance of @@b for the class

    # this method cannot directly access members of the
    # static object, but it can call static methods:

    Foo.bar

  end

end

def Foo.world
  #this is also a static object method of Foo
  #it accesses the same @a as Foo.hello
  puts @a + @a
end

a = Foo.new
def a.biz
  #this is a method that belongs to a single instance only.
end