Brian DiCasa
Brian DiCasa

Reputation: 9487

Ruby get inheriting class

I'm working on creating my first plugin for rails. I'm still pretty new to ruby and I was wondering if its possible to get the inheriting class?

For example, I'm trying to create a plugin that will allow unit testing and functional testing when you are not using migrations. What I'm trying to do is initialize a class variable named controller to be initialized to the type of controller that is being tested.

If I have a base class ControllerTest:

class ControllerTest < Test::Unit::TestCase
  attr_accessor :controller

  def initialize
    super
    @controller = "call function that will find the inheriting classes name and create an instance of that controller type."
  end
end

So what I'm currently stuck on is getting the name of the inheriting class. Is this possible? And if not, does anyone know another way on how I could go about implementing this?

Thanks in advance.

Upvotes: 8

Views: 18757

Answers (4)

Dino Reic
Dino Reic

Reputation: 3858

This will list only instance methods in current class

self.class.new.methods - self.class.ancestors[1].new.methods

And generic solution c = some_class

c.new.methods - c.ancestors[1].new.methods

Upvotes: 0

Arkku
Arkku

Reputation: 42139

If you wish to get the name of the class you're in at the moment, you can use self.class.name. If you wish to get the superclasses, you can use the array self.class.ancestors, e.g. self.class.ancestors[1].name. The immediate superclass is also available as self.superclass.

Edit, added example:

class ControllerTest
  attr_accessor :controller
  def initialize
    super
    @controller = eval "#{self.class.name}Controller.new(self)"
  end
end

class Foo <ControllerTest
end
class Bar <ControllerTest
end

class Controller
  def initialize (o)
    puts "Created #{self.class} to control #{o.class.name}"
  end
end

class FooController <Controller
end
class BarController <Controller
end

foo = Foo.new
bar = Bar.new

This outputs

Created FooController to control Foo
Created BarController to control Bar

Upvotes: 11

user65663
user65663

Reputation:

Very simple: use the "inherited" callback.

From the RDoc for the Class class: inherited(subclass): Callback invoked whenever a subclass of the current class is created.

Example:

   class Foo
      def self.inherited(subclass)
         puts "New subclass: #{subclass}"
      end
   end

   class Bar < Foo
   end

   class Baz < Bar
   end
produces:

   New subclass: Bar
   New subclass: Baz

http://ruby-doc.org/core/classes/Class.html#M002785

Upvotes: 10

Mike Cargal
Mike Cargal

Reputation: 6785

I believe you'll need to catch the classes as they're being defined...

From the RDoc for the Class class:

inherited(subclass)
Callback invoked whenever a subclass of the current class is created.

Example:

   class Foo
      def self.inherited(subclass)
         puts "New subclass: #{subclass}"
      end
   end

   class Bar < Foo
   end

   class Baz < Bar
   end
produces:

   New subclass: Bar
   New subclass: Baz

Upvotes: 1

Related Questions