Kaushik Vijayakumar
Kaushik Vijayakumar

Reputation: 835

Create inner-class object after executing outer-class's constructor in Ruby?

I want to create objects for inner classes in a class. All the inner class methods use a common variables which needs to be initialised when the the outer class is created.

class A
    @x = nil
    @y = nil
    def initialize(x, y)
        @x = x
        @y = y
    end

    class B
        def func_b
            puts "x- #{@x} and y- #{@y} in class B"
        end
    end

    class C
        def func_c
            puts "x- #{@x} and y- #{@y} in class C"
        end
    end
end

I was able to create object for classes B and C like

#1
b = A::B.new
#2
a = A
c = a::C.new

But I want to initialize A before creating objects for B or C

Something like

a = A.new(4,5)
b = a::C.new

But this doesn't seem to work. How should I do the above.

Upvotes: 1

Views: 188

Answers (2)

Max
Max

Reputation: 22365

Nested modules and classes in Ruby are a mostly organizational choice. Compare this

class A; end
class B; end

and this

class A
  class B; end
end

There are only two differences between these

  1. In the second example, you have to write A::B to access B
  2. In the second example, constants accessed in B will be looked up in A before they are looked up in the top-level

If you actually want the instances of these classes to be related, you need a sub- and superclass relationship between them i.e.

class B < A; end

now instances of B can access methods and instance variables in A. Note that this is independent of nesting, you could define that as

class A
  class B < A; end
end

but again that's only an organizational difference.


On a totally separate note, this

class A
  @x = nil
  @y = nil
end

does not do what you think it does. This is setting instance variables on A itself, i.e. treating A as an instance of A.singleton_class. If you want default values for the instances of A, you have to set those in initialize:

class A
  def initialize
    @x = nil
    @y = nil
  end
end

Upvotes: 2

Kaushik Vijayakumar
Kaushik Vijayakumar

Reputation: 835

class A
    def initialize(x, y)
        @x = x
        @y = y
    end
end

class B < A
    def func_b
        puts "x- #{@x} and y- #{@y} in class B"
    end
end

class C < A
    def func_c
        puts "x- #{@x} and y- #{@y} in class C"
    end
end

c = C.new(4,5)
c.func_c

prints

x- 4 and y- 5 in class C

This seems to work fine :).

Upvotes: 0

Related Questions