Jmenné prostory – Last Call Announcement

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
David Grudl
Nette Core | 8218
+
0
-

Dnes proběhne velký třesk a dojde k úpravě jmenných prostorů ve frameworku. Změna se týká skutečně velkého počtu tříd. Je jasné, že přejmenovávání nepatří mezi populární úpravy, nicméně přechod by měl být bezbolestný.

Důvody

Nette Framework je dost možná prvním PHP frameworkem na světě, který používání jmenných prostorů zavedl. Kvůli prodlevám s vydáním PHP 5.3 se začaly v praxi používat docela pozdě a tudíž mají stále svou první a dnes již historickou podobu. Ta neodpovídá současnému stavu frameworku a před vydáním klíčové verze 2.0 je záhodno ji upravit.

Zpětná kompatibilita

Úpravy se týkají pouze verze pro PHP 5.3, ve verzích pro 5.2 k žádným změnám nedojde. Rozevírají se tím sice nůžky mezi 5.3 a 5.2 verzemi, nicméně podpora 5.2 stejně časem skončí.

Ve verzi pro 5.3 bude zajištěna 100% zpětná kompatibilita. Při použití starého názvu třídy se bude jen emitovat hláška úrovně E_USER_DEPRECATED. Bude k dispozici nástroj Class-Updater, který detekuje použití starého názvu třídy ve vašem kódu a opraví je.

Pravidla pojmenování

Novou podobu názvů tříd jsem chtěl podřídit, jako v podstatě vše v Nette, pohodlí programátora. Jak ukázala řada diskusí, subjektivní požadavky mohou být rozporuplné. Pro někoho znamená pohodlí mít co nejkratší názvy tříd, pro jiného jsou to názvy co nejvíce popisné.

Najít nějaká formální pravidla není vůbec snadné, často je lepší rozhodovat citem, každopádně první pravidlo a další doporučení (v sestupné důležitosti) se dodržují:

a) třída musí mít výstižný název i bez uvedení jmenného prostoru

Název každé třídy i bez jmenného prostoru musí vystihovat její podstatu, tj. název musí obsahovat podmět. Příklady:

  • chybně: Nette\Application\Routers\Simple – nelze dovodit, že Simple je router
  • chybně: Nette\Application\Responses\Download – nelze dovodit, že Download je odpověď
  • chybně: Nette\Database\Drivers\MsSql – MsSql je název databáze
  • dobře: Nette\Database\Drivers\MsSqlDriver – už je jasné, že jde o driver pro MsSql
  • dobře: Nette\Forms\Controls\Button – pokud existuje jednoslovný výraz, je to ideální

(Výstižný pochopitelně musí být samotný název jmenného prostoru, výhodou je název kratší.)

b) bez zbytečných duplicit

Název třídy a název prostoru by neměly pokud možno duplicitně obsahovat stejnou informaci.

  • místo Nette\Latte\LatteFilter raději Nette\Latte\Filter
  • místo Nette\Http\HttpRequest raději Nette\Http\Request

Pak se i zjednodušuje používání use, stačí importovat celé use Nette\Http; a poté přistupovat k třídám přes Http\Request, Http\Response apod.

c) nezaměnitelnost tříd z více prostorů

Pokud se v kódu často používají vedle sebe dvě třídy z různých prostorů, nebo pokud mají mezi sebou jinou souvislost, neměly by mít stejný název. Jinými slovy, nemělo by být nutné používat AS v klauzuli USE.

d) závislosti
  • Třídy ze jmenného prostoru A\B by neměly mít závislost na třídy z prostoru A\B\C.
  • Pokud má třída ze jmenného prostoru A\B závislost na třídě ze jmenného prostoru A\C, neměla by žádná třída z A\C mít závislost na A\B

(Toho nebude však zcela docíleno pouhým přejmenováním)

e) nezařazené třídy

Primárním úkolem jmenných prostorů je zavést do frameworku pořádek a přehlednost, sjednotit logické celky, nikoliv třídy samoúčelně kategorizovat. Problém tak vzniká u tříd, které přirozeně nezapadají do žádného existujícího celku. Příkladem může být třída Finder, kterou lze smysluplně zařadit hned do několika jmenných prostorů:

  • Nette\Finder – „zapleveluje“ jmenný prostor Nette
  • Nette\Tools\Finder – přesun to Nette\Tools je spíš jen zametením předchozí situace pod koberec
  • Nette\Finder\Finder – samostatný jmenný prostor vede k nepěknému zdvojování názvů
  • Nette\FileSystem\Finder – srozumitelný název, výstižnější než samotné Nette\Finder
  • Nette\FileSystem\Tools\Finder – oproti předchozímu nic nepřináší, jen je delší

