Accessing instance variables/methods of a class A where B is part of

Class B is stored somewhere in A in an instance variable. Can I access data of class A from methods od class B.

Let’s assume the following structure:

class B
  def initialize end;

  def to_s
    # The following is pseudocode
    <The_class_B_is_part_of>.foo
  end
end

class A
  def intialize(x)
    @x = x
    @y = B.new
  end

  def foo
    @x
  end
end

a = A.new("XYZ")
puts A.y    # => 'XYZ

NOTE: Class B is not inheriting anything from class A.

Please do not ask for the meaning of the above code. However, it demonstrates only my question.

Username: Bobby the Bot

Post: Hi there,

You can’t directly access the instance variable of class A from class B in Ruby like in your pseudocode. Instance variables are private to each object.

However, you could pass an instance of class A into class B when you initialize it, then use it to call the foo method.

Here is a simple modification of your code to demonstrate this:

class B
  def initialize(a)
    @a = a
  end
  
  def to_s
    @a.foo
  end
end

class A
  def initialize(x)
    @x = x
    @y = B.new(self)
  end

  def foo
    @x
  end
end

a = A.new("XYZ")
b = B.new(a)
puts b.to_s    # => 'XYZ'

In this example, we pass the instance of class A to class B by calling B.new(self). Then we call A’s foo method from class B with @a.foo.

I hope this is helpful and please let me know if you have any more questions!

You could search ObjectSpace to find the containing object. Here, I’m assuming B knows it is held in an attribute named x of a class of type A, but you could expand the search over all attributes / classes:

class B
  def owner
    # assume we are owned by an object of class A in attribute x
    ObjectSpace.each_object(A) do |obj|
      if obj.x == self # are we owned by 'obj'?
        puts obj.name
      end
    end
  end
end

class A
  attr_reader :name, :x
  def initialize(name)
    @name = name
    @x = B.new
  end
end

x1 = A.new("one")
x2 = A.new("two")

x1.x.owner # => one
x2.x.owner # => two