Jak rozjet h4kuna\Exchange – chybí service?
- Phalanx
- Člen | 310
Ahoj, snažím se rozjet už nějakou chvíli h4kuna\Exchange ale bohužel se mi nedaří.
config.neon mám stejně jako tady:
https://github.com/h4kuna/exchange
A následně v Homepage.php presenteru
<?php
/* @var \h4kuna\Exchange\Exchange @inject */
public $exchange;
public function renderDefault()
{
Debugger::dump($this->exchange); // NULL
}
?>
Zkoušel jsem i zaregistrovat service za pomocí
https://forum.nette.org/…i-presenteru
ale tady mi to píše chybu
Class \h4kuna\Exchange\Storage\IWarehouse used in service ‚eStorage‘ not
found or is not instantiable
Rád bych pak nechal uživatele vybrat měnu, uložit do cookies a vypisovat v šabloně podle měny v cookie.
Děkuju za každou radu, už se s tím mořím dlouho.
- Šaman
- Člen | 2666
Tohle není o vytváření servis, ale taková specialitka, jak je rychle
předat do presenteru. Služba je již vytvořená v DI kontejneru (to
zajistíš zápisem do configu).
Abys ji do presenteru nemusel předávat konstruktorem, jako když ji
předáváš kamkoliv jinam. Proto nakonec vznikl akademicky velmi špatný,
zato jednoduchý a návykový způsob – anotace @inject.
Ale anotace není obyčejný komentář, anotace vychází z PhpDoc
syntaxe.
Na tuhle dvě hvězdičky si dávej pozor, na ně občas narazíš a
i když je to technicky komentář, prakticky jsou anotace součástí
kódu. Dále zajišťují napovídání v IDE, potkáš je
v Doctrině apod.
Trocha historie jak se k tomuto řešení došlo a hlavně vysvětlení
proč v konstruktorech nepoužívat předávání konstruktorem najdeš
tady. Jen pozor – odkazovaný článek je starý a to co on popisuje
NENÍ anotace inejct, ale jen její ideový předchůdce. Technicky však on
používá magii (zapisuje do private property), zatímco anotace inject je
normální property injection – závislost se zapíše do public property a
anotace jen řeknou, že se to má provést (@inject
) a o jaká
služba se má předat (@var
).
P.S. Presentery už nejsou opuchlé hromádky kódu, konstruktor nyní mají prázdný a proto se do koncovch presenterů doporučuje předávat povinné závislosti konstruktorem (nikoliv však do abstraktních BasePresenterů jinak vznikne popisovaný konstructor-hell). Takže věta od @FilipProcházka „Ale stále – jediný důvod proč to dělám je, že presentery jsou opuchlé boule kódu.“ je jen alibi, které už neplatí. Ale programátor je tvor líný, tak se dodnes anotace používá i tam, kde to není potřeba :D
Editoval Šaman (2. 12. 2015 20:44)
- Pavel Kravčík
- Člen | 1196
Netbeans hvězdičkové peklo:
/* @var $item \App\ArticleEntity */
foreach($list as $item)
{
$item-> //napovídá
}
/** @var $item \App\ArticleEntity */
foreach($list as $item)
{
$item-> //nenapovídá
}
/** @var \App\ArticleEntity $item */
foreach($list as $item)
{
$item-> //nenapovídá
}
/**
* @inject
* @var \App\ArticleModel
*/
public $Model; //injectuje
/*
* @inject
* @var \App\ArticleModel
*/
public $Model; //neinjectuje
Rozšířil jsem ještě o třetí příklad a upravil
private `na `public
. Anotace ve správném pořadí
nenapovídá.
Editoval Pavel Kravčík (3. 12. 2015 12:47)
- Šaman
- Člen | 2666
Pavel Kravčík napsal(a):
Netbeans hvězdičkové peklo:
/* @var $item \App\ArticleEntity */ foreach($list as $item) { $item-> //napovídá } /** @var $item \App\ArticleEntity */ foreach($list as $item) { $item-> //nenapovídá } /** * @inject * @var \App\ArticleModel */ private $Model; //injectuje /* * @inject * @var \App\ArticleModel */ private $Model; //neinjectuje
- To, že neinjectuje je jasné, jedna hvězdička anotaci nedělá. Pozor na ty private property, do těch to neinjectuje nikdy! (3. příklad takhle fungovat nebude.) Nicméně napovídání ve 3. a 4. příkladu funguje správně (ve třetím napovídá, ve čtrvtém ne.)
- První příklad je nějaká NetBeans divočina a slouží JEN
k napovídání. Sice napovídá, ale není to ani anotace (jedna hvězdička)
a i pokud by to anotace byla, tak má špatný formát. Formát anotace
je
/** @var type $varName comment */
- Druhý příklad, pokud by byl ve tvaru
/** @var \App\ArticleEntity $item */
tak by imho napovídat mohl, ale nedělá to. Nicméně tyhle pomocné definice typu uprostřed kódu jsou vzácné a v phpDoc se o nich vůbec nemluví. PhpDoc mluví o definici typu třídní property a to funguje správně (3. a 4.).
Resume: Doporučuji si v NetBeans trochu zvýraznit anotace (teď je píše
tučně, mám to nastavené i na trochu tmavší barvu ať jsou na první
pohled výrazné), pak se omezí nebezpečí zapomenuté hvězdičky – je na
první pohled vidět, jestli je to jen šedý kus komentáře, nebo v něm jsou
zvýrazněny @anotace
.
Pak, pokud se používají jen anotace podle dokumentace (tj. anotační blok popisující třídu, metodu, nebo property), tak to všechno funguje správně.
Případ jedna je výjimka, jinak nikdy jedna hvězdička nic nedělá. A i ten případ 1 by měl jít bez nebezpečí odmazat (pravé anotace se naopak často odmazat nesmí) a ani v prvním případě NetBeans tu pseudo anotaci nezvýrazní, takže jasně naznačuje, že to anotace není.
Editoval Šaman (3. 12. 2015 11:28)
- Pavel Kravčík
- Člen | 1196
@Šaman: Máš pravdu, ty private jsou hrozný nesmysl. :) Psal jsem to jen tak na koleni rychle z hlavy. Já se v tom orientuji dobře a nikdy se mi nestalo, že by mi tam chyběla.
Spíš jsem tyhle věci sepsal do nějaké dokumentace a ukázal to dvěma externistům, kteří se zaučují. A pro ně je to hvězdičkové peklo. Plus ještě otočení variableName className za className variableName. Moje pointa spíš byla, že pro začátečníka je tohle strašně neintuitivní.
Ale pěkný komentář!
Ještě k netbeans divočině – to je strašně cool feature, hlavně pro kolekci entit. Takže to používám relativně často a chtěl jsem to předat dále, protože hlavně externisté nemají povědomí o všech 80ti entitách.
Editoval Pavel Kravčík (3. 12. 2015 12:35)
- CZechBoY
- Člen | 3608
@PavelKravčík v phpstormu je ta syntaxe otočená
/** @var Entity $a */
foreach ($asdf as $a) {
}
- Šaman
- Člen | 2666
@PavelKravčík: Já bych je ten případ jedna raději ani neučil a jako zlaté pravidlo dal:
- Jedna hvězdička je obyčejný komentář. Nic nedělá, z funkčniho hlediska je možné ho vymazat.
- Dvě hvězdičky jsou blok PhpDoc dokumentace a ten může
obsahovat
@anotace
. Anotace v Nette a jiných (Doctrině, LeanMapperu, …) mohou obsahovat část aplikační logiky a není možné je smazat (a je nutné hlídat, že jsou ve dvou hvězdičkách). Podle anotací také umí NetBeans a PhpStorm (a možná i další) napovídat. Oba tyto editory také anotace zvýrazňují.
- Jen v NetBeans je výjimka – neumí napovídat podle anotací lokálních proměnných. Ty se většinou ani neanotují, protože nejsou součástí rozhraní. (Bod jedna bych je ani neučil, protože to stejně nebude fungovat v jiném editoru a možná ani v budoucích verzích NetBeans, protože bod jedna není opřený o žádnou specifikaci, nebo RFC.)
Editoval Šaman (3. 12. 2015 14:07)
- h4kuna
- Backer | 740
Já potřebuji nějak v dokumentaci říct co je v proměnný za objekt. Jak se k tomu objektu dostanu je na mě. Jestli si ho vytáhnu přes Container. Nebo inject do presenteru nebo přes konstruktor třídy. Prostě je hodně případů které nechci rozepisovat v dokumentaci, proto se vyrojil nápad napsat to komentářem co znám z netbeansu.
phpDoc je definovaný dvěma hvězdičkami a abych mohl použít anotace tak musím zapsat phpDoc. @inject je anotace. Mě to přijde jasný.
Editoval h4kuna (3. 12. 2015 15:15)
- Pavel Kravčík
- Člen | 1196
@Šaman: Ano, přesně takhle. :) Jedna hvězdička napovídání je prostě takový sugar navíc, snadno se to pak z kódu dá odstranit pomocí hledání `/* `.
@h4kuna: Tak prakticky všem to přijde jasné. Ale někomu, kdo anotace vidí poprvé v životě a ani nechápe princip DI a Netbeans jsou jeho první IDE to jasné opravdu není. :)
- CZechBoY
- Člen | 3608
Já bych možná přidal nápovědu/suggestion pro chybu, že nejde provést
operaci nad NULL.
Stejně každý z nás má zafixováno, že NULL v objektu ⇒ zapomněl jsem
na 99% přidat anotaci/inject.
ps. alespoň v presenterech, kde se inject volání děje defaultně.
Editoval CZechBoY (3. 12. 2015 15:30)