0

I'm looking for a way to advance a set of methods wrapped in a method. Depending on input from users, a certain version of a set of methods needs to be used, but I'm wanting to know how to best version the system. Is there a way I can avoid loads of conditionals and repetitive code?

What I'm currently considering:

module Module_3 def self.alpha() puts 'alpha 3' end end module Module_4 def self.alpha() puts 'alpha 4' end end module Module_5 def self.alpha() puts 'alpha 5' end end version = 4 case version when 3, 6 include Module_3 when 4 include Module_4 else include Module_5 end 

The issue with this is the method call. I would have to use the module namespace in front:

Module_4.alpha # => alpha 4 

So that hard coding means there really is no efficient way around this, that I can find. The case method cannot penetrate a method as the scope keeps it unavailable to any conditional inside the method to make a choice.

module Mod case version # => undefined local variable or method when 3, 6 def self.alpha() puts 'alpha 3' end when 4 def self.alpha() puts 'alpha 4' end else def self.alpha() puts 'alpha 5' end end end include Mod 

Again, the question: Is there a way I can avoid loads of conditionals and repetitive code?

2 Answers 2

2

If you are going to use a module, my approach would be something similar to @engineersmnky last example, although would use load as opposed to require.

This script would be loaded with the main application. (simplified)

class MyModule def self.init_version(version) file = case version when 3, 6 then './my_module_3.rb' when 4 then './my_module_4.rb' when 5 then './my_module_5.rb' else raise RunTimeError, "invalid versions specified - #{version}" end load file end end 

Then you would have separate scripts for each behavior you need for each version.

mymodule_3.rb

class MyModule def self.alpha puts 'alpha 3' end end 

mymodule_4.rb

class MyModule def self.alpha puts 'alpha 4' end end 

mymodule_5.rb

class MyModule def self.alpha puts 'alpha 5' end end 

Once you get the version you need to process, invoke MyModule.init_version(version), and the appropriate method will be loaded into MyModule. If the version changes, you can recall init_version to have the methods be overwritten with the required ones. require will not reload the scripts once they are already loaded, but load will.

This is still not "ideal", but more flexible without checking versions with each method call. Depending on your situation, it may not be necessary at all to have the ability to change versions during execution. You would maintain the ability to use consistent method calls, but so long as you load the correct version, each method will be specific for that version.

Sign up to request clarification or add additional context in comments.

Comments

2

While I don't understand why you would want to to this.

I guess you could go with something similar to your first implementation but rather like this:

module Module_3 def alpha() puts 'alpha 3' end end module Module_4 def alpha() puts 'alpha 4' end end module Module_5 def alpha() puts 'alpha 5' end end version = 4 Mod = Module.new.send(:include, case version when 3, 6 Module_3 when 4 Module_4 else Module_5 end) include Mod 

Then you can just use Mod e.g. Mod.alpha (regardless of version).

Additionally if you were to put them in separate filed then simply have 1 module name would be fine and you can make the require conditional like.

case version when 3, 6 require_relative 'mod_3.rb' when 4 require_relative 'mod_4.rb' else require_relative 'mod_5.rb' end include Mod # where module Mod is defined in each of the above files 

4 Comments

Users are uploading a spreadsheet with a "version number" in it. The structure of this file might change, so I've put in a version number in a field. I test to decide how to proceed post-upload.
Would personally prefer to use load instead of require in this case to support different versions being used within the same application. They can be dynamically overwritten each time the required version is changed if swapping around different versions. May not be needed at all in OP's case, it is unclear, but would be more flexible.
@ForeverZero I can agree although I hate the implementation all together and if there were more context chances are this is better suited for a class based implementation than a module based one.
@engineersmnky Agreed :)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.