How to use Ruby mixins as patches to classes

metaprogramming, mixins, ruby

Solution

Your module code doesn't work because it is executed in wrong context. You need to execute it in context of `A`, but it is instead evaluated in context of `Plus`. This means, you need to change `self` from `Plus` to `A`.

Observe:

class A
  def print
    "A"
  end
end

class B < A
  def print
    super + "B"
  end
end

module Plus
  self # => Plus
  def self.included base
    self # => Plus
    base # => A
    base.class_eval do
      self # => A
      alias_method :print_orig, :print
      def print
        print_orig + "+"
      end
    end
  end
end

A.send :include, Plus
B.new.print # => "A+B"

Problem

I started looking into Ruby, since I am looking to a more dynamic alternative to Java. I like how you can modify a class in Ruby after it's definition, for example like this: ``` class A def print "A" end end class B < A def print super + "B" end end class A alias_method :print_orig, :print def print print_orig + "+" end end puts B.new.print # A+B ``` Now I try to do the same with mixins: ``` class A def print "A" end end class B < A def print super + "B" end end module Plus alias_method :print_orig, :print def print print_orig + "+" end end A.extend(Plus) # variant 1 B.extend(Plus) # variant 2 class A # variant 3 include Plus end class B # variant 4 include Plus end puts B.new.print ``` However none of the variants produce the expected result. BTW, the expected result is the following: I want to be able to 'patch' class A with a mixin, in order to modify its behavior. I want to use mixins, since I want to 'patch' several classes with the same behavior. Is it possible to do what I want? If yes, how?

Original source

Related problems