
Funkce pro práci s čísly budu ukládat do knihovny nm_Util – logické místo pro všechny nm_
funkce. Každá funkce bude interně rozvětvovat kód pro PHP a JavaScript pomocí CombiScriptového přepínače. A samozřejmě – budeme dodržovat striktní režim a kontrolu typů.
Začneme funkcí nm_IsNumber
- základní cihlou pro všechny další operace. V JavaScriptu využijeme typeof. V PHP existují dva číselné typy float a int a proto pro detekci použijeme pro to určené funkce is_int a is_float samozřejmě s operátorem OR. Výsledná funkce bude vypadat takto:
- <!-- --><?php /*
- "use strict";
- //*/
- function nm_IsNumber($num)
- {
- 0&&0<!--$_;/*
- return typeof $num === 'number';
- /*/
- return is_int($num) OR is_float($num);
- //*/
- }
Jako další bychom si chtěli vytvořit funkci vracející absolutní hodnotu čísla. Pro PHP použijeme abs a pro JS použijeme Math.abs
- function nm_Abs($num)
- {
- 0&&0<!--$_;/*
- return Math.abs($num);
- /*/
- return abs($num);
- //*/
- }
U funkce nm_Abs
se na chvíli zastavíme – protože tady poprvé narazíme na jeden z principů CombiScriptu: striktní kontrola typů a strojově čitelné chyby
Funkce nesmí dělat automatické přetypování – to by v PHP a JS vedlo k odlišným výsledkům. Místo toho – při chybném vstupu vyhodí výjimku
.A tady přichází další princip: Chybový kód musí být strojově zpracovatelný. Nesnáším chyby ve stylu „Duplicate entry 'abc' for key 'xyz'“, kde si musím parametry „vyparsovat“. (a pak mu někdo přepne SQL engine do češtiny a parsování zkolabuje).
Funkce s kódem volajícím výjimku by podle mne měla vypadat nějak takto:
- function nm_Abs($num)
- {
- if (!nm_IsNumber($num)) throw new cs_Error('nm_Abs-$num-NotNumber', [cs_Type($num)]);
- 0&&0<!--$_;/*
- return Math.abs($num);
- /*/
- return abs($num);
- //*/
- }
Kde cs_Error
je třída výjimky a cs_Type
je funkce vracející typ proměnné. Zároveň je vidět jak budu konstruovat chybové kódy výjimek. Odděluji znakem "-", jako první uvádím název funkce, kde chyba nastala, jako další v jakém parametru a jako další typ chyby, kde používám PascalCase (Upper-CamelCase) syntaxi.
Pokračujeme funkcí nm_Sign
. JavaScript má Math.sign(), PHP ne – tak si ji napíšeme sami. A můj oblíbený trik? ($num > 0) - ($num < 0)
. Elegantní, rychlé, a krásně ukazuje, jak boolean hodnoty v PHP fungují pod kapotou. (Ano, true - true = 0, true - false = 1, false - true = -1 – tohle je ta „magie“, kterou mám rád :-))
- function nm_Sign($num)
- {
- if (!nm_IsNumber($num)) throw new cs_Error('nm_Sign-$num-NotNumber', [cs_Type($num)]);
- 0&&0<!--$_;/*
- return Math.sign($num);
- /*/
- return ($num > 0) - ($num < 0);
- //*/
- }
A nakonec přidáme funkci nm_IsAsInt
. V této funkci budeme kontrolovat zda se nějaké číslo "tváří" jako celé. V JS toto zjistit není problém, má na to přímo funkci Number.isInteger($num)
. V PHP docílíme stejné funkčnosti odříznutím desetinné části a porovnáním.
- function nm_IsAsInt($num)
- {
- 0&&0<!--$_;/*
- return Number.isInteger($num);
- /*/
- if (is_int($num)) return true;
- return (is_float($num) && floor($num) === $num);
- //*/
- }
Nyní si celou naši knihovnu můžeme shrnout:
- <!-- --><?php /*
- "use strict";
- //*/
- function nm_IsNumber($num)
- {
- 0&&0<!--$_;/*
- return typeof $num === 'number'
- /*/
- return is_int($num) OR is_float($num);
- //*/
- }
- function nm_Abs($num)
- {
- if (!nm_IsNumber($num)) throw new cs_Error('nm_Abs-$num-NotNumber', [cs_Type($num)]);
- 0&&0<!--$_;/*
- return Math.abs($num);
- /*/
- return abs($num);
- //*/
- }
- function nm_Sign($num)
- {
- if (!nm_IsNumber($num)) throw new cs_Error('nm_Sign-$num-NotNumber', [cs_Type($num)]);
- 0&&0<!--$_;/*
- return Math.sign($num);
- /*/
- return ($num > 0) - ($num < 0);
- //*/
- }
- function nm_IsAsInt($num)
- {
- 0&&0<!--$_;/*
- return Number.isInteger($num);
- /*/
- if (is_int($num)) return true;
- return (is_float($num) && floor($num) === $num);
- //*/
- }
Tvorbu nm_Util tady na chvíli přerušíme. Příště se přijde čas na cs_Util a cs_Error
, která nese nejen zprávu, ale i strukturované parametry- což není u výjimek zcela běžné a může se Vám to hodit i v čistém PHP nebo JS.