Reputation: 7209
Some undeclared variables are nil, some throw an error. How come?
$ irb
1.9.3p0 :001 > asdf # local
NameError: undefined local variable or method `asdf' for main:Object
from (irb):1
from /Users/saizai/.rvm/rubies/ruby-1.9.3-p0/bin/irb:16:in `<main>'
1.9.3p0 :002 >@asdf # instance
=> nil
1.9.3p0 :003 >@@asdf # class
NameError: uninitialized class variable @@asdf in Object
from (irb):3
from /Users/saizai/.rvm/rubies/ruby-1.9.3-p0/bin/irb:16:in `<main>'
1.9.3p0 :004 > $asdf # global
=> nil
Upvotes: 4
Views: 852
Reputation: 17169
Class variables must always be assigned or else they will return a NameError
when you attempt to use them. I do not currently have the details as to why this is.
Instance and Global variables will return nil
even if they are not assigned. However, they will raise a warning if you run the script with the -w
flag.
I do, however, have the answer in regards to the local variables. The reason local variables act like this comes in the fact that they do not have any punctuation in front of them. This means the variable could be either a variable or a method call (since Ruby does not require ()
after a method call with no parameters).
something # could be a variable named 'something' or a method called 'something()'
If there is no value assigned to something
variable then the Ruby interpreter assumes it is a method invocation. If there is no method by that name then it raises NameError
. That is why you will get this message:
NameError: undefined local variable or method 'something' for main:Object
from (irb):1
from path/to/Ruby/bin/irb:12 in '<main>'
So, it is important for the Ruby interpreter to treat local variables in this manner just in case it is actually a method you are referring to.
As an interesting side note:
There is one quirk—a variable comes into existence when the Ruby interpreter sees an assignment expression for that variable. This is the case even if that assignment is not actually executed. A variable that exists but has not been assigned a value is given the default value nil.
Which means that:
if false
z = "Something"
end
z.nil? #=> true
never_assigned.nil? #=> NameError
The above quote is from The Ruby Programming Language by David Flanagan and Yukihiro Matsumoto section 4.2
Upvotes: 5