Totéž se týká celé řady dalších tříd, od Nette\Json přes Nette\Image po Nette\Object. Pro tyto třídy navíc platí, že se jejich název v kódu často používá. Z hlediska pohodlí programátora se pak jeví jako nejvýhodnější zůstat u jednoduchého prostoru Nette a uměle ho neprodlužovat.

f) sdružující jmenné prostory

Dalším případem jsou jmenné prostory sdružující např. různé implementace téhož rozhraní apod. Příklad:

  • Nette\Caching\Storages\FileStorage, MemcachedStorage, … – všechny úložiště v samostatném prostoru Nette\Caching\Storages

Sdružující namespace prodlužuje název, protože Storage nelze z názvu třídy zpravidla odstranit (pravidlo a) a tím pádem porušuje doporučení b). Význam namespace je tak čistě kategorizační. Výhodou je lepší orientace v API dokumentaci (téhož by však šlo dosáhnout jinak, např. anotací @package), možná i snazší dostupnost při použití plnohodnotných IDE. Sdružující jmenné prostory by se tedy měly používat co nejméně a rozvážně.

g) ohled na budoucí vývoj

Některé změny namespaces předjímají budoucí vývoj frameworku (Nette\Application\UI). Obdobně nedošlo ke změnám tam, kde se chystá jiná úprava (Nette\Forms).

h) třídy výjimek

Do jmenného prostoru Nette byly zahrnuty i výjimky.

Last Call Announcement

Pokud je zde někdo, kdo má jakékoliv konstruktivní připomínky, nechť promluví teď nebo ať mlčí navždy.

David Grudl
Nette Core | 8218
+
0
-

Nové jmenné prostory

