Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access parent class instance variable

How can this work?

class A
  attr_accessor :name

  def initialize params
    @name = params[:name]
    @collection << B.new 
  end
end

class B < A
  def initialize
    @my_name = lookup_something(<parent.name>)
  end
end

Basically, I need a value from the parent class to use in a lookup on the child class, but I don't want to pass it explicitly if there's a better way. Is the instance var of the parent totally inaccessible in the child class? Or is this just poor hierarchy design?

like image 683
Bruno Antunes Avatar asked May 20 '10 14:05

Bruno Antunes


People also ask

Can child class access instance variables of parent class?

You inherit the following from the parent class. This means, the child class has all of the public methods that the parent class has. It has all of the instance variables. The only unusual aspect is that, within child class method definitions, you can't directly access parent class instance variables.

How do you access the private variable of parent class in a child class python?

Use a single underscore ( _field ) instead. This "documents" that the attribute is intended to be private (e.g. not part of a class's public API), without enabling name mangling. That way, if you find later than another class does need to access the variable it can.


1 Answers

I don't really know what you are trying to do here - all the code you posted works on instance variables. Instance variables are per-object, not per class, so I don't know what you mean when you say "I need a value from the parent class".

There are several things that I note with your code:

  • Base classes should never be aware of subclasses. So creating B objects in A#initialize is not a good thing, because the base uses the subclass.
  • You are overwriting the class B#initialize with a completely different behaviour than A#initialize. You even change the parameter list. Not a very good thing either. An object of a subclass should behave in the same way as an object of its superclass.
  • When you call B.new('myname') the variable @name is never assigned, because the A#initialize method is never called. You will have to either call super(:name => name) (to run the superclass initialize) or you have to assign to @name directly in B#initialize
  • Once @name is defined, all your instance methods can use its value. Including the ones that are defined in the parent/superclass.

Let me say I'm not quite sure why you are using inheritance here, I have the feeling that it is not what you want. If you have two classes for two different things, there should never be inheritance involved. If you want to re-use code, either have a look at Ruby's mixin feature, or compose your complex objects of several "smaller" objects that have the behaviour you want to re-use.

like image 116
averell Avatar answered Sep 26 '22 00:09

averell