0

I have a module that i am including in a few classes. Each class calculates different percentages for the modules methods.

Having calculations that are shared i thought i would abstract them into a singular module to include the shared methods. But the instance variables from the classes are not persisting into the modules methods.

So just to demonstrate the principle:

module Models::CharteredAccountancyMethods
  def calculated_npat_or_calculated_revenue
    [calculated_npat, calculated_revenue].max
  end

....
....

  def calculated_npat
    return 0 if @npat_percentage.to_f.zero?
    return scorecard.npat.to_f * @npat_percentage.to_f
  end

  def calculated_revenue
    return 0 if @revenue_percentage.to_f.zero? 
    return scorecard.general.revenue.to_f * @revenue_percentage.to_f
  end
end

This module is included in 3 classes. all of which need the calculated_npat_or_calculated_revenue method.

An example of a class:

class CharteredAccountancyGenericEnterpriseDevelopment < GenericEnterpriseDevelopment
  include Models::CharteredAccountancyMethods
  @npat_percentage = 0.03
  @revenue_percentage = 0.00375
  ....
  ....
end

The methods defined within the module work fine it picks up things like the scorecard object from the EnterpriseDevelopment class, which is then given it to it's child object the GenericEnterpriseDevelopment class through inheritance, and works fine.

Only if i call the calculated_npat method within the module the @npat_percentage will return 0. So it seems as if the @npat_percentage that is defined within the class is not persisting to the module methods that are included. Why is this? especially when just plain old inherited methods work.

I mean i could i suppose make them global variables or define a method that just returns a percentage. i thought it was really odd? and what is the best practice to do in such a situation. i dont want to have confusing methods or any global variables for that matter.

Thanks in advance.

1 Answer 1

1

When you use include the module's methods run on your class's instances. When you declared @npat_percentage you declared it in your class's static context, where it is not visible to the instances.

You should use extend instead, see here:

class CharteredAccountancyGenericEnterpriseDevelopment < GenericEnterpriseDevelopment
  extend Models::CharteredAccountancyMethods
  @npat_percentage = 0.03
  @revenue_percentage = 0.00375
  ....
  ....
end

Or alternatively, set the variables inside the def initialize method:

class CharteredAccountancyGenericEnterpriseDevelopment < GenericEnterpriseDevelopment
  include Models::CharteredAccountancyMethods

  def initialize
    @npat_percentage = 0.03
    @revenue_percentage = 0.00375
  end
  ....
  ....
end
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much Uri for the link its helped me understand the difference between extend and include.

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.