Přehled všech tříd se změněným názvem:

  • bez prostoru
    • InvalidStateExceptionNette\InvalidStateException
    • NotImplementedExceptionNette\NotImplementedException
    • NotSupportedExceptionNette\NotSupportedException
    • DeprecatedExceptionNette\DeprecatedException
    • MemberAccessExceptionNette\MemberAccessException
    • FatalErrorExceptionNette\FatalErrorException
    • ArgumentOutOfRangeException (zrušeno)
  • Nette
    • IComponentNette\ComponentModel\IComponent
    • ComponentNette\ComponentModel\Component
    • IComponentContainerNette\ComponentModel\IContainer
    • ComponentContainerNette\ComponentModel\Container
    • AmbiguousServiceExceptionNette\DI\AmbiguousServiceException
    • IContextNette\DI\IContext
    • ContextNette\DI\Context
    • ConfiguratorNette\DI\Configurator
    • DebugNette\Diagnostics\Debugger
    • DebugPanelNette\Diagnostics\Panel
    • IDebugPanelNette\Diagnostics\IPanel
    • DebugHelpersNette\Diagnostics\Helpers
    • ITranslatorNette\Localization\ITranslator
    • SafeStreamNette\Utils\SafeStream
    • FinderNette\Utils\Finder
    • ArrayToolsNette\Utils\Arrays
    • JsonNette\Utils\Json
    • NeonNette\Utils\Neon
    • PaginatorNette\Utils\Paginator
    • StringNette\Utils\Strings
    • Tools → rozděleno do tříd Nette\DateTime Nette\Utils\CriticalSection Nette\Utils\MimeTypeDetector
    • CallbackFilterIteratorNette\Iterators\Filter
    • GenericRecursiveIteratorNette\Iterators\Recursor
    • InstanceFilterIteratorNette\Iterators\InstanceFilter
    • MapIteratorNette\Iterators\Mapper
    • RecursiveCallbackFilterIteratorNette\Iterators\RecursiveFilter
    • SmartCachingIteratorNette\Iterators\CachingIterator
  • Nette\Application
    • PresenterRequestNette\Application\Request
    • IPresenterResponseNette\Application\IResponse
    • DownloadResponseNette\Application\Responses\FileResponse
    • ForwardingResponseNette\Application\Responses\ForwardResponse
    • JsonResponseNette\Application\Responses\JsonResponse
    • RedirectingResponseNette\Application\Responses\RedirectResponse
    • RenderResponseNette\Application\Responses\TextResponse
    • CliRouterNette\Application\Routers\CliRouter
    • MultiRouterNette\Application\Routers\RouteList
    • RouteNette\Application\Routers\Route
    • SimpleRouterNette\Application\Routers\SimpleRouter
    • RoutingDebuggerNette\Application\Diagnostics\RoutingPanel
    • LinkNette\Application\UI\Link
    • IRenderableNette\Application\UI\IRenderable
    • ISignalReceiverNette\Application\UI\ISignalReceiver
    • IStatePersistentNette\Application\UI\IStatePersistent
    • IPartiallyRenderableNette\Application\UI\IPartiallyRenderable
    • PresenterNette\Application\UI\Presenter
    • PresenterComponentNette\Application\UI\PresenterComponent
    • PresenterComponentReflectionNette\Application\UI\PresenterComponentReflection
    • ControlNette\Application\UI\Control
    • AppFormNette\Application\UI\Form
    • BadSignalExceptionNette\Application\UI\BadSignalException
    • InvalidLinkExceptionNette\Application\UI\InvalidLinkException
  • Nette\Forms
    • ButtonNette\Forms\Controls\Button
    • CheckboxNette\Forms\Controls\Checkbox
    • FileUploadNette\Forms\Controls\UploadControl
    • FormControlNette\Forms\Controls\BaseControl
    • HiddenFieldNette\Forms\Controls\HiddenField
    • ImageButtonNette\Forms\Controls\ImageButton
    • MultiSelectBoxNette\Forms\Controls\MultiSelectBox
    • RadioListNette\Forms\Controls\RadioList
    • SelectBoxNette\Forms\Controls\SelectBox
    • SubmitButtonNette\Forms\Controls\SubmitButton
    • TextAreaNette\Forms\Controls\TextArea
    • TextBaseNette\Forms\Controls\TextBase
    • TextInputNette\Forms\Controls\TextInput
    • FormGroupNette\Forms\ControlGroup
    • FormContainerNette\Forms\Container
    • IFormControlNette\Forms\IControl
    • DefaultFormRendererNette\Forms\Rendering\DefaultFormRenderer
  • Nette\Caching
    • ICacheStorageNette\Caching\IStorage
    • DummyStorageNette\Caching\Storages\DevNullStorage
    • FileJournalNette\Caching\Storages\FileJournal
    • FileStorageNette\Caching\Storages\FileStorage
    • ICacheJournalNette\Caching\Storages\IJournal
    • MemcachedStorageNette\Caching\Storages\MemcachedStorage
    • MemoryStorageNette\Caching\Storages\MemoryStorage
  • Nette\Config
    • ConfigAdapterIniNette\Config\IniAdapter
    • ConfigAdapterNeonNette\Config\NeonAdapter
    • IConfigAdapterNette\Config\IAdapter
  • Nette\Database\Selector
    • GroupedTableSelectionNette\Database\Table\GroupedSelection
    • TableRowNette\Database\Table\ActiveRow
    • TableSelectionNette\Database\Table\Selection
  • Nette\Loaders
    • LimitedScopeNette\Utils\LimitedScope
  • Nette\Mail
    • MailNette\Mail\Message
    • MailMimePartNette\Mail\MimePart
  • Nette\Reflection
    • ClassReflectionNette\Reflection\ClassType
    • ExtensionReflectionNette\Reflection\Extension
    • FunctionReflectionNette\Reflection\GlobalFunction
    • MethodReflectionNette\Reflection\Method
    • ParameterReflectionNette\Reflection\Parameter
    • PropertyReflectionNette\Reflection\Property
  • Nette\Templates
    • LatteFilterNette\Latte\Engine
    • LatteMacrosNette\Latte\DefaultMacros
    • LatteExceptionNette\Latte\ParseException
    • CachingHelperNette\Caching\OutputHelper
    • TemplateExceptionNette\Templating\FilterException
    • TemplateCachestorageNette\Templating\PhpFileStorage
    • TemplateHelpersNette\Templating\DefaultHelpers
    • TemplateFilters → přesunuto do doplňků
  • Nette\Web
    • HtmlNette\Utils\Html
    • HttpContextNette\Http\Context
    • IHttpRequestNette\Http\IRequest
    • HttpRequestNette\Http\Request
    • IHttpResponseNette\Http\IResponse
    • HttpResponseNette\Http\Response
    • HttpRequestFactoryNette\Http\RequestFactory
    • HttpUploadedFileNette\Http\FileUpload
    • ISessionStorageNette\Http\ISessionStorage
    • SessionNette\Http\Session
    • SessionNamespaceNette\Http\SessionNamespace
    • UriNette\Http\Url
    • UriScriptNette\Http\UrlScript
    • IUserNette\Http\IUser
    • UserNette\Http\User
Lopo
Člen | 277
+
0
-

celkom by ma zaujimal dovod zrusenia ArgumentOutOfRangeException – kedze to mam pouzite v BailIff\Utils\Network::CIDR2LongRange()

Jan Tvrdík
Nette guru | 2595
+
0
-

Špatně vidím, nebo skutečně chybí IPresenter a BadRequestException? Navrhuji přejmenovat AppForm na Form (v souladu s 2. pravidlem). Dále mi pořád nesedí RoutingDebugger v Application, ale v praxi mi to nevadí, protože ho nikdy neinstancuji.

Teď koukám, že chybí také celé Nette\Forms. Mám to chápat tak, že tam dojde ke změnám zároveň s uvedením nových formulářů?

paranoiq
Člen | 392
+
0
-

Lopo

