Alexander Sirobaba
Alexander Sirobaba

Reputation: 4599

How can I dynamically extend/modify all methods of inherited class in Ruby?

I have a class like this:

class MainClass
  def self.method_one(String)
      puts "#{self.class} a"
  end
  def self.method_two(String)
      puts "#{self.class} a"
  end
end

And I have a class which inherits the MainClass:

class NewClass < MainClass
  #any_mathod should match any method that is called for NewClass call
  def self.any_method(a,b)
     puts "#{self.class} b"
     super(a)
  end
end

Is there any way how can I extend all methods from the MainClass when running them from NewClass without redefining them all in NewClass to accept two parameters instead of one, for example:

NewClass.method_one(String1, String2)

And it will produce:

#=> NewClass String2
#=> MainClass String1

and to process String1 parameter within NewClass class. The processor for the additional parameter will be the same for all the methods.

Upvotes: 3

Views: 412

Answers (3)

Catnapper
Catnapper

Reputation: 1905

Another approach is to ditch inheritance and use modules instead:

module TestModule
  def awesome1
  end
  def awesome2
  end
end

class TestClass
  def self.include mod
    puts (mod.instance_methods - Module.methods).sort
    super
  end
  include TestModule
end

Add singleton methods in the overridden #include as in the above answers.

Upvotes: 0

evfwcqcg
evfwcqcg

Reputation: 16335

Maybe you wanted super method

class A
  def self.method_one(a)
    puts "a is #{a}"
  end
end

class B < A
  (superclass.methods - superclass.superclass.methods).each do |m|
    define_singleton_method(m) do |a, b|
      puts "b is #{b}"
      super(a)
    end
  end
end

B.method_one(5, 10)

# => b is 10
# => a is 5

Upvotes: 2

Justin Ko
Justin Ko

Reputation: 46836

Try this:

class MainClass
    def self.method_one(string)
        puts string
    end
    def self.method_two(string)
        puts string
    end
end


class NewClass < MainClass
    #Iterate through all methods specific to MainClass and redefine
    (self.superclass.public_methods - Object.public_methods).each do |method|
        define_singleton_method method do |string1, string2|
            #Common processing for String1
            puts string1 

            #Call the MainClass method to process String2
            super(string2)
        end
    end
end

NewClass will iterate through all methods defined specifically in MainClass. Then it will define a class method for NewClass that processes String1 and then calls the MainClass method to process String2.

Upvotes: 1

Related Questions