In general an instance variable is local and persisted inside an instance of an object, whereas a local variable is only local and persisted inside a function/object/block scope. For instance:
class User
def name
@name
end
def name= name
@name = name
end
end
def greet user
name = user.name || 'John'
p "Hi, my name is #{name}"
end
user = User.new
greet user
=> 'Hi, my name is John'
name
=> NameError: undefined local variable or method 'name' for main:Object
user.name = "Mike"
greet user
=> 'Hi, my name is Mike'
@name
=> nil
In the greet function name
is a local variable that is only defined within that function. The name variable is set on the first line on the function, name = user.name || 'John'
, but its value is not persisted outside of the function. When you try calling name
you get a NameError
because name has only been defined as a local variable within the greet function.
@name
is local to the user instance of the User class. When you try calling it outside of that context you get nil
. This is one difference between local and instance variables, instance variables return nil if they have not been defined, whereas local non-instance variables raise an Error.
Notice that both variable types are local to a specific context though. @name
is defined within the user instance, so when you call user.name
you are calling the name function in the user instance, in which @name
is defined. name
is only defined in the greet function, so when you call p "Hi, my name is #{name}"
you are able to get a value for name
because you are within the scope in which it is defined.