Атрибут Inheritable был реализован в основном для решения проблемы, когда переменная класса ruby является общей для наследования классов.Рассмотрим этот пример
class Counter
@@count = 0
def self.count
@@count
end
def self.increment
puts "==> #{self} increment"
@@count += 1
end
end
class DogCounter < Counter
end
puts "Counter.count: #{Counter.count}"
puts "DogCounter.count: #{DogCounter.count} -> nice, DogCounter inherits @@count from Counter"
DogCounter.increment
puts "DogCounter.count: #{DogCounter.count} -> as expected"
puts "Counter.count: #{Counter.count} -> but Counter.count is also changed!"
Counter.increment
puts "Counter.count: #{Counter.count}"
puts "DogCounter.count: #{DogCounter.count} -> @@count is shared with all the descendants of Counter"
Это приведет к выводу
Counter.count: 0
DogCounter.count: 0 -> nice, DogCounter inherits @@count from Counter
==> DogCounter increment
DogCounter.count: 1 -> as expected
Counter.count: 1 -> but Counter.count is also changed!
==> Counter increment
Counter.count: 2
DogCounter.count: 2 -> @@count is shared with all the descendants of Counter
Обратите внимание, что начиная с Rails 3.2 был удален write_inheritable_attribute.См. http://dev.mensfeld.pl/2012/01/upgrading-to-rails-3-2-0-from-rails-3-1-3/
С помощью атрибута класса (который раньше был наследуемым атрибутом) мы можем реализовать что-то вроде этого:
class Counter
class_attribute :count
self.count = 0
def self.increment
puts "==> #{self} increment"
self.count += 1
end
end
class DogCounter < Counter
end
puts "Counter.count: #{Counter.count}"
puts "DogCounter.count: #{DogCounter.count} -> nice, DogCounter inherits count from Counter"
DogCounter.increment
puts "DogCounter.count: #{DogCounter.count} -> as expected"
puts "Counter.count: #{Counter.count} -> nice, it doesn't change count for Counter"
Counter.increment
puts "Counter.count: #{Counter.count}"
puts "DogCounter.count: #{DogCounter.count} -> now each subclass can have their own class attribute that inherits default value from the superclass"
Это приведет к выводу
Counter.count: 0
DogCounter.count: 0 -> nice, DogCounter inherits count from Counter
==> DogCounter increment
DogCounter.count: 1 -> as expected
Counter.count: 0 -> nice, it doesn't change count for Counter
==> Counter increment
Counter.count: 1
DogCounter.count: 1 -> now each subclass can have their own class attribute that inherits default value from the superclass