Подтвердить что ты не робот

Attr_accessor для переменных класса

attr_accessor не работает над следующим кодом. Ошибка говорит "undefined method 'things' for Parent:Class (NoMethodError)":

class Parent
  @@things = []
  attr_accessor :things
end
Parent.things << :car

p Parent.things

Однако следующий код работает

class Parent
  @@things = []
  def self.things
    @@things
  end
  def things
    @@things
  end
end
Parent.things << :car

p Parent.things
4b9b3361

Ответ 1

attr_accessor определяет методы доступа для экземпляра. Если вам нужны автогенерированные аксессоры класса, вы можете использовать его в метаклассе

class Parent
  @things = []

  class << self
    attr_accessor :things
  end
end

Parent.things #=> []
Parent.things << :car
Parent.things #=> [:car]

но обратите внимание, что это создает переменную экземпляра класса, а не переменную класса. Вероятно, это то, что вы хотите, поскольку переменные класса ведут себя по-другому, чем вы могли бы ожидать при работе с наследованием. См. "Переменные класса и экземпляра в Ruby".

Ответ 2

attr_accessor генерирует аксессоры для переменных экземпляра. Переменные класса в Ruby - это совсем другое дело, и они обычно не то, что вы хотите. Вероятно, вам нужна переменная экземпляра класса. Вы можете использовать attr_accessor с переменными экземпляра класса, например:

class Something
  class <<self
    attr_accessor :things
  end
end

Тогда вы можете написать Something.things = 12, и он будет работать.

Ответ 3

Просто уточнение: переменные класса не будут доступны с помощью attr_accessor. Все о переменных экземпляра:

class SomeClass
  class << self
    attr_accessor :things
  end
  @things = []
end

потому что в Ruby класс является экземпляром класса "Класс" (Бог, я люблю это говорить), а attr_accessor устанавливает методы доступа для переменных экземпляра.

Ответ 4

Это, наверное, самый простой способ.

class Parent
  def self.things
    @@things ||= []
  end
end
Parent.things << :car

p Parent.things

Ответ 5

Также обратите внимание, что метод singleton - это метод только для одного объекта. В Ruby класс также является объектом, поэтому он также может иметь одноэлементные методы! Поэтому имейте в виду, когда вы можете их называть.

Пример:

class SomeClass
  class << self
    def test
    end
  end
end

test_obj = SomeClass.new

def test_obj.test_2
end

class << test_obj
  def test_3
  end
end

puts "Singleton methods of SomeClass"
puts SomeClass.singleton_methods
puts '------------------------------------------'
puts "Singleton methods of test_obj"
puts test_obj.singleton_methods

Одиночные методы SomeClass

тест


Одиночные методы test_obj

test_2

test_3