News in Nette Utils 3.2

6 months ago by David Grudl     edit

One of the main new features of Nette Utils 3.2 is the new static class Nette\Utils\Floats with useful functions for comparing decimal numbers.

The class solves a problem that surprised many programmers when they found that equality does not apply for 0.1 + 0.2 == 0.3. In mathematical operations with decimal numbers, errors occur due to the conversion between the decimal and binary systems. Therefore, when comparing floats, we must tolerate a small difference from a certain decimal place. And that's what the Floats class is doing.

The following comparison will work as expected:

Floats::areEqual(0.1 + 0.2, 0.3) // returns true

In addition to this method, the class offers a number of other useful functions.

Image

Class Nette\Utils\Image has two new methods for image type detection detectTypeFromFile() and detectTypeFromString():

$type = Image::detectTypeFromFile('image/logo.gif'); // returns Image::GIF

Arrays

Surprisingly, PHP does not have functions (without side effects) to return the first or last element in an array, so functions first() and last() were created in Nette\Utils\Arrays. If the array is empty, it returns null:

Arrays::first([1, 2, 3]); // 1
Arrays::last([1, 2, 3]);  // 3
Arrays::first([]);        // null

The contains() searches for elements in with strict comparison:

Arrays::contains([1, 2, 3], 1);    // true
Arrays::contains(['1', false], 1); // false

Finally, we have a method for invoking all callbacks in an array:

$callbacks = [
	'+' => function ($a, $b) { return $a + $b; },
	'*' => function ($a, $b) { return $a * $b; },
];

$array = Arrays::invoke($callbacks, 5, 11);
// $array = ['+' => 16, '*' => 55];

And to call a method on each object in the array:

$objects = ['a' => $obj1, 'b' => $obj2];

$array = Arrays::invokeMethod($objects, 'foo', 1, 2);
// $array = ['a' => $obj1->foo(1, 2), 'b' => $obj2->foo(1, 2)];

Reflection

The union types in PHP 8 requested the addition of new methods getReturnTypes(), getParameterTypes() and getPropertyTypes() in class Nette\Utils\Reflection, which return array of (normalized) types, see documentation . If older methods getParameterType(), getReturnType() or getPropertyType() encounter a union type, they throw an exception (in older version 3.0 they return null for compatibility).

Clarity

Nette gradually leaves the prefix I in the interface names, so these changes have taken place:

  • Nette\Localization\ITranslatorNette\Localization\Translator
  • Nette\Utils\IHtmlStringNette\HtmlStringable (to correspond to Stringable in PHP).

The name of the method Nette\Utils\Arrays::searchKey() is changed to more precise getKeyOffset().

Of course, the original names still work as aliases.