I understand that a variable declared with @ outside of a class will become an instance variable of the object main.
Functionally, is this any different than declaring it as @@?
Yes, it is. @
is an instance variable, @@
is a class variable. At the top-level, @
is an instance variable of the main object, @@
is a class variable of Object
:
@@foo = :bar
# warning: class variable access from toplevel
Object.class_variables
# => [:@@foo]
I was expecting @test
declared in file2.rb
to throw an exception when accessed in file1.rb
(through require
), but it did not.
This has actually nothing to do with your question: instance variables never raise
an Exception
when accessed, even when they don't exist. They simply evaluate to nil
in that case.
Does this mean there is always only one main object
Yes, there is one main object.
and that @
and @@
are equivalent in this scope?
No, they are not. @
at the top-level is an instance variable of main
, @@
at the top-level is a class variable of Object
. And since class variables are inherited by all subclasses and all instances of the class and all its subclasses and (almost) all classes are subclasses of Object
and (almost) all objects are (indirect) instances of Object
, this means that top-level @@
is an (almost) global variable.
So, the scopes of top-level @
and @@
are very different!