Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
1 | <?php |
||
9 | class MathEnv implements EnvInterface |
||
10 | { |
||
11 | use MappedEnvTrait; |
||
12 | |||
13 | const INVALID_ARG_REQUIRES_NUMERIC = 'All arguments must be numeric'; |
||
14 | const INVALID_ARG_TYPE_PRED_MATCH = 'Supplied arguments do not match the first'; |
||
15 | |||
16 | const MAPPING = [ |
||
17 | '+' => 'add', |
||
18 | '-' => 'subtract', |
||
19 | '*' => 'multiply', |
||
20 | '/' => 'divide', |
||
21 | '>' => 'isGreaterThan', |
||
22 | '>=' => 'isGreaterThanOrEqual', |
||
23 | '<' => 'isSmallerThan', |
||
24 | '<=' => 'isSmallerThanOrEqual', |
||
25 | '=' => 'isEqual', |
||
26 | 'number?' => 'isNumber', |
||
27 | 'integer?' => 'isInteger', |
||
28 | 'real?' => 'isReal', |
||
29 | 'complex?' => 'isComplex', |
||
30 | 'exact?' => 'isExact', |
||
31 | 'inexact?' => 'isInexact', |
||
32 | 'positive?' => 'isPositive', |
||
33 | 'negative?' => 'isNegative', |
||
34 | 'odd?' => 'isOdd', |
||
35 | 'even?' => 'isEven', |
||
36 | ]; |
||
37 | |||
38 | /** @var float */ |
||
39 | public $pi = M_PI; |
||
40 | |||
41 | /** |
||
42 | * Sum the args |
||
43 | * |
||
44 | * @param int[]|float[] $args |
||
45 | * @return int|float |
||
46 | * @throws \InvalidArgumentException |
||
47 | */ |
||
48 | 1 | public function add(...$args) |
|
53 | |||
54 | /** |
||
55 | * Subtract the args |
||
56 | * |
||
57 | * @param int[]|float[] $args |
||
58 | * @return int|float |
||
59 | * @throws \InvalidArgumentException |
||
60 | */ |
||
61 | 1 | View Code Duplication | public function subtract(...$args) |
70 | |||
71 | /** |
||
72 | * Multiply the args |
||
73 | * |
||
74 | * @param int[]|float[] $args |
||
75 | * @return int|float |
||
76 | * @throws \InvalidArgumentException |
||
77 | */ |
||
78 | 1 | public function multiply(...$args) |
|
83 | |||
84 | /** |
||
85 | * Divide the args |
||
86 | * |
||
87 | * @param int[]|float[] $args |
||
88 | * @return int|float |
||
89 | * @throws \InvalidArgumentException |
||
90 | */ |
||
91 | 1 | View Code Duplication | public function divide(...$args) |
100 | |||
101 | /** |
||
102 | * Returns true if $a is greater than $b, otherwise false |
||
103 | * |
||
104 | * @SuppressWarnings(PHPMD.ShortVariable) |
||
105 | * @param int|float $a |
||
106 | * @param int|float $b |
||
107 | * @return bool |
||
108 | */ |
||
109 | 1 | public function isGreaterThan($a, $b): bool |
|
114 | |||
115 | /** |
||
116 | * Returns true if $a is greater than or equal to $b, otherwise false |
||
117 | * |
||
118 | * @SuppressWarnings(PHPMD.ShortVariable) |
||
119 | * @param int|float $a |
||
120 | * @param int|float $b |
||
121 | * @return bool |
||
122 | */ |
||
123 | 1 | public function isGreaterThanOrEqual($a, $b): bool |
|
128 | |||
129 | /** |
||
130 | * Returns true if $a is smaller than or equal to $b, otherwise false |
||
131 | * |
||
132 | * @SuppressWarnings(PHPMD.ShortVariable) |
||
133 | * @param int|float $a |
||
134 | * @param int|float $b |
||
135 | * @return bool |
||
136 | */ |
||
137 | 1 | public function isSmallerThanOrEqual($a, $b): bool |
|
142 | |||
143 | /** |
||
144 | * Returns true if $a is smaller than $b, otherwise false |
||
145 | * |
||
146 | * @SuppressWarnings(PHPMD.ShortVariable) |
||
147 | * @param int|float $a |
||
148 | * @param int|float $b |
||
149 | * @return bool |
||
150 | */ |
||
151 | 1 | public function isSmallerThan($a, $b): bool |
|
156 | |||
157 | /** |
||
158 | * @param int[]|float[] ...$args |
||
159 | * @return bool |
||
160 | * @throws \InvalidArgumentException |
||
161 | */ |
||
162 | 1 | public function isEqual(...$args): bool |
|
177 | |||
178 | /** |
||
179 | * @param mixed $num |
||
180 | * @return bool |
||
181 | */ |
||
182 | 21 | public function isNumber($num): bool |
|
186 | |||
187 | /** |
||
188 | * Scheme's rules for integerness are slightly different than PHP's: |
||
189 | * An integer can be a "float" but it must have `.0` |
||
190 | * |
||
191 | * @param mixed $num |
||
192 | * @return bool |
||
193 | */ |
||
194 | 1 | public function isInteger($num): bool |
|
198 | |||
199 | /** |
||
200 | * Not implemented yet. |
||
201 | * Requires complex number support |
||
202 | * |
||
203 | * @param $num |
||
204 | * @return bool |
||
205 | * @throws \Error |
||
206 | * @SuppressWarnings(PHPMD) |
||
207 | */ |
||
208 | 1 | public function isComplex($num): bool |
|
212 | |||
213 | /** |
||
214 | * Not implemented yet. |
||
215 | * Requires complex number support |
||
216 | * |
||
217 | * @param $num |
||
218 | * @return bool |
||
219 | * @throws \Error |
||
220 | * @SuppressWarnings(PHPMD) |
||
221 | */ |
||
222 | 1 | public function isReal($num): bool |
|
226 | |||
227 | /** |
||
228 | * @param $num |
||
229 | * @return bool |
||
230 | * @throws \InvalidArgumentException |
||
231 | */ |
||
232 | 2 | public function isExact($num): bool |
|
238 | |||
239 | /** |
||
240 | * @param $num |
||
241 | * @return bool |
||
242 | * @throws \InvalidArgumentException |
||
243 | */ |
||
244 | 1 | public function isInexact($num): bool |
|
248 | |||
249 | /** |
||
250 | * @param $num |
||
251 | * @return bool |
||
252 | * @throws \InvalidArgumentException |
||
253 | */ |
||
254 | 1 | public function isZero($num): bool |
|
260 | |||
261 | /** |
||
262 | * @param $num |
||
263 | * @return bool |
||
264 | * @throws \InvalidArgumentException |
||
265 | */ |
||
266 | 2 | public function isPositive($num): bool |
|
272 | |||
273 | /** |
||
274 | * @param $num |
||
275 | * @return bool |
||
276 | * @throws \InvalidArgumentException |
||
277 | */ |
||
278 | 1 | public function isNegative($num): bool |
|
282 | |||
283 | /** |
||
284 | * @param $num |
||
285 | * @return bool |
||
286 | * @throws \InvalidArgumentException |
||
287 | */ |
||
288 | 2 | public function isOdd($num): bool |
|
294 | |||
295 | /** |
||
296 | * @param $num |
||
297 | * @return bool |
||
298 | * @throws \InvalidArgumentException |
||
299 | */ |
||
300 | 1 | public function isEven($num): bool |
|
304 | |||
305 | /** |
||
306 | * @param int[]|float[] ...$args |
||
307 | * @return int|float |
||
308 | * @throws \InvalidArgumentException |
||
309 | */ |
||
310 | 1 | public function max(...$args) |
|
316 | |||
317 | /** |
||
318 | * @param int[]|float[] ...$args |
||
319 | * @return int|float |
||
320 | * @throws \InvalidArgumentException |
||
321 | */ |
||
322 | 1 | public function min(...$args) |
|
328 | |||
329 | /** |
||
330 | * @param int|float $arg |
||
331 | * @return int|float |
||
332 | */ |
||
333 | 1 | public function abs($arg) |
|
339 | |||
340 | /** |
||
341 | * Used as the callback to array_reduce, with the "carry" argument being the predicate to enforce |
||
342 | * |
||
343 | * @param callable $pred |
||
344 | * @param $thingToCheck |
||
345 | * @return callable |
||
346 | * @throws \InvalidArgumentException |
||
347 | * @SuppressWarnings(PHPMD.UnusedPrivateMethod) |
||
348 | */ |
||
349 | 19 | private function enforcePredicate(callable $pred, $thingToCheck): callable |
|
357 | } |
||
358 |
This check looks from parameters that have been defined for a function or method, but which are not used in the method body.