0

I have a design problem which I can't think up an elegant solution for. I'm writing a background job in my rails app which means that my job class (MyJobClass) must inherit from a certain parent job class (ParentJobClass). My job will need to have the same methods, however the implementation of some of those methods will need to be different depending on the value of a parameter which is passed in during the instantiation of my job class.

Because MyJobClass is already inheriting from ParentJobClass I don't get how to get multiple implementations of the same method.

I was thinking of something like a conditional mixin of a module containing the specific implementations. However I'm not sure if that's a possible since it would be conditional on a parameter that's passed in during instantiation. E.g. something like...

class ParentJobClass
end

class MyJobClass < ParentJobClass
  
  case @p1
  when 'text'
    include TextTips
  when 'image'
    include ImageTips
  when 'video'
    include VideoTips
  end


  def initialize(p1)
    @p1 = p1
  end


end
1
  • A small point concerning your tags: it's a pure-Ruby question so the Rail's tag is not deserved, and it seems to me unlikely that anyone would search on "oop", "design-patterns", or "polymorphism", as they are so broad, so I would suggest just the single tag "ruby". Commented Feb 10, 2023 at 1:46

1 Answer 1

2

You are correct that they way you have it will not work because it relies on an instance variable that is out of scope. (@p1 in the context of the class will always be nil)

While you would probably be better off implementing specific sub-classes (or just standalone classes depending on implementation), as it would be more communicative, technically speaking you can include those modules specific to the eigenclass of the instance. Meaning:

class MyJobClass < ParentJobClass
  MODS = {'text' => TextTips, 'image' => ImageTips, 'video' => VideoTips}.freeze 

  def initialize(p1) 
    @p1 = p1 
    singleton_class.include(MODS[p1]) if MODS.key?(p1)
  end 
end 

Or use dependency injection for the same

class MyJobClass < ParentJobClass
  def initialize(p1, mod=nil) 
    @p1 = p1 
    singleton_class.include(mod) if mod.class == Module 
  end 
end 

MyJobClass.new('text',TextTips)

By way of simplified example:

class Foo 
  def initialize(mod=nil) 
    singleton_class.include(mod) if mod
  end 
  def hello = 'hi'
end 

module Portuguese
  def hello = 'olá'
  def goodbye = 'adeus'
end 

a = Foo.new
a.hello   #=> 'hi'
a.goodbye #=> NoMethodError

b = Foo.new(Portuguese)
b.hello   #=> 'olá'
b.goodbye #=> 'adeus'
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.