imo je příliš konkrétní a málo používaný. argument může být nevalidní z desítek důvodů. rozpitvávat jen jeden z nich není konzistentní

Jan Tvrdík

AppForm → Form není v souladu s pravidlem c)

David Grudl

pořád se mi nelíbí ta přílišná katalogizace, kvůli které pak porušuješ pravidlo b) (Responses\..Response, Routers\..Router, Helpers\..Helper). jmenné prostory nemusí kopírovat adresářovou strukturu. celé pravidlo f) považuji za špatné

zjednodušil (ponechal tak jak jsou teď) bych také všechny případy, kdy je jméno třídy až na čtvrté úrovni (Application\UI, Application\Diagnostics), ale netuším, jaký bude ‚budoucí vývoj‘ ohledně UI

název třídy Filter považuji za příliš obecný. narozdíl třeba od Request či Response, což jsou celkem zažité pojmy, neříká absoulutně nic o účelu třídy

Editoval paranoiq (5. 4. 2011 9:44)

Honza Marek
Člen | 1664
+
0
-

paranoiq napsal(a):

Jan Tvrdík

AppForm → Form není v souladu s pravidlem c)

Je… AppForm s třídou Form jsem vedle sebe ještě neviděl použít.

pravidlo f

Zdá se mi divné… Vyčleňovat třeba Routery kvůli tomu, že je jich hodně? Dává mi větší smysl prohlásit celé routování za samostatný celek a dát do něj všechno, co s ním souvisí. Např. Nette\Application\Routing\IRouter, ono toho víc nebude.

Neměl bych problém ani s namespacem Nette\Routing, které by odpovídalo i pravidlu d.

Nilp
Člen | 65
+
0
-

Katalogizace je skvělá, navrhuji ještě jmenné prostory Exception, zvláště Nette\ by to prospělo. Dále:

  • Templates\PhpFilesStorageTemplates\PhpFileStorage?
  • Application\UI\PresenterLinkApplication\UI\Link? (bude tam ještě nějaký další?)
  • Application\UI\AppFormApplication\UI\Form

Editoval Nilp (5. 4. 2011 11:00)

Vojtěch Dobeš
Gold Partner | 1316
+
0
-

PhpFileStorage do Templates patří, protože je implementací cachování šablon, ne? Viz původní název té třídy.

David Grudl
Nette Core | 8218
+
0
-

Předně: nechtěl bych tu startovat další nikamnevedoucíflame, takže prosím pište jen připomínky, které považujete za skutečně podstatné.

Lopo napsal(a):

celkom by ma zaujimal dovod zrusenia ArgumentOutOfRangeException – kedze to mam pouzite v BailIff\Utils\Network::CIDR2LongRange()

Framework ji nepoužívá tudíž si ji nemusí definovat. Přesunem do prostoru Nette už jde o soukromé výjimky frameworku.

Jan Tvrdík napsal(a):

Špatně vidím, nebo skutečně chybí IPresenter a BadRequestException

Nic se na nich nemění.

Navrhuji přejmenovat AppForm na Form (v souladu s 2. pravidlem).

Form extends Form může být pro začátečníky hodně matoucí.

paranoiq napsal(a):

pořád se mi nelíbí ta přílišná katalogizace, kvůli které pak porušuješ pravidlo b) (Responses\..Response, Routers\..Router, Helpers\..Helper).

Mě taky a je to vlastně poslední věc, o které bych ještě diskutoval :-)

celé pravidlo f) považuji za špatné

Třeba v případě Nette\Database\Drivers mi to vyloženě vyhovuje. „Úplně“ za špatné bych to neviděl.

Jan Tvrdík
Nette guru | 2595
+
0
-

class Form extends Nette\Forms\Form mi nepřijde nijak problematické.

Honza Marek
Člen | 1664
+
0
-

David Grudl napsal(a):

paranoiq napsal(a):

pořád se mi nelíbí ta přílišná katalogizace, kvůli které pak porušuješ pravidlo b) (Responses\..Response, Routers\..Router, Helpers\..Helper).

Mě taky a je to vlastně poslední věc, o které bych ještě diskutoval :-)

Máš moje svolení zbytečně nekatalogizovat :-D

bazo
Člen | 620
+
0
-

Nilp napsal(a):

Katalogizace je skvělá, navrhuji ještě jmenné prostory Exception, zvláště Nette\ by to prospělo.

tiez som za pridanie namespace Nette\Exceptions\, s vynimkami pracujem celkom casto a je treba si pamatat ich nazvy ked ich chcem vylovit, takto by som len napisal Nette\Exceptions\ stlacil ctrl+medzera a dostal by som zoznam vsetkych vynimiek. Cize podporuje to pohodlie programatora :)

Nox
Člen | 378
+
0
-

Ad b) vs a) není taky „Request“ nebo „Filter“ ne úplně 100% jasné? Vadila by ta duplicita moc? Není lepší duplicitní informace než potenciální nejednoznačnost?

