Например, если мы пишем
class MyClass
attr_accessor :something
end
но явно не создал метод инициализации с переменной экземпляра @something
, Ruby автоматически создает его?
Например, если мы пишем
class MyClass
attr_accessor :something
end
но явно не создал метод инициализации с переменной экземпляра @something
, Ruby автоматически создает его?
Нет. Переменные экземпляра не определены до тех пор, пока вы их не назначите, а attr_accessor
не сделает это автоматически.
Попытка доступа к переменной экземпляра undefined возвращает nil
, но не определяет эту переменную. Они фактически не определяются, пока вы не напишите им. attr_accessor
полагается на это поведение и ничего не делает, кроме определения геттера/сеттера.
Вы можете проверить это, проверив .instance_variables
:
class Test
attr_accessor :something
end
Новый экземпляр x
не имеет переменных экземпляра:
x = Test.new # => #<Test:0xb775314c>
x.instance_variables # => []
Вызов геттера не вызывает @something
для определения:
x.something # => nil
x.instance_variables # => []
Вызов установщика приводит к тому, что @something
станет определяемым:
x.something = 3 # => 3
x.instance_variables # => ["@something"]
Настройка something
назад на nil
не приводит к возврату instance_variables
, поэтому мы можем быть уверены, что первый пустой возвращенный массив - это не просто случай instance_variables
omitting nil
values:
x.something = nil # => nil
x.instance_variables # => ["@something"]
Вы также можете проверить, что это не просто поведение, характерное для attr_accessor
:
class Test
def my_method
@x # nil
instance_variables # []
@x = 3
instance_variables # ["@x"]
end
end
Test.new.my_method
Сорт. В Ruby переменные экземпляра создаются, когда они сначала назначаются. Это полностью прозрачно для программиста. По умолчанию они равны нулю, пока не будут назначены.
Пример:
class Foo
attr_accessor :bar
def baz
@nonexistant
end
end
f.bar #=> nil
f.baz #=> nil
f.bar = 4
f.bar #=> 4
Пока вы не назначили значение переменной экземпляра, оно плавает в состоянии undefined nil.