Question

Like the following code shows, having class accessors defined in the superclass could have unexpected behaviours because the class accessor is the same variable for all the subclasses.

class Super 
  cattr_accessor :name
end

class SubA < Super; end
class SubB < Super; end

SubA.name = "A"
SubB.name = "B"

SubA.name
 => "B" # unexpected!

I want to have an independent class accessor for each subclass, so a possible solution is moving the cattr_accessor from the superclass and putting it in every subclass.

class Super; end

class SubA < Super
  cattr_accessor :name
end

class SubB < Super
  cattr_accessor :name
end

SubA.name = "A"
SubB.name = "B"

SubA.name
 => "A" # expected!

It is this solution a good practice? Do you know better alternatives?

Was it helpful?

Solution

Open up Super's singleton class and give that a regular attr_accessor:

class Super 
  class << self
    attr_accessor :name
  end
end

That should give you the semantics you want: a "class level instance variable".

However I'll note that any value set for :name on Super will not be inherited by Super's children. This makes sense if you think about it: the children inherit the attr_accessor, not the attribute itself.

There are some ways around this, most notably rails provides class_attribute which provides the ability of children to inherit the value of the parent's attribute unless explicitly overridden.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top