Filip Procházka
Moderator | 4668
+
0
-

Nette\FinderNette\FileFinder ?

Vyki
Člen | 388
+
0
-

HosipLan napsal(a):

Nette\FinderNette\FileFinder ?

K tomu bych se připojil. Kdybych nevěděl k čemu třída Finder slouží, určitě by mě nenapadlo, že je to zrovna k procházení FS.

hrach
Člen | 1838
+
0
-

Jenže Finder bude ve FileSystem, tak je to jasný, ne?

Nox
Člen | 378
+
0
-

@**hrach**a) třída musí mít výstižný název i bez uvedení jmenného prostoru“ (s čímž souhlasim)

xificurk
Člen | 121
+
0
-

Osobně mi přijde hloupé pravidlo a), protože:

  1. Velmi často koliduje s doporučením b) a v předloženém seznamu změn je jednou upřednostněna výstižnost názvu a jindy neduplicita. Sice je pravidlo a) „jasně“ definované požadavkem na podmět, ale to do celého problému jen vnáší další pravidlo, které celkem nevhodně nastavuje hranici mezi a) a b). Typickým matoucím příkladem je Application\Responses\JsonResponse (vítězí a) vs. Http\Response (vítězí b)
  2. Pokud požadujeme „třída musí mít výstižný název i bez uvedení jmenného prostoru“, tak to člověka logicky vede k otázce – „A proč teda ty jmenné prostory zavádíme?“. Jednoduše řečeno – pravidlo a) mi připadá jako zpátečnické beznamespacové myšlení.

--

Taky se přimlouvám za přejmenování AppForm. Je pravda, že Form extends Form vypadá divně, ale to je interní věc frameworku, která moc lidí trápit nebude. Důležité je, že v aplikaci se používá buď Application\Form, nebo Forms\Form. Případů, kdy je rozumné oba přístupy mixovat moc nebude, natožpak případů, kdy se oba přístupy mixují v jednom souboru.

Editoval xificurk (7. 4. 2011 17:23)

paranoiq
Člen | 392
+
0
-

David: Třeba v případě Nette\Database\Drivers mi to vyloženě vyhovuje

ale vždyť jde o stejný případ. čím se Drivers\..Driver liší od příkladů výše? (Reflection\..Reflection a Selector\..Selection sice není úplně to samé, ale také se mi to moc nezdá :/)

pokud se ti Responses\..Response, Routers\..Router, Helpers\..Helper nelíbí a Drivers\..Driver ano, chceš to udělat nekonzistentně? já myslím katalogizovat buď všude nebo nikde. (a jsem pro druhou možnost ;)

xificurk

jméno třídy se většinou v kódu vyskytuje bez NS, protože use. proto musí být poznat o co jde ze samotného názvu třídy. jinak se zhorší čitelnost kódu. pravidlo a) je setsakra užitečné

xificurk & Jan Tvrdík

nováčci jistě uvítají, že Nette obsahuje dvě funkčně odlišné třídy Form ;->

Nette\Finder → Nette\FileFinder

souhlasím. finder je nic neříkající jméno

redhead
Člen | 1313
+
0
-

Rozhodně nechat pravidlo a). S použitím use nebudu vůbec tušit, co že za třídy to v kódu mám.

AppForm nechat.

FileFinder++

Majkl578
Moderator | 1364
+
0
-

Souhlasím s návrhem na Nette\Exceptions.

Jsem i pro přejmenování AppFormForm. Argument class Form extends Form stojí za prd, protože to není reálné kvůli kolizi a i framework by musel použít něco jako class Form extends Nette\Forms\Form. A asi nikdy jsem neviděl použití AppForm a Form zároveň, upřímně, kdo z vás ano?

Context, Request a IResponse porušují pravidla a) a c):

  • Nette\Application\DI\Context vs. Nette\Http\Context
  • Nette\Application\Request vs. Nette\Http\Request
  • Nette\Application\IResponse vs. Nette\Http\IResponse

    (Pravidlo a) mi mimochodem přijde jako krok zpět, viz co psal xificurk. Máme tu přece as u use, ne?)

Některé další třídy porušují pravidlo a) (tj. bezu uvedení namespace):

  • Nette\Diagnostics\Helpers – helper čeho / k čemu?
  • Nette\Latte\Filter – filter čeho?

Přejmenování HttpUploadedFile na Nette\Http\FileUpload mi přijde hodně WTF, protože FileUpload evokuje spíš prostředek k nahrávání souborů, rozhodně ne nahratý soubor. Raději bych volil Nette\Http\UploadedFile.

Nekonzistence jmen tříd v Nette\Application\Responses – některé mají -ingový tvar, některé ne. Nechat nekonzistentní nebo sjednotit? (Download × Downloading, Render × Rendering)

