The inherited attribute was mainly implemented to solve the problem in which the ruby ββclass variable is common for class inheritance. Consider this example
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"
This will create this output.
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
Please note that since Rails 3.2 write_inheritable_attribute has been removed. See http://dev.mensfeld.pl/2012/01/upgrading-to-rails-3-2-0-from-rails-3-1-3/
With the class attribute (an attribute that was inherited) we can implement something like this:
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"
This will create this output.
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
Reynard
source share