File Coverage

lib/Spreadsheet/Engine/Function/IRR.pm
Criterion Covered Total %
statement 36 36 100.0
branch 8 12 66.6
condition 3 6 50.0
subroutine 9 9 100.0
pod 3 3 100.0
total 59 66 89.3


line stmt bran cond sub pod time code
1             package Spreadsheet::Engine::Function::IRR;
2              
3 28     28   155 use strict;
  28         58  
  28         1952  
4 28     28   146 use warnings;
  28         51  
  28         777  
5              
6 28     28   148 use base 'Spreadsheet::Engine::Fn::base';
  28         61  
  28         8109  
7 28     28   174 use Spreadsheet::Engine::Sheet qw/operand_value_and_type/;
  28         75  
  28         1867  
8 28     28   6213 use Spreadsheet::Engine::Fn::Approximator 'iterate';
  28         257  
  28         11732  
9              
10 27     27 1 89 sub argument_count { -1 => 2 }
11 27     27 1 106 sub signature { 'r', 'n' }
12              
13             sub result {
14 27     27 1 45 my $self = shift;
15 27         117 my ($r_op, $g_op) = $self->_ops;
16 27 50 66     226 die Spreadsheet::Engine::Sheet->val
      33        
17             if $g_op
18             and not $g_op->is_num
19             and not $g_op->is_blank;
20              
21 27         69 my @cashflows;
22 27         697 my @rangeoperand = ($r_op->value);
23              
24 27         208 while (@rangeoperand) {
25 81         1794 my $value1 =
26             operand_value_and_type($self->sheetdata, \@rangeoperand,
27             $self->errortext, \my $tostype);
28 81 50       229 die Spreadsheet::Engine::Sheet->val if substr($tostype, 0, 1) eq 'e';
29 81 50       311 push @cashflows, $value1 if substr($tostype, 0, 1) eq 'n';
30             }
31              
32             my $rate = iterate(
33             initial_guess => $g_op ? $g_op->value : 0.01,
34             function => sub {
35 254     254   282 my $rate = shift;
36 254         264 my $sum = 0;
37 254         236 my $factor = 1;
38 254         329 for my $cf (@cashflows) {
39 762 50       1356 $factor *= (1 + $rate) or die Spreadsheet::Engine::Error->div0;
40 762         1212 $sum += $cf / $factor;
41             }
42 254         621 return $sum;
43             },
44 27 100       333 );
45 27 100       173 die Spreadsheet::Engine::Error->num unless defined $rate;
46 26         663 return Spreadsheet::Engine::Value->new(type => 'n%', value => $rate);
47              
48             }
49              
50             1;
51              
52             __END__