In what circumstances should I use instance variables instead of other variable types?
class, ruby, ruby-on-rails, ruby-on-rails-3, variables
Solution
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.
Problem
I am using Ruby on Rails 3 and I would like to know in what circumstances should I use instance variables instead of other variable types and if there are security reason for those. Example: ``` # Using an instance variable @accounts = Account.find(...) # Using a "local"\"normal" variable account = Account.find(...) ```