Я не собираюсь делать это с самого начала. Начинать с нуля может быть очень долго, очень быстро, и я хотел бы просто сосредоточиться на узкой части переменных экземпляра, которые беспокоили меня и заставили меня немного разобраться. Так что, если вы надеялись, что это будет еще один длинный пост… Мне жаль? Посмотрим, как быстро я смогу осуществить эту передачу знаний.

Итак, как они работают?

Переменные экземпляра очень похожи на «обычные» локальные переменные в Ruby. Локальные переменные представляют собой значение, хранящееся в памяти. Мы используем переменную для доступа к этим данным и делаем с ними забавные вещи.

Переменные экземпляра ведут себя немного иначе:

  1. Они не существуют до тех пор, пока код не будет выполнен в первый раз. Они существуют после создания экземпляра первого объекта из класса, но не раньше.
  2. переменные экземпляра являются общими для всех экземпляров класса. Каждый экземпляр использует одну и ту же переменную. Они не получают свои собственные версии переменной

Итак, если переменные экземпляра являются общими, как Ruby узнает, на какие данные указывают переменные?

Столы!

Столы!… как говорится в заголовке. Я буду работать над своими переходами.

При первом создании экземпляра объекта класса Ruby помещает все переменные экземпляра в таблицу.

class My_Pets
  def initialize
    @cat = "frisky"
    @bird = "chirpy"
    @mouse = "squeaky"
    @dog = "barky"
  end
end

My_Pets.new

Таким образом, с приведенной выше настройкой мы создаем новый экземпляр My_Pets.

Во-первых, Ruby игнорирует значения, потому что еще не составил список всех переменных. Таким образом, вы получаете таблицу, построенную с каждой переменной экземпляра, закодированной в этой таблице, и ее положение в этой таблице записывается (как массив).

#pretend this is a table
_____________
|@cat   | 0 |
|@bird  | 1 |
|@mouse | 2 |
|@dog   | 3 |
_____________

Как ни странно, но мы еще не закончили.

Затем Ruby создает массив значений переменных экземпляра. Это делается для каждого экземпляра класса:

#value array
["frisky", "chirpy", "squeaky", "barky"]

Как вы, наверное, поняли, порядок значений соответствует порядку переменных экземпляра, которые на них указывают. Положение значений в массиве также соответствует положению чисел в таблице. Вот как Руби отслеживает!

При создании исходной таблицы Ruby сохраняет эту информацию статической, потому что ваши переменные экземпляра не меняются. Единственное, что является динамическим, это то, что Ruby знает, какой массив искать, и это предоставляется каждым экземпляром класса.

Итак, когда вам нужно значение переменной экземпляра, Ruby просматривает таблицу переменных экземпляра, а затем ищет соответствующий номер переменной экземпляра, для которой вы пытаетесь получить значение. Затем он переходит непосредственно к этой числовой позиции в массиве значений и извлекает ее для использования.

Это не похоже на потрясающую новость, но переменные экземпляра просто не имели для меня смысла, пока я не узнал вышеизложенное. Ответ «именно так они и работают» меня не устраивал.

Спасибо за прочтение! Оставляйте любые вопросы или отзывы в комментариях. Всегда рад их читать.