File Coverage

blib/lib/App/Math/Tutor/Role/DecFracExercise.pm
Criterion Covered Total %
statement 17 20 85.0
branch n/a
condition n/a
subroutine 7 10 70.0
pod n/a
total 24 30 80.0


line stmt bran cond sub pod time code
1             package App::Math::Tutor::Role::DecFracExercise;
2              
3 1     1   855 use warnings;
  1         2  
  1         30  
4 1     1   5 use strict;
  1         2  
  1         44  
5              
6             =head1 NAME
7              
8             App::Math::Tutor::Role::DecFracExercise - role for exercises in decimal fraction
9              
10             =cut
11              
12 1     1   7 use Moo::Role;
  1         2  
  1         7  
13 1     1   349 use MooX::Options;
  1         2  
  1         7  
14              
15             with "App::Math::Tutor::Role::Exercise", "App::Math::Tutor::Role::DecFrac";
16              
17 1     1   664 use Scalar::Util qw(looks_like_number);
  1         2  
  1         830  
18              
19             our $VERSION = '0.004';
20              
21 230     230   856 sub _lt { return $_[0] < $_[1]; }
22 0     0   0 sub _le { return $_[0] <= $_[1]; }
23 0     0   0 sub _gt { return $_[0] > $_[1]; }
24 0     0   0 sub _ge { return $_[0] >= $_[1]; }
25 230     230   1491 sub _ok { return 1; }
26              
27             =head1 ATTRIBUTES
28              
29             =head2 range
30              
31             Specifies range of resulting numbers ([m..n] or [m..[n or m]..n] ...)
32              
33             =cut
34              
35             option range => (
36             is => "ro",
37             doc => "Specifies range of results",
38             long_doc => "Specifies range of fraction value using a lower and an upper limit:\n\n"
39             . "\t--range [m..n] -- includes value of m and n in range\n\n"
40             . "\t--range [m..[n -- includes value of m in range, but exlude n\n\n"
41             . "\t--range m]..n] -- excludes value of m from rangem but include n\n\n",
42             isa => sub {
43             defined( $_[0] )
44             and !ref $_[0]
45             and $_[0] !~ m/^(\[?)((?:\d?\.)?\d+)(\]?)\.\.(\[?)((?:\d?\.)?\d+)(\]?)$/
46             and die("Invalid range");
47             },
48             coerce => sub {
49             defined( $_[0] )
50             or return [ 0, \&_lt, undef, \&_ok ];
51              
52             ref $_[0] eq "ARRAY" and return $_[0];
53              
54             my ( $fmtmin, $fmtmax ) = (
55             $_[0] =~ m/^( (?:\[(?:\d+\.?\d*)|(?:\.?\d+))
56             |
57             (?:(?:\d+\.?\d*)|(?:\.?\d+)\])
58             )
59             (?:\.\.
60             (
61             (?:\[(?:\d+\.?\d*)|(?:\.?\d+))
62             |
63             (?:(?:\d+\.?\d*)|(?:\.?\d+)\])
64             )
65             )?$/x
66             );
67             my ( $minr, $minc, $maxr, $maxc );
68              
69             $fmtmin =~ s/^\[// and $minc = \&_le;
70             $fmtmin =~ s/\]$// and $minc = \&_lt;
71             defined $minc or $minc = \&_lt;
72             $minr = $fmtmin;
73              
74             if ( defined($fmtmax) )
75             {
76             $fmtmax =~ s/^\[// and $maxc = \&_gt;
77             $fmtmax =~ s/\]$// and $maxc = \&_ge;
78             defined $maxc or $maxc = \&_ge;
79             $maxr = $fmtmax;
80             }
81             else
82             {
83             $maxc = \&_ok;
84             }
85              
86             return [ $minr, $minc, $maxr, $maxc ];
87             },
88             default => sub { return [ 0, \&_lt, undef, \&_ok ]; },
89             format => "s",
90             short => "r",
91             );
92              
93             =head2 digits
94              
95             Specifies number of decimal digits (after decimal point)
96              
97             =cut
98              
99             option digits => (
100             is => "ro",
101             doc => "Specified number of decimal digits (after decimal point)",
102             long_doc => "Specify count of decimal digits after decimal point (limit value using range)",
103             isa => sub {
104             defined( $_[0] )
105             and looks_like_number( $_[0] )
106             and $_[0] != int( $_[0] )
107             and die("Digits must be natural");
108             defined( $_[0] )
109             and ( $_[0] < 2 or $_[0] > 13 )
110             and die("Digits must be between 2 and 13");
111             },
112             coerce => sub {
113             int( $_[0] );
114             },
115             default => sub { return 5; },
116             format => "s",
117             short => "g",
118             );
119              
120             =head1 LICENSE AND COPYRIGHT
121              
122             Copyright 2010-2014 Jens Rehsack.
123              
124             This program is free software; you can redistribute it and/or modify it
125             under the terms of either: the GNU General Public License as published
126             by the Free Software Foundation; or the Artistic License.
127              
128             See http://dev.perl.org/licenses/ for more information.
129              
130             =cut
131              
132             1;