Brian
Brian

Reputation: 2415

Ruby base class call child class like in abstract classes

In Java, I am used to writing an abstract class that does some setup work and then delegates to the concrete class like this:

public abstract class Base {
    public void process() {
        // do some setup
        //...

        // then call the concrete class
        doRealProcessing();
    }
     
    protected abstract void doRealProcessing();
}

public class Child extends Base {
    @Override
    protected void doRealProcessing() {
        // do the real processing
    } 
}

I am having a hard time doing this in Ruby because I don't have abstract classes or methods. I also read that "you aren't supposed to need abstract classes or methods in Ruby and that I should stop trying to write Java in Ruby".

I would love to know what is the right way to implement the equivalence in Ruby?

Upvotes: 2

Views: 901

Answers (3)

steenslag
steenslag

Reputation: 80075

You don't see much of this in Ruby for this use case, because the pattern

  • do some household setup ( make a connection to a resource for instance)
  • do something real with it
  • teardown household job (f.i. close connection)

is baked into ordinary methods:

# pseudocode:
def a_method(an_argument)
  # do some setup with an_argument
  yield(a_result)
  # do some teardown
end

# use like:
a_method(the_argument){|the_result| puts "real processing with #{the_result}"}

Upvotes: 0

David Grayson
David Grayson

Reputation: 87486

Welcome to dynamically typed languages! You were probably nervous about just defining some function that wasn't declared anywhere. Don't be worried. It is very easy:

class Base
  def process
     # ...
     real_processing
  end

  def real_processing    # This method is optional!
    raise "real_processing not implemented in #{self.class.name}"
  end
end

class Child < Base
   def real_processing
     # ...
   end
end

b = Child.new
b.process

EDIT: Here's another option for you which avoids the need to have two different method names:

class Base
  def process
    # ...
  end
end

class Child < Base
  def process
    # ...
    super   # calls the process method defined above in Base
    # ...
  end
end

Upvotes: 2

manojlds
manojlds

Reputation: 301337

Here's how you can do the template pattern in Ruby:

class Template
  def template_method
    perform_step1
    perform_step2
    #do some extra work
  end

  def perform_step1
    raise "must be implemented by a class"
  end

  def perform_step2
    raise "must be implemented by a class"
  end
end

class Implementation < Template
  def perform_step1
    #implementation goes here
  end

  def perform_step2
    #implementation goes here
  end
end

http://andymaleh.blogspot.com/2008/04/template-method-design-pattern-in-ruby.html

Upvotes: 0

Related Questions