Marcin Doliwa
Marcin Doliwa

Reputation: 3659

Defining attr_accessor in parent class using constants from child classes

I have parent class, and some child classes

class Base
end
class ChildNameAge < Base
  ATTRIBUTES = [:name, :age]
  attr_accessor *ATTRIBUTES
end
class ChildHeightWidth < Base
  ATTRIBUTES = [:height, :width]
  attr_accessor *ATTRIBUTES
end

How can I move this attr_accessor to parent class, but still use ATTRIBUTES constant from child classes, so I wouldn't have to repeat this attr_accessor *ATTRIBUTES for each child class.

Upvotes: 1

Views: 181

Answers (2)

user11659763
user11659763

Reputation: 193

You'll define ATTRIBUTES in Base as a Hash associating the class name to the attributes and use the inherited method for Class.

class Base
  ATTRIBUTES = {
    "ChildNameAge" => [:name, :age],
    "ChildHeightWidth" => [:height, :width]
  }

  def self.inherited(child)
    return unless (attributes = ATTRIBUTES[child.name])
    child.class_eval { attr_accessor *attributes }
  end
end

This way, when you'll create your child class it'll be directly defined. But like other said, it's not a good idea (even if it's possible). You cannot document your attributes (using automatic doc like YARD) and when you read the Child implementation, you don't see exactly where the attributes are defined (which can lead to missunderstanding of the classes.)

Upvotes: 0

Peter Gao
Peter Gao

Reputation: 96

Your question is fundamentally flawed. You are inverting the dependency cycle of Class-based inheritance.

Parents cannot know anything about their children, by definition of Class-based inheritance.

Moving attr_accessor to the Base (parent) class would mean it would only have access to values defined in itself, not in any of its children!

Upvotes: 3

Related Questions