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