tatey.com

Why I Like Enumerable#inject

Recently I’ve been helping a friend learn Ruby. Digging around first year university assignments, I stumbled on a method definition for calculating the annual interest on a bank balance that’s compounded monthly. The original implementation was in Java, which you could imagine would be more verbose.

def calculate_interest(rate)
  monthly_balance = @balance
  interest = 0
  12.times do
    monthly_interest = monthly_balance * rate
    interest = interest + monthly_interest
    monthly_balance = monthly_balance + monthly_interest
  end
  interest
end

Look at all those variables. Yuck. I would never write code like this today. Accumulation is a perfect candidate for Enumerable#inject.

def calculate_interest(rate)
  balance_plus_interest = 12.times.inject(@balance) do |balance, m| 
    balance += balance * rate
  end
  balance_plus_interest  @balance
end

Storing the result is unnecessary.

def calculate_interest(rate)
  12.times.inject(@balance) { |b, m| b += b * rate }  @balance
end

Although unnecessary, I’d argue it may lead to less readable code.

Lastly, while you’re not prevented from chaining method invocations to the end keyword, it doesn’t feel right. That said, I’m open to change.

def calculate_interest(rate)
  12.times.inject(@balance) do |balance, m| 
    balance += balance * rate
  end  @balance
end

If you've read this far, you should follow me on Twitter.


← Older
Newer →