Jak rozjet h4kuna\Exchange – chybí service?

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
Phalanx
Člen | 310
+
0
-

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.

Myiyk
Člen | 321
+
0
-

Ten doplněk neznám,
ale podle názvu objektu \h4kuna\Exchange\Storage\IWarehouse to vypadá, že se snažíš zaregistrovat interface jako službu.

To velké I na začátku IWarehouse nejspíš znamená, že to je interface.

Myiyk
Člen | 321
+
+2
-

Možná je chyba v

/* @var \h4kuna\Exchange\Exchange @inject */

dokumentační komentář anotace musí začítat /**, tedy

/** @var \h4kuna\Exchange\Exchange @inject */

Editoval Myiyk (2. 12. 2015 21:28)

Phalanx
Člen | 310
+
0
-

Bylo to hvězdičkou… Díky moc! Hledal jsem v tom složitosti, protože úplně nerozumím vytváření servis

Šaman
Člen | 2666
+
+2
-

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)

h4kuna
Backer | 740
+
+2
-

Dokumentace opravena.

Pavel Kravčík
Člen | 1196
+
0
-

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
+
+1
-

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
+
0
-

@Š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
+
0
-

@PavelKravčík v phpstormu je ta syntaxe otočená

/** @var Entity $a */
foreach ($asdf as $a) {
}

http://phpdoc.org/…ags/var.html

Pavel Kravčík
Člen | 1196
+
0
-

@CZechBoY: Ano, to Šaman psal. Protože je to anotace a ne komentář.

Šaman
Člen | 2666
+
0
-

@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
+
0
-

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
+
0
-

@Š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í. :)

Oli
Člen | 1215
+
0
-

@Šaman v PHPStormu funguje napovídání lokálních proměnných stejně. Z funkčního hlediska je to komentář a může se smazat. Ale napovídá a to se počítá. Takže proč to nevyužít? ;-) Může se tomu třeba říkat standardizovaný komentář…

CZechBoY
Člen | 3608
+
0
-

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)