Třídy jako String, Image apod. bych nasypal do prostoru Nette\Utils.

Mimochodem, nepasovaly by třídy IUser & User lépe do Nette\Application (Nette\Web\UserNette\Application\User)?

Filip Procházka
Moderator | 4668
+
0
-

Myslím že pravidlo a) by mělo mít větší prioritu než duplicity v názvu.

Editoval HosipLan (5. 4. 2011 15:05)

xificurk
Člen | 121
+
0
-

paranoiq napsal(a):
jméno třídy se většinou v kódu vyskytuje bez NS, protože use. proto musí být poznat o co jde ze samotného názvu třídy. jinak se zhorší čitelnost kódu. pravidlo a) je setsakra užitečné

To není obecně pravda, tohle přeci záleží na volbě programátora. Stejně jako např. u pojmenování proměnných je jen na něm, aby našel kompromis mezi srozumitelností a leností psát. Pokud si jsem jistý, že to bude srozumitelné použiju use Nette\Http\Request;, pokud hrozí nějaké zmatení tak použiju use Nette\Http; a v kódu se pak odkazuji na Http\Request.

Aurielle
Člen | 1281
+
0
-

Ad použití Form + AppForm dohromady – nejspíš jsem ještě naučený z PHP 5.2 verzí, nicméně validační pravidla připisuji přes Form::SOMETHING.

Majkl578
Moderator | 1364
+
0
-

gmvasek napsal(a):

Ad použití Form + AppForm dohromady – nejspíš jsem ještě naučený z PHP 5.2 verzí, nicméně validační pravidla připisuji přes Form::SOMETHING.

A kde je problém? Však to by fungovalo úplně stejně jako doposud…
(Mmj. v PHP 5.3 můžeš použít i přístup ke konstantě přes instanci: $form::INTEGER.)

Honza Marek
Člen | 1664
+
0
-

Když už teda hlasujeme o prioritách, tak hlasuju pro nízkou prioritu pravidla a :)

Aurielle
Člen | 1281
+
0
-

Majkl578 napsal(a):

A kde je problém? Však to by fungovalo úplně stejně jako doposud…
(Mmj. v PHP 5.3 můžeš použít i přístup ke konstantě přes instanci: $form::INTEGER.)

Psaní $ je znak navíc :D

Patrik Votoček
Člen | 2221
+
0
-

Vyhnu se zbytečnému flame okolo všecho a vypíchnu jenom jednu věc a to AppForm vs Form. Předně jsem pro přejmenovat AppForm na Form. Kdo z vás kdy naposledy použil samotný Nette\Forms\Form? Podle mě ho používají pouze lidé kteří používají samotné formuláře. Takže to tak matoucí není.

Nehledě na:
varianta 1 (ta kterou nemám rád):

namespace App;

use Nette\Application\AppForm;

class FooPresenter extends BasePresenter
{
	protected function createComponentMyForm($name)
	{
		$form = new AppForm($this, $name);
		$form->addText('foo', "Foo")->addRule(AppForm::PATTERN, "[a-z0-9]");
	}
}

varianta 2 (hezčí srozumitelnější ale používám 2 různé „Form“):

namespace App;

use Nette\Forms\Form,
	Nette\Application\AppForm;

class FooPresenter extends BasePresenter
{
	protected function createComponentMyForm($name)
	{
		$form = new AppForm($this, $name);
		$form->addText('foo', "Foo")->addRule(Form::PATTERN, "[a-z0-9]");
	}
}

varianta 3 (po přejmenování Nette\Application\AppForm na Nette\Application\Form):

namespace App;

use Nette\Application\Form;

class FooPresenter extends BasePresenter
{
	protected function createComponentMyForm($name)
	{
		$form = new Form($this, $name);
		$form->addText('foo', "Foo")->addRule(Form::PATTERN, "[a-z0-9]");
	}
}

Aneb ve variantě 1 definuju pravidlo PATTERN ale musím psát AppForm proto si to ve variantě 2 usnadním a přidám use Nette\Forms\Form abych mohl psát jenom Form (tím ale vznikne trochu WTF proč instancuju AppForm když pro pravidla používám Form). No a varianta 3 je prostě žůžo labůžo… No ni?

Jó a jednu tak trochu „OFF TOPIC“ si neodpustím a to co App namespace pro sandbox?

Jan Jakeš
Člen | 177
+
0
-
  • AppFormForm +1
  • Nette\Exceptions +1
  • App namespace pro sandbox → navrhuji pro používání namespace uvnitř aplikace lehce přizpůsobit defaultní implementaci PresenterFactory https://forum.nette.org/…itr-aplikace
kravčo
Člen | 721
+
0
-

Patrik Votoček napsal(a):

varianta 1 (ta kterou nemám rád):

varianta 2 (hezčí srozumitelnější ale používám 2 různé „Form“):

