Question: In Ruby, What is the difference between `@@variable` to `self.variable`

1. In the scope of main.
2. In the scope of the class
3. In the scope of a method

For example my file looks like: 

```
self.variable = 'data'
@@variable = 'data'

def class A
  self.variable = 'data'
  @@variable = 'data'

  def method()
    self.variable = 'data'
    @@variable = 'data'
  end
end

```

How many variables are there? And under what scope?

Answer: 
```
self.variable = 'data'

```

This is a method call at toplevel. The `self.` just distinguishes it as a method call versus a local variable definition. Assuming you have `def variable= x` somewhere, it will call that method. Otherwise it's a `NoMethodError`

```
@@variable = 'data'

```

This generates a warning: "class variable access from toplevel". Class variables are shared among all objects of that class *and* subclasses. Toplevel's class is just Object, so effectively this is a *global* class variable `[].instance_eval { @@variable } # 'data'` because everything ultimately derives from Object.

```
def class A
  self.variable = 'data'
  @@variable = 'data'

```

Same deal as above, but now the receiver is `A` so it will call `A.variable=('data')` and set `@@variable` on `A`.

```
  def method()
    self.variable = 'data'
    @@variable = 'data'

```

And now the receiver is some instance of `A`, let's say `a = A.new`. So it's `a.variable=('data')`. `@@variable` is set for `A` as before since all instances of a class (and its subclasses) share the one variable.

The **only** case in which you can assume that `self.variable = 'data'` means anything in particular is if you see `attr_accessor :variable` or `attr_writer :variable` in the class's context. In those cases it's a particular method call that sets `@variable`. Otherwise it could do literally anything and you need to read the method definition.
1. Difference between `@@variable` and `self.variable` in scope of `main`.

As we probably know, `@@variable` is a class variable.

`@@variable` will attach itself to the class of `self.class`. The class of main is `Object`.

To demonstrate:

```
self # => main
self.class # => Object
@@variable = "variable"
self.class.class_variables # => [:@@variable]
object.class_variables # => [:@@variable]

```

Be aware, this means *every* object will have access to `@@variable`.

```
String.class_variables # => [:@@variable]

```

and modifying that variable at the top level will also change its value for all objects.

`self.variable` will give a `NoMethodError`, as there are no getters or setters for it. If you were to define a getter and setter, however ...

```
class Object
  class << self
    attr_accessor :variable
  end
end
self.variable = "variable" # => "variable"

```

2. Difference between `@@variable` and `self.variable` in scope of a class.

`@@variable` will be have the same way as above, except now instead of class `Object`, we're applying it to whatever class we're currently in.

But now, `self.variable` will apply to a *Class Instance Variable*. This is the sort of variable that's most commonly referred to as Class Variables or Static Variables in other languages (ie. it is only accessible to that class, and not its children). It is the same as having a `@variable` at the class's top level.

```
class T
  @some = "some"
  class << self
    attr_accessor :variable
  end
  self.variable = "variable"
end
T.instance_variables # => [:@some, :@variable]

```

3. Difference between `@@variable` and `self.variable` in scope of a method.

`@@variable` behaves exactly as above -- it's still referring to the class we are defining the method of.

But now `self.variable` refers to an *instance* variable, not the Class's instance.

```
class T
  attr_accessor :variable
  def initialize
    self.variable = "variable"
  end
end
instance = T.new
instance.instance_variables
instance.variable # => "variable"

```

4. "How many variables are there? And under what scope?"

In your example, there are 5 variables (assuming proper getters/setters have been created):

1. Class variable `@@variable` belonging to `Object`
2. Instance variable `main.variable` belonging to the instance `main` of class `Object`
3. Class variable `@@variable` belonging to `A`
4. Class Instance variable `A.variable` belonging to class `A`
5. Instance variable `@variable` belonging to any instances of `A`.