ruby: переменные экземпляра класса против переменных экземпляра
Моя идея состоит в том, чтобы создать сообщество вики для людей, которые приходят из java
фон, потому что, читая много объяснений, я ничего не мог понять, пока я действительно не попробовал пару вещей, и части головоломки не начали находить свои места. Но сначала я должен убедиться, что я правильно понял. Исходя из такого фона, мне было очень странно узнать, что @variable
может означать 2 очень разные вещи. Вот пример:
class Test
@ins = "gah"
def self.ins
puts @ins
end
def initialize()
@ins = "wtf?"
end
def ins2
puts @ins
end
end
Насколько я понимаю, первый @ins
переменная экземпляра объекта, представляющего класс Test
, Второй @ins
переменная экземпляра в объекте класса Test
,
Теперь вещи начинают иметь некоторый смысл для меня. Вот пара примеров:
[14] pry(main)> test.ins2
wtf?
Мы вызываем метод объекта, и он возвращает переменную экземпляра объекта.
[15] pry(main)> test.ins
NoMethodError: undefined method `ins' for #<Test:0x000000017d9348 @ins="wtf?">
Мы пытаемся вызвать метод класса через объект, этот метод относится к классу, поэтому мы получаем NoMethodError
[16] pry(main)> Test.ins
gah
Мы вызываем метод класса, чтобы он правильно видел переменную экземпляра объекта класса.
[17] pry(main)> Test.ins2
NoMethodError: undefined method `ins2' for Test:Class
Мы вызываем объектный метод через класс, который является неправильным, поэтому NoMethodError
,
Все вышеперечисленное было выполнено с помощью ruby 2.0. Так что я спрашиваю?
- Я правильно понял?
- Я правильно понимаю терминологию рубина?
- Любое реальное использование переменных экземпляра класса, которые имеют смысл в правильно разработанном приложении? Или это просто лучшие переменные @@class?
3 ответа
мне было очень сложно понять, что
@variable
может означать 2 очень разные вещи.
Нет, это не так. Классы являются объектами, как и любой другой объект. Они могут иметь переменные экземпляра, как и любой другой объект. Они могут иметь методы экземпляра, как и любой другой объект. Фактически, в отличие от Java, который имеет три различных типа "методов" (методы экземпляра, статические методы и конструкторы), в Ruby существует только один тип метода: методы экземпляра.
Красота того, чтобы занятия были объектами, заключается именно в том, что @variable
всегда означает одно и то же.
Нет такой вещи как переменная экземпляра класса: это просто обычная переменная экземпляра, как и любая другая. Объект оказывается экземпляром Class
, но это не меняет природу переменной экземпляра. Переменная экземпляра объекта класса String
это не переменная экземпляра строки, это просто переменная экземпляра. Аналогично, переменная экземпляра объекта класса Class
это просто переменная экземпляра.
Нет такого понятия, как метод класса: это просто обычный одноэлементный метод объекта, который является экземпляром Class
, (На самом деле, не существует такого понятия, как одноэлементный метод: это просто обычный метод экземпляра одноэлементного класса объекта.)
Примечание. Рубиисты могут использовать термин "метод класса" в обычной беседе. Но это не означает, что методы класса на самом деле существуют, это означает лишь то, что "метод экземпляра синглтон-класса объекта класса" является полным ртом. Важная вещь: поскольку классы являются объектами, они работают точно так же, как и все другие объекты. У них могут быть методы экземпляра (определенные в классе Class
или унаследовано от Module
, Object
, Kernel
или же BasicObject
), они могут иметь "одноэлементные методы" (которые на самом деле являются методами экземпляров их соответствующих одноэлементных классов), они могут иметь переменные экземпляра.
Они также могут иметь переменные класса (@@variables
)... это странно. Игнорируй их:-)
Во-первых, чтобы понять переменные экземпляра, нужно это знать - классы являются объектами.
Все классы являются экземплярами
Class
(читать документ), который наследует отObject
, Вот почему классы являются объектами.Затем каждый экземпляр переменных (идентификаторы отмечены
@
, лайк@ins
) определены вself
,когда
self
является классом, они являются переменными экземпляра классов (переменные экземпляра класса). когдаself
является объектом, они являются переменными экземпляра объектов (переменные экземпляра).В разных областях кода
self
представляет разные вещи.class Test # class scope, uncomment following line to see the value of self # p self @ins = "gah" def self.ins # class scope # p self puts @ins end def initialize() # object scope # p self @ins = "wtf?" end def ins2 # object scope # p self puts @ins end end
Все выглядит правильно для меня.
Переменная класса будет передана через наследование, а переменная экземпляра класса - нет. (src: переменная экземпляра класса Ruby против переменной класса)
Что касается проектирования, я предпочитаю вообще избегать переменных класса (я бы предпочел использовать синглтон), но если бы мне пришлось выбирать одну, я бы, вероятно, выбрал переменную класса вместо переменной экземпляра класса, чтобы избежать путаницы.