1Number::Tolerant(3) User Contributed Perl Documentation Number::Tolerant(3)
2
3
4
6 Number::Tolerant - tolerance ranges for inexact numbers
7
9 version 1.708
10
12 use Number::Tolerant;
13
14 my $range = tolerance(10 => to => 12);
15 my $random = 10 + rand(2);
16
17 die "I shouldn't die" unless $random == $range;
18
19 print "This line will always print.\n";
20
22 Number::Tolerant creates a number-like object whose value refers to a
23 range of possible values, each equally acceptable. It overloads
24 comparison operations to reflect this.
25
26 I use this module to simplify the comparison of measurement results to
27 specified tolerances.
28
29 reject $product unless $measurement == $specification;
30
32 Instantiation
33 new
34
35 tolerance
36
37 There is a "new" method on the Number::Tolerant class, but it also
38 exports a simple function, "tolerance", which will return an object of
39 the Number::Tolerant class. Both use the same syntax:
40
41 my $range = Number::Tolerant->new( $x => $method => $y);
42
43 my $range = tolerance( $x => $method => $y);
44
45 The meaning of $x and $y are dependent on the value of $method, which
46 describes the nature of the tolerance. Tolerances can be defined in
47 five ways, at present:
48
49 method range
50 -------------------+------------------
51 plus_or_minus | x +/- y
52 plus_or_minus_pct | x +/- (y% of x)
53 or_more | x to Inf
54 or_less | x to -Inf
55 more_than | x to Inf, not x
56 less_than | x to -Inf, not x
57 to | x to y
58 infinite | -Inf to Inf
59 offset | (x + y1) to (x + y2)
60
61 For "or_less" and "or_more", $y is ignored if passed. For "infinite",
62 neither $x nor $y is used; "infinite" should be the sole argument. The
63 first two arguments can be reversed for "more_than" and "less_than", to
64 be more English-like.
65
66 Offset tolerances are slightly unusual. Here is an example:
67
68 my $offset_tolerance = tolerance(10 => offset => (-3, 5));
69 # stringifies to: 10 (-3 +5)
70
71 An offset is very much like a "plus_or_minus" tolerance, but its center
72 value is not necessarily the midpoint between its extremes. This is
73 significant for comparisons and numifications of the tolerance. Given
74 the following two tolerances:
75
76 my $pm_dice = tolerance(10.5 => plus_or_minus => 7.5);
77 my $os_dice = tolerance(11 => offset => (-8, 7));
78
79 The first will sort as numerically less than the second.
80
81 If the given arguments can't be formed into a tolerance, an exception
82 will be raised.
83
84 from_string
85
86 A new tolerance can be instantiated from the stringification of an old
87 tolerance. For example:
88
89 my $range = Number::Tolerant->from_string("10 to 12");
90
91 die "Everything's OK!" if 11 == $range; # program dies of joy
92
93 This will not yet parse stringified unions, but that will be
94 implemented in the future. (I just don't need it yet.)
95
96 If a string can't be parsed, an exception is raised.
97
98 stringify_as
99 my $string = $tolerance->stringify_as($type);
100
101 This method does nothing! Someday, it will stringify the given
102 tolerance as a different type, if possible. "10 +/- 1" will
103 "stringify_as('plus_or_minus_pct')" to "10 +/- 10%" for example.
104
105 numify
106 my $n = $tolerance->numify;
107
108 This returns the numeric form of a tolerance. If a tolerance has both
109 a minimum and a maximum, and they are the same, then that is the
110 numification. Otherwise, numify returns undef.
111
112 Overloading
113 Tolerances overload a few operations, mostly comparisons.
114
115 boolean
116 Tolerances are always true.
117
118 numify
119 Most tolerances numify to undef; see "numify".
120
121 stringify
122 A tolerance stringifies to a short description of itself, generally
123 something like "m < x < n"
124
125 infinite - "any number"
126 to - "m <= x <= n"
127 or_more - "m <= x"
128 or_less - "x <= n"
129 more_than - "m < x"
130 less_than - "x < n"
131 offset - "x (-y1 +y2)"
132 constant - "x"
133 plus_or_minus - "x +/- y"
134 plus_or_minus_pct - "x +/- y%"
135
136 equality
137 A number is equal to a tolerance if it is neither less than nor
138 greater than it. (See below).
139
140 smart match
141 Same as equality.
142
143 comparison
144 A number is greater than a tolerance if it is greater than its
145 maximum value.
146
147 A number is less than a tolerance if it is less than its minimum
148 value.
149
150 No number is greater than an "or_more" tolerance or less than an
151 "or_less" tolerance.
152
153 "...or equal to" comparisons include the min/max values in the
154 permissible range, as common sense suggests.
155
156 tolerance intersection
157 A tolerance "&" a tolerance or number is the intersection of the
158 two ranges. Intersections allow you to quickly narrow down a set
159 of tolerances to the most stringent intersection of values.
160
161 tolerance(5 => to => 6) & tolerance(5.5 => to => 6.5);
162 # this yields: tolerance(5.5 => to => 6)
163
164 If the given values have no intersection, "()" is returned.
165
166 An intersection with a normal number will yield that number, if it
167 is within the tolerance.
168
169 tolerance union
170 A tolerance "|" a tolerance or number is the union of the two.
171 Unions allow multiple tolerances, whether they intersect or not, to
172 be treated as one. See Number::Tolerant::Union for more
173 information.
174
176 This feature is slighly experimental, but it's here.
177
178 New tolerance types may be written as subclasses of
179 Number::Tolerant::Type, providing the interface described in its
180 documentation. They can then be enabled or disabled with the following
181 methods:
182
183 " enable_plugin "
184 Number::Tolerant->enable_plugin($class_name);
185
186 This method enables the named class, so that attempts to create new
187 tolerances will check against this class. Classes are checked against
188 "validate_plugin" before being enabled. An exception is thrown if the
189 class does not appear to provide the Number::Tolerant::Type interface.
190
191 " disable_plugin "
192 Number::Tolerant->disable_plugin($class_name);
193
194 This method will disable the named class, so that future attempts to
195 create new tolerances will not check against this class.
196
197 " validate_plugin "
198 Number::Tolerant->validate_plugin($class_name);
199
200 This method checks (naively) that the given class provides the
201 interface defined in Number::Tolerant::Type. If it does not, an
202 exception is thrown.
203
205 · Extend "from_string" to cover unions.
206
207 · Extend "from_string" to include Number::Range-type specifications.
208
209 · Allow translation into forms not originally used:
210
211 my $range = tolerance(9 => to => 17);
212 my $range_pm = $range->convert_to('plus_minus');
213 $range->stringify_as('plus_minus_pct');
214
215 · Create a factory so that you can simultaneously work with two sets
216 of plugins.
217
218 This one is very near completion. There will now be two classes
219 that should be used: Number::Tolerant::Factory, which produces
220 tolerances, and Number::Tolerant::Tolerance, which is a tolerance.
221 Both will inherit from N::T, for supporting old code, and N::T will
222 dispatch construction methods to a default factory.
223
225 The module Number::Range provides another way to deal with ranges of
226 numbers. The major differences are: N::R is set-like, not range-like;
227 N::R does not overload any operators. Number::Tolerant will not (like
228 N::R) attempt to parse a textual range specification like
229 "1..2,5,7..10" unless specifically instructed to. (The valid formats
230 for strings passed to "from_string" does not match Number::Range
231 exactly. See TODO.)
232
233 The "Number::Range" code:
234
235 $range = Number::Range->new("10..15","20..25");
236
237 Is equivalent to the "Number::Tolerant" code:
238
239 $range = Number::Tolerant::Union->new(10..15,20..25);
240
241 ...while the following code expresses an actual range:
242
243 $range = tolerance(10 => to => 15) | tolerance(20 => to => 25);
244
246 Thanks to Yuval Kogman and #perl-qa for helping find the bizarre bug
247 that drove the minimum required perl up to 5.8
248
249 Thanks to Tom Freedman, who reminded me that this code was fun to work
250 on, and also provided the initial implementation for the offset type.
251
253 Ricardo Signes <rjbs@cpan.org>
254
256 · Alexandre Mestiashvili <alex@biotec.tu-dresden.de>
257
258 · Karen Etheridge <ether@cpan.org>
259
260 · Michael Carman <mjcarman@cpan.org>
261
262 · Ricardo SIGNES <rjbs@codesimply.com>
263
264 · Smylers <Smylers@stripey.com>
265
267 This software is copyright (c) 2004 by Ricardo Signes.
268
269 This is free software; you can redistribute it and/or modify it under
270 the same terms as the Perl 5 programming language system itself.
271
272
273
274perl v5.32.0 2020-07-28 Number::Tolerant(3)