1

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?

OiciTrap
  • 729

2 Answers2

4

What they said:

No 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.

  • 1
    Constant 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. – Jörg W Mittag Jan 12 '15 at 23:17
3

Different 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]
Jörg W Mittag
  • 103,514