variant 3

namespace NetteSandbox;

use Nette\Application\AppForm as Form;

class FooPresenter extends BasePresenter
{
	protected function createComponentMyForm($name)
	{
		$form = new Form($this, $name);
		$form->addText('foo', "Foo")->addRule(Form::PATTERN, "[a-z0-9]");
	}
}

David Grudl napsal(a):

a) Název každé třídy i bez jmenného prostoru musí vystihovat její podstatu, tj. název musí obsahovat podmět.

Pravidlo a) neznamená, že názov triedy musí byť jednoznačný v rámci frameworku.

Mne sa veľmi páči zápis

<?php

use Nette\Http;

$request = new Http\Request;
$response = new Http\Response;

pretože krásne využíva vlastnosť PHP „importovať“ menné priestory. Analógia z aktuálneho stavu je zbytočne ukecaná:

<?php

use Nette\Http\HttpRequest,
    Nette\Http\HttpResponse;

$request = new HttpRequest;
$response = new HttpResponse;

Škoda len, že nie všetky triedy sa dajú takto zapísať…

na1k
Člen | 288
+
0
-

kravčo napsal(a):
variant 3

namespace NetteSandbox;

use Nette\Application\AppForm as Form;

class FooPresenter extends BasePresenter
{
	protected function createComponentMyForm($name)
	{
		$form = new Form($this, $name);
		$form->addText('foo', "Foo")->addRule(Form::PATTERN, "[a-z0-9]");
	}
}

Používat jako alias jméno nějaké jiné třídy je trochu masochismus, ne?

Asi bych byl taky za přejmenování AppForm na normální Form (a přesun někam do Application) a nahrazení obyč Formu něčím jiným. Form využijí jen ti co používají standalone formuláře; těch je ale minimum. Zatímco většina jede na plné verzi Nette a musejí psát o tři znaky delší AppForm. Já hlasuji pro pohodlí většiny :)

mm-marek
Člen | 61
+
0
-

Nette\Http\UploadedFile ++ (Nette\Http\FileUpload mi skutečně přijde hodně WTF)

ad Finder, prohledává i adresáře, takže FileFinder či jiná varianta s File by byla opět WTF

redhead
Člen | 1313
+
0
-

Zdá se mi to nebo tu nikdo nepracuje v Javě, ta by vás naučila. Škoda. Jsem jednoznačně pro zachování a)

@mm-marek: Nás učili, že složka je zvláštní případ souboru :)

Editoval redhead (5. 4. 2011 20:42)

Patrik Votoček
Člen | 2221
+
0
-

kravčo napsal(a):

David Grudl napsal(a):

a) Název každé třídy i bez jmenného prostoru musí vystihovat její podstatu, tj. název musí obsahovat podmět.

Jinými slovy, nemělo by být nutné používat AS v klauzuli USE.

na1k napsal(a):

Asi bych byl taky za přejmenování AppForm na normální Form (a přesun někam do Application) a nahrazení obyč Formu něčím jiným. Form využijí jen ti co používají standalone formuláře; těch je ale minimum. Zatímco většina jede na plné verzi Nette a musejí psát o tři znaky delší AppForm. Já hlasuji pro pohodlí většiny :)

Souhlas

kravčo
Člen | 721
+
0
-

Patrik Votoček napsal(a):

Jinými slovy, nemělo by být nutné používat AS v klauzuli USE.

Ale ono to vôbec nutné nie je!

Majkl578
Moderator | 1364
+
0
-

redhead napsal(a):

Zdá se mi to nebo tu nikdo nepracuje v Javě, ta by vás naučila.

Ale tady nejsme v Javě. :)

David Grudl
Nette Core | 8218
+
0
-

Přátelé, alespoň většina z vás, ten post jsem psal tak tři hodiny, kdybyste věnovali alespoň 15 minut snaze ho přečíst a pochopit, dalo by se tu i o něčem diskutovat.

Patrik Votoček
Člen | 2221
+
0
-

Já ho četl a to 2x… :-/
Nechme tedy AppForm stranou možná se to ztratilo v kontextu ale co App namespace pro „sandbox“ / „app“?

David Grudl
Nette Core | 8218
+
0
-

paranoiq napsal(a):

David: Třeba v případě Nette\Database\Drivers mi to vyloženě vyhovuje

ale vždyť jde o stejný případ. čím se Drivers\..Driver liší od příkladů výše?

Nevadí to proto, že instanci nikdy nevytváříš a je to výhodné proto, že se tak lépe řeší dynamické instancování ("Drivers/{$name}Driver").

Majkl578 napsal(a):

Některé další třídy porušují pravidlo a) Nette\Latte\Filter – filter čeho?

Doporučuji nastudovat význam slova podmět / podstatné jméno ;-)

