Re: Template Method Pattern (GoF) without abstract methods in Ruby

Michael Schwarze <[email protected]>
Newsgroups gmane.comp.lang.ruby.general
Message-ID <[email protected]>
Hi Austin,

> Am 11.01.2019 um 17:52 schrieb Austin Ziegler <[email protected]>:

Many thanks for your patience and your explanations!

> But that’s my point. If you’re trying to implement the `Template Method Pattern`, you’re trying to use GoF as a recipe book. This is a mistake and will only hinder your learning of Ruby.

Sorry, my English is probably worse than my Ruby ;-) I’m not really focussed on implementing the pattern 'by the book‘ but I think my problem is in the realm of the Template Method Pattern...

> What problem are you actually trying to solve?

A simple management report which was text-only so far and should get an additional HTML output now; both following the same process / outline in generating the slightly differing output. That’s why I supplied the three made-up code examples with my initial email.

> In Ruby, you quite *literally* don’t need abstract methods.

That was my understanding from the book, too. I did a web research but the results confused me, as they contained mainly abstract methods in Ruby. Hence my request to this list.

> class Processor
>   def process
>     step1
>     step2
>     step3
>     finalize
>   end
> 
>   private
> 
>   def finalize
>     # finalize the process here
>   end
> end
> 
> class Foo < Processor
>   private
> 
>   def step1; end
>   def step2; end
>   def step3; end
> end

Code helps - that’s the discussion I was looking for! That’s close to my example 2...

> If I do Processor.new.process, I will get a NoMethodError because I have no implementation of `step1`, `step2`, or `step3`. If I do `Foo.new.process`, it works. You don’t need abstract methods in Ruby because the methods don’t have to exist during compilation, because there’s no compilation phase or static method resolution.

Ok, I get this. So you are suggesting inheritance here, but why use a class you will probably never instantiate? Why not mixin a module with the common methods (my example 3)?

  module Processor
    def process
      step1
      step2
      step3
      finalize
    end
    
    def finalize; end
  end

  class Foo
    include Processor

    def step1; end
    def step2; end
    def step3; end
  end

  class Bar
    include Processor

    def step1; end
    def step2; end
    def step3; end
  end

Or, when preferring inheritance, why not inheriting from the simple use case (my example 1):

  class Foo # simple text
    def process
      step1
      step2
      step3
      finalize
    end

    def step1; end
    def step2; end
    def step3; end
    def finalize; end
  end

  class Bar # complex HTML
    def process
      step1
      step2
      step3
      finalize
    end

    def step1; end
    def step2; end
    def step3; end
    def finalize; end
  end

All three approaches do work but which one would do Ruby experts prefer for solving this problem?

Cheers,
Michael

Unsubscribe: <mailto:[email protected]?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.