
A funkce prefixované nm_ uložím logicky do knihovny nm_Util. Knihovnu začneme již definovanou ošetřenou hlavičkou pro PHP včetně zapnutí strict módu pro javascript. V jednotlivých funkcích budu používat pro rozvětvení JS a PHP kódu již dříve definovaný CombiScriptový přepínač.
A jako první si vytvoříme funkci nm_IsNumber
, která nám ověří zda v proměnné je číslo. Pro JS použijeme klasickou konstrukci 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);
- //*/
- }
Ovšem u této funkce se na chvilku zastavíme. V definici jazyka jsme se shodli, že bude striktně kontrolovat typy. A funkce nm_Abs
by měla vracet absolutní hodnotu jen čísel, bez automatického přetypování, které by v každém jazyce dopadlo jinak. Dál jsme říkali, že při chybném vstupu funkce budeme vyhazovat výjimku.
Teď je otázka jaký by měl být obsah této výjimky. Preferuji, aby výjimka šla snadno strojově zpracovat - teprve potom lidsky číst. Měla by obsahovat jasný kód a parametry s podrobnostmi. Opravdu nesnáším výjimky (či SQL error kódy) ve tvaru "Duplicate entry abc for key xyz", kde si programátor musí parametry "abc" a "xyz" vyparsovat (a pak mu někdo přepne SQL engine do češtiny).
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.
Dále si stejným způsobem naprogramujeme funkci nm_Sign
. Pro JS můžeme využít Math.sign PHP funkci sign nemá. Musíme si jí naprogramovat sami. Jako nejhezčí algoritmus se mi jeví rozdíl mezi boolean hodnotami :-) konstatujících zde je číslo větší a menší než nula.
- 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_AsInt
. 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 pustíme do knihovny cs_Util
, kde vznikne třída cs_Error
. Ta bude umět přijímat více parametrů - což není u výjimek zcela běžné a může se Vám to hodit i v čistém PHP nebo JS.