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
Ответы
Ответ 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