views:

208

answers:

1

I've written a very basic finance module in Ruby to ease my own calculations, as sometimes it's just a lot easier to enter irb and start calling functions. But the odd thing is, that in my module I have a submodule with a method called future_value (Finance::CompoundInterest.future_value) ... but according to irb it doesn't exist? It's quite small, but I'd really prefer to be able to use compound interest instead of having to enter the formula each time.

When loading in irb no errors or warnings are thrown, and the method is invisible for all intents and purposes. Almost sadly, I can instantiate a Finance::Mortgage.

Here's my finance unit:

module Finance
  module CompoundInterest
    def future_value(present_value, interest, length)
      interest /= 100 if interest >= 1 # if given in percent 1..100
      present_value * ((1 + interest)**length)
    end
  end

  class Mortgage
    attr_accessor :amount, :rate, :years, :payment, :interest_paid
    def initialize(amount, rate, years)
      @amount, @rate, @years = amount, rate, years

      i = rate  / 12
      n = years * 12
      m = (1 + i)**n

      @payment = ((i * m) / (m - 1)) * amount
      @interest_paid = @payment * n - amount
    end
  end
end

What have I mistyped to get this strange situation? I am using Ruby 1.8.7-72.

+4  A: 

In the method declaration you need to prefix the name with "self." or with the name of the module i.e.

def self.future_value(present_value, interest, length)

or

def CompoundInterest.future_value(present_value, interest, length)

It should then work as you expect. This is the same way that you define a class method (as opposed to an instance method) on a class.

mikej
So to wit, just writing "def some_method" in a module defines a module instance method -- it's copied as an instance method into a class when you write "include SomeModule".
Chuck
Oh! I hadn't considered that. Do the class-methods get implemented as such when included?
The Wicked Flea
No, the self methods from the module don't get mixed in as class methods when included. Take a look at the "included" hook and the Class.extend method if this is something you'd like to do. Feel free to ask if you'd like more info.
mikej