четверг, 11 июля 2013 г.

How to realize inheritance of 'class methods' of modules in Ruby



# This script shows how to call parent method in module A from the method in module B that is overwritten.
# Output of calling:

#This is D
#Calling D.b
#
#this is A.ClassMethodsA.b
#Called from:D.b
#
#this is A.ClassMethodsA.a_b
#Called from:D.a_b
#
#this is B.ClassMethodsB.b
#Called from:D.b



# if you change the order of calling 'extend' in child module
# def self.included(base)
#   base.extend(ClassMethodsA)
#   base.extend(ClassMethodsB)
# end
#
# the output will be looks like this:

#This is D
#Calling D.b
#
#this is B.ClassMethodsB.b
#Called from:D.b
#
#this is A.ClassMethodsA.b
#Called from:D.b
#
#this is A.ClassMethodsA.a_b
#Called from:D.a_b

module A
  def self.included(base)
    base.extend(A::ClassMethodsA)
  end 

  module ClassMethodsA
    def b
      puts "this is A.ClassMethodsA.b"
      puts 'Called from:' + name + '.' + __method__.to_s
      puts ''
      a_b
      super if defined?(super)
    end
    def a_b
      puts "this is A.ClassMethodsA.a_b"
      puts 'Called from:' + name + '.' + __method__.to_s
      puts ''
    end

  end
end


module B
  module ClassMethodsB
    def b
      puts "this is B.ClassMethodsB.b"
      puts 'Called from:' + name + '.' + __method__.to_s
      puts ''
      super if defined?(super)
    end
  end

  include A
  def self.included(base)
    base.extend(ClassMethodsB)
    base.extend(ClassMethodsA)
  end
end


class D
  include B
  puts 'This is D'
  puts 'Calling D.b'
  puts ''
  b
end


1 комментарий:

  1. More simple implementation


    module Moo
    def self.hello
    puts "Hello, I'm module Moo!"
    end
    end

    module Foo
    include Moo

    def self.hello
    puts "Hello, I'm module Foo!!!"
    puts "There are my ancestors:"
    puts ""
    Moo.hello

    end
    end

    module Bar
    include Foo

    def hello
    puts "Hello, I'm module Bar!!!"
    puts "There are my ancestors:"
    puts ""
    Foo.hello
    end

    def self.included(base)
    base.extend(Bar)
    end
    end

    class A
    include Bar
    hello
    end

    ОтветитьУдалить