I have a question, because in most serious sources I read, all say the same No variable is ever declared in Ruby , but still I have doubts, because according to what I was taught in my university implicit declaration is when a variable is created via allocation, where you can specify the type of a variable through conventions established in the language. This contrasts with explicit declaration, when the data type specified in its declaration, like C. or at least that's what I understood. So I was taught wrong?, or I misunderstood something?
asked Jan 12, 2015 at 20:17 729 1 1 gold badge 7 7 silver badges 14 14 bronze badgesNo variable is ever declared in Ruby
What they meant:
There is no keyword defining a line of code as declaring a variable. Variables can just be used, and at worst are nil .
If you have not previously assigned a value to a variable in Ruby, it becomes nil as soon as you retrieve its value.
class Foo def bar @bar end end a = Foo.new puts a.bar
You weren't taught wrong. They just describe it in a non academic way.
answered Jan 12, 2015 at 21:26 Greg Burghardt Greg Burghardt 40.7k 8 8 gold badges 79 79 silver badges 130 130 bronze badgesConstant variables and class hierarchy variables raise a NameError if they are not defined, instance variables and global variables evaluate to nil , and local variables also evaluate to nil but need to be disambiguated from a method call by being lexically defined first, otherwise they will raise a NameError but for being ambiguous, not undefined.
Commented Jan 12, 2015 at 23:17Different variables behave differently in Ruby, but none of them need explicit declaration.
The most interesting behavior is for local variables: Ruby allows you to leave off the receiver for a message send to self ( self is the implicit receiver), so foo() is the same thing as self.foo() , and it also allows you to leave off the argument list if there are no arguments, so foo.bar is the same thing as foo.bar() ; putting the two together, we get that foo is the same thing as self.foo() , i.e. a message send without arguments to the implicit receiver self . It could, however, also be a reference to the local variable foo . This ambiguity is resolved the following way: foo is interpreted as a message send, unless an assignment to foo has been parsed (but not necessarily executed) before, then from that point on it is interpreted as a local variable.
This is the closest thing Ruby has to variable declaration:
foo # NameError: undefined local variable or method `foo' defined?(foo) # => nil def foo; 23 end foo # => 23 defined?(foo) # => 'method' methods # => [:foo, …] if false then foo = 42 end foo # => nil defined?(foo) # => 'local-variable' local_variables # => [:foo]
Note that the NameError is not raised because the local variable is undefined, but because Ruby doesn't know what to make of the expression: is it a local variable or a method call?
Instance variables and global variables behave similarly, they evaluate to nil even if they are not defined:
@foo # => nil defined?(@foo) # => nil @foo = 42 @foo # => 42 defined?(@foo) # => 'instance-variable' instance_variables # => [:@foo] $foo # => nil defined?($foo) # => nil $foo = 42 $foo # => 42 defined?($foo) # => 'global-variable' global_variables # => [:$foo, …]
Class hierarchy variables and constants behave differently, they raise NameError if they are not defined:
@@foo # NameError defined?(@@foo) # => nil @@foo = 42 @@foo # => 42 defined?(@@foo) # => 'class-variable' self.class.class_variables # => [:@@foo] FOO # NameError defined?(FOO) # => nil FOO = 42 FOO # => 42 defined?(FOO) # => 'constant' self.class.constants # => [:FOO]