Přejmenování HttpUploadedFile na Nette\Http\FileUpload mi přijde hodně WTF, protože FileUpload evokuje spíš prostředek k nahrávání souborů, rozhodně ne nahratý soubor.

Přesně tak, jestli došlo k nahrání se zjistí až přes isOk().

Nekonzistence jmen tříd v Nette\Application\Responses – některé mají -ingový tvar, některé ne. Nechat nekonzistentní nebo sjednotit? (Download × Downloading, Render × Rendering)

Jj, upravím na neingový tvar.

xificurk napsal(a):

Pokud si jsem jistý, že to bude srozumitelné použiju use Nette\Http\Request;, pokud hrozí nějaké zmatení tak použiju use Nette\Http; a v kódu se pak odkazuji na Http\Request.

A kdy použiješ Json nebo File?

David Grudl
Nette Core | 8218
+
0
-

O pravidle a) prosím vůbec nediskutujme, to je naprosto základní pilíř celé koncepce.

David Grudl
Nette Core | 8218
+
0
-

Sdružující jmenné prostory Iterators, Responses, Routers a Helpers jsem zrušil.

David Grudl
Nette Core | 8218
+
0
-

A zase si to rozmyslel a vrátil je.

Jan Tvrdík
Nette guru | 2595
+
0
-

David Grudl wrote: A zase si to rozmyslel a vrátil je.

:P

  • Nette\Database\Drivers a Nette\Iterators se mi libí.
  • Naopak jsem proti Nette\Exceptions (viz také RFC).
  • U Nette\Application\Routers mi vadí, že neobsahuje rozhraní Nette\Application\IRouter (tj. shlukuje to routery a ne celou problematikou routování). Proč?
  • Nette\Template\Helpers mi je v celku jedno. Záleží na tom, jestli v budoucnu předpokládáš, že tam toho bude víc.
  • Na Nette\Application\Responses nemám jednoznačný názor.
  • Stále si myslím, že AppForm by se měl přejmenovat na Form, ale v nejhorším si to pořeším sám v aplikaci.
paranoiq
Člen | 392
+
0
-

David Grudl napsal(a):

A zase si to rozmyslel a vrátil je.

ono je to v podstatě fuk. kdyby byl opravdu pádný argument pro nebo proti, asi by jsme tady o tom nediskutovali

juzna.cz
Člen | 248
+
0
-

Vyjimky bez namespace se mi libi. Jelikoz je potencialni problemy potreba osetrovat neustale, a kazdou chvili nejake jine, tak v kazdem souboru nekolik trid vyjimek mit budu. Pred zavedenim namespace bylo jejich pouziti snadne; s namespace se pak pridal jen jeden znak – zpetne lomitko.

Jak budete resit vyjimky kdyz budou namespacovane? Pomoci use + nekolik trid jen pro vyjimky v kazdem souboru? Nebo budete psat cele jmeno? Me to prijde docela dost psani navic :(

Pavel Kouřil
Člen | 128
+
0
-

S Nette\Exceptions souhlasím – už jen díky tomu, že si člověk pak napíše jen Exceptions\ a dá ctrl-shift a vyjedou mu všechny možné Nette výjimky (což se hodí, protože každá výjimka začíná jiným slovem než Exception; a hledat nějakou konkrétní by bylo poměrně otravné, když si člověk nepomatuje její název zpaměti).

Jan Tvrdík
Nette guru | 2595
+
0
-

Jsem toho názoru, že aplikace by neměla používat výjimky z jmenného prostoru Nette. Aplikace by měla být ideálně celá obalena vlastním jmenným prostorem a v něm si definovat vlastní výjimky (které by neměly dědit od výjimek z jmenného prostoru Nette).

Filip Procházka
Moderator | 4668
+
0
-

Honzo, s těmi výjimkami máš samozřejmě pravdu, ale né všichni vědí, že by měli psát výjimku zvlášť pro každou třídu/balíček, nebo to chtějí dodržovat. Já to dodržuji jen částečně. Rozhodně jsem pro zabalení Nette výjimek do Exceptions\, je to neuvěřitelně pohodlné.

David Grudl napsal(a):

A zase si to rozmyslel a vrátil je.

Jsem pro Nette\Application\Responses\ForwardingResponse. Sám to používám, když mám skupinu tříd, které dělají podobnou činnost (responses, Iterators, …).

Editoval HosipLan (7. 4. 2011 7:59)

David Grudl
Nette Core | 8218
+
0
-

Jsem pro Nette\Application\Responses\ForwardingResponse. Sám to používám, když mám skupinu tříd, které dělají podobnou činnost (responses, Iterators, …).

Jsem pro Nette\Application\Responses\Forward :-)

Filip Procházka
Moderator | 4668
+
0
-

Jsi si jistý, že to dostatečně popisuje co třída dělá? :) Možná u forward ano, ale co takový Json?