В общем случае переменная экземпляра является локальной и сохраняется внутри экземпляра объекта, тогда как локальная переменная является только локальной и сохраняется внутри области действия функции / объекта / блока. Например:
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
В функции greet name
- это локальная переменная, которая определяется только внутри этой функции. Переменная name устанавливается в первой строке функции, name = user.name || 'John'
, но ее значение не сохраняется вне функции. Когда вы пытаетесь вызвать name
, вы получаете NameError
, потому что имя было определено только как локальная переменная в функции greet.
@name
локально для пользовательского экземпляра класса User. Когда вы пытаетесь вызвать его вне этого контекста, вы получаете nil
. Это одно различие между локальными и переменными экземпляра, переменные экземпляра возвращают nil, если они не были определены, тогда как локальные переменные не экземпляра вызывают ошибку.
Обратите внимание, что оба типа переменных локальны для определенного контекста. @name
определяется в пользовательском экземпляре, поэтому, когда вы вызываете user.name
, вы вызываете функцию name в пользовательском экземпляре, в котором определено @name
. name
определяется только в функции greet, поэтому при вызове p "Hi, my name is #{name}"
вы можете получить значение для name
, поскольку находитесь в области действия, в которой оно определено.