“Template methods”

Suppose we have the following setup


module M1 
    included do 
        def m1_method1
            building_block1
        end

        def building_block1
            implementation1
        end
    end
end
  
class C1
    include M1

    def building_block1
        override_implmentation1
    end
end

C1.m1_method1

Problems with this setup

  • Often building_block1 has a generic name. As a result, RubyMine and VSCode are not able to find definitions or references precisely. They return a giant list of methods with the same name instead.
  • Ideally, template method interface is abstract. A concrete implementation1 misleads me on the runtime behavior, espeically when the I find the definition through C1.m1_method1
    • What if I take out the M1.building_block1 or implementation1? Then we expect the classing mixining M1, e.g., C1, should implement or override building_block1., but there is no class or method signature to enforce this expectation. You can imagine my frustration when I find this during the runtime

Override mixin’s constant

module M1 
    STATE = "m1_state"
    included do 
        def m1_method1
            process(STATE)
        end
    end
end
  
class C1
    include M1
    STATE = 'c1_state'
end

C1.m1_method1

This setup frustrates the code reader. Imagine the sequence of actions:

  • The user finds the defintion of C1.m1_method1
  • The code runs, but STATE in m1_method1 is different from the definition in the same class.
  • The user finds the reference of the STATE, and the IDE returns 20 different places with 3 different overrides.

Stateless mixins that are not utils

module M1 
    included do 
        def m1_method1
        end
    end
end

module M2 
    included do 
        def m2_method2
            m1_method1
        end
    end
end

module M3 
    included do 
        def m3_method3
            m1_method1
        end
    end
end

class C1
    include M2
    include M3
end

C1.m3_method3
C1.m2_method2
  • Hard to navigate through layers of definitions, especially if any name is generic. Often IDEs are not able to resolve the method precisely
  • I prefer just merging stateless mixins