Je ArrayHash omyl? … Předmět nesmí být kratší než 25 znaků
- Filip Procházka
- Moderator | 4668
Ahoj, chtěl bych se zeptat…
- na co je dobrý
ArrayHash
? - proč mám pocit, že když už byl využit v
Nette\Database
, tak byl vnucen i formulářům, kterým tím totálně zničil jakoukoliv zpětnou kompatibilitu, jen aby byl použit i někde jinde? - proč je vnucen do
$container->params
?
Opravdu v něm nevidím nic užitečného, naopak přináší spoustu problémů s přetypováním a přepisováním hromady kódu, „jenom aby to byl objekt“.
Pokud to je nějaký princip čistoty, tak se mi vůbec nelíbí.
Nerad bych, aby to vyznělo, že teď David musí bránit
ArrayHash
, protože se mně nelíbí (a spoustě
dalších lidí činí velké problémy), ale opravdu bych rád znal alespoň
nějaké výhody při použití ve formulářích a contextu (kromě
voňavějšího zápisu $context->params->database
vs
$context->params['database']
).
PS: dost mi tam chybí metoda toArray
, proč tam není? Má
význam posílat pull?
- Filip Procházka
- Moderator | 4668
Páááni, nevěděl jsem že (array)
umí
ArrayHash
přetypovat rekurzivně? :)) Díky, problém
vyřešen!
Počkat… vlastně neumí, jiné nápady?
PS: Je veselé jak mi okamžitě třemi různými kanály začali radit lidé, s tou největší pitomostí, která je z toho příspěvku úplně nejméně podstatná…
Editoval HosipLan (30. 6. 2011 9:07)
- Filip Procházka
- Moderator | 4668
To je pěkné :) asi tu poslední větu umažu… To si opravdu myslíte, že si to neumím přetypovat?
@**xxxObiWan**: fungují
@**Tharos**, @**Patrik Votoček**:
$data = ArrayHash::from($array);
$model->method($data);
$data = (object)$array;
$model->method($data);
Neskutečnej rozdíl ;)
Nefungují php funkce, rozbilo nám to snad všechny validace v systému, nemám jak dohledat, kde musím všechny validace opravit, jenom proto, že je to i ve formulářích. Všechno co se do teď změnilo ve dvojce bylo úplně v pohodě, až na tohle. Tohle je neskutečný porod přemigrovat.
Takže ptám se, znovu.
Jaké má výhody ArrayHash
? Kromě toho, že mi umí pole
přetypovat rekurzivně, což jsem ještě nikdy nepotřeboval a neumí ho
přetypovat zpátky rekurzivně, což bych ocenil.
A už mi prosím neraďte jak se přetypovává objekt… diky
- JakubJarabica
- Gold Partner | 184
@Hosiplan: Co sa tyka formularov, nenapadlo ta prepisat getValues aby vracala uz pretypovane udaje?
- Patrik Votoček
- Člen | 2221
HosipLan napsal(a):
Páááni, nevěděl jsem že
(array)
umíArrayHash
přetypovat rekurzivně? :)) Díky, problém vyřešen!Počkat… vlastně neumí, jiné nápady?
Sorry ale v tomhle se ta ironie fakt blbě hledá!
(str_replace("? :)) Díky, problém vyřešen!", "! :))", ...)
)
Neskutečnej rozdíl ;)
Přesně tak! A o ten rozdíl jde! :-)
… že je to i ve formulářích. Všechno co se do teď změnilo ve dvojce bylo úplně v pohodě, až na tohle.
Počkat ale formuláře ArrayHash používají už nevím jak dlouho… :-) (a neříkej že zrovna ty jedeš na 0.9.x).
- Filip Procházka
- Moderator | 4668
@**JAM3SoN**: Konstruktivní nápad, díky! Jenom je blbé, že bych toho musel měnit poněkud více. Kontejnery, vlastni formulářové prvky, … ale dobrý nápad, díky!
@**Patrik Votoček**: Ja ne, firma ano. Ale o to nejde, to se prostě přepíše a odladí.
Jenom jsem se ale do teď pořád od nikoho nedozvěděl, co mi přinesl
ArrayHash
užitečného.
PS: Všimněte si prosím, že příspěvek je v obecné diskuzi, ne v bug reportech nebo feature requestech!
Editoval HosipLan (30. 6. 2011 12:10)
- Tharos
- Člen | 1030
@HosipLan: Zvolil jsi příklad koulervoucí :)
(využívající ArrayHash::from
s předáním již existujícího
pole). Teď si vem následující kódy:
$collection = array();
$collection[1] = 'foo';
$collection[2] = 'bar';
$this->doSomethingUsefull((object) $collection);
$collection = new Nette\ArrayHash;
$collection[1] = 'foo';
$collection[2] = 'bar';
$this->doSomethingUsefull($collection);
Osobně bych pro lepší čitelnost volil druhou variantu.
- Filip Procházka
- Moderator | 4668
To je ale tvůj subjektivní názor, a podle mě to dost záleží na konkrétním use-case a v čitelnosti nevidím rozdíl.
Když budu chtít pracovat s daty, které jsou logicky seznam, pak budu psát.
$list = array();
$list[] = 'a';
$model->method($list);
když budu pracovat s asociativním polem, tak podle zvyku
$assoc = array();
$assoc['a'] = 'b';
$model->method($list);
když budu mít potřebu, to mít jako objekt…
$o = (object)NULL;
$o = (object)array();
$o = new stdClass; // tohle se mi nevímproč nelíbí
$o = new ArrayCollection();
$o = new MojeTrida();
$o->klic = 'neco';
$model->method($o);
echo $o->klic; // očekávám nějakou případnou modifikaci
Pokud tam nemáš ohromne megabajty, tak se ti nemůže vyplatit to předávat objektem…
Také bych upozornil všechny na Davidův článek Černá magie optimalizace, který mimo jiné říká, že když předanou hodnotu nezměním, pak stále ukazuje na stejnou fyzickou hodnotu v paměti a jenom přibývají ukazatelé.
Takže v 87%
případů, jenom zkontroluji hodnoty a uložím do databáze (když
nepočítám převádění na DateTime
a pod drobnosti)
Jo a taky mi ptáček cvrlikáček našeptal, že Davídek se kdysi
rozčiloval jak ArrayObject
a podobné nejdou protahovat PHP
funkcemi array_*
, takže tohle by mě taky zajímalo, proč změnil názor.
PS: Prej to ženu zlým tónem, takže se dyštak omlouvám, já nejsem zlej.. jenom možná trochu nevyspalej :)
edit: něco o hash mapách k tématu: http://pastebin.com/82uwyqEi
Editoval HosipLan (30. 6. 2011 13:38)
- David Grudl
- Nette Core | 8228
V prvé řadě bych poprosil snížit míru ironie, jinak se nedomluvíme.
Anonymní objekt (tj. objekt třídy stdClass) je v PHP v podstatě
zbytečná věc, protože tu máme vícefunkční
pole. Nicméně anonymní objekt má výhodu příjemnější syntaxe
$val->item
místo $val['item']
a zároveň určité
odlišnosti oproti poli: předává se referencí, má jiný přístup
k číselným hodnotám, zakazuje prázdné klíče a taky klíče obsahující
\x00
. Nejde tedy jen o syntaktickou úsporu dvou znaků, ale má
to určitý filosofický přesah. Prostě to není pole.
ArrayHash je nadstavbou nad anonymním objektem stdClass, přidávající
možnost volat count()
a používat hranaté závorky pro přístup
k prvkům. Proč?
$obj = (object) array('a' => 1, 'b' => 2);
count($obj); // poněkud překvapivě vrací 1
echo $obj->$a; // ten dolar vypadá spíš jako bug...
echo $obj[$a]; // teď je jasné, že dolar je tam schválně
Vedlejším efektem pak je, že ArrayHash při přímém přístupu k prvkům funguje i tam, kde se očekává pole.
Problém ale vzniká u vícerozměrných struktur. Zatímco
$a['b']['c'] = 'x'
vytvoří vícerozměrné pole v poklidu, tak
$a->b->c = 'x'
vyhodí notice (v PHP 5.4 dokonce Warning).
Pokud by $a
byl ArrayHash, tak to vyhodí Notice: Indirect
modification of overloaded a struktura se vůbec nevytvoří.
Z toho důvodu je vhodné používat anonymní objekty buď jako read-only nebo jako jednorozměrné struktury. Tohle se mi jevilo splněné v případě formulářů (1. případ) a databází (1. + 2. případ).
Původně i v případě $container->params
, jenže tehdy
jsem nepočítal s používáním vícerozměrných parametrů. Dnes bych
u kontejnerů ArrayHash jednoznačně zrušil, bylo by to ovšem za cenu
velkého BC breaku.
- Filip Procházka
- Moderator | 4668
Ok, omlouvám se za tu ironii, pár věcí mě kapku dožralo po ránu.
Use-case: ve firmě máme formuláře více rozměrné (klidně i 3–4
zanoření) a není to chyba návrhu, prostě je to potřeba, je to vysoce
komponentové. Máme potomky Forms\Container
snad na všechno a
skládáme to pak dohromady. Občas je potřeba tuhle něco sečíst, tuhle
něco prohnat tímhle… a
$form->values['neco'] + $form->values['neco2']
a další
v takových případech odmítají fungovat po upgradu, což je dost velký BC
break (respektive byl, hodně týdnů zpátky :).
V těch parametrech v Container
u a v
Nette\Database
to chápu, je to přecejenom něco „nového“
hodí se to víc a navíc to nebylo v žádných aplikacích už použito. Ale
blbé je, že ty formuláře jsou v hodně aplikacích a počítají s poly.
Teď otázka kolik lidí už přemigrovalo z 0.9
a pro koho to
budou BC breaky (tipuju že hodně). V těch formulářích mi to dost vadí,
všude dopisovat (array)
a přetypovávat není pěkné.
Otázka je, co ty si o tom myslíš v těch formulářích. A jestli si myslíš, že má význam to dávat z formulářů pryč.
No a taky díky za příspěvek co mi neradil jak přetypovávat objekt, ale odpověděl mi na to, na co jsem se ptal :)
edit: Kontejner sem, kontejner tam. Já o formulářích ty o contextu :)) Trošku se ztrácím
Editoval HosipLan (30. 6. 2011 15:57)
- David Grudl
- Nette Core | 8228
HosipLan napsal(a):
edit: Kontejner sem, kontejner tam. Já o formulářích ty o contextu :)) Trošku se ztrácím
V prvním příspěvku o kontejnerech nepíšeš?