Na začátek jeden vtip.

Špatní fotografové se baví o objektivech, dobří o fotografiích a ti slavní o ženských.

Dalo by se to vztáhnout i na programátory, že ti špatní se baví o programovacích jazycích. Největším dnešním úskalím softwarového inženýrství rozhodně není zdrojový kód, přesto věnuji tento příspěvek jazyku Groovy. Java mě živí, ale Groovy mě baví víc, je to příjemné zpestření. Dočetl jsem druhé vydání knihy Groovy in Action (čekali jsme na druhé vydání této bible dlouhých 6 let). Udělal jsem si pár poznámek, které by se mohly hodit i vám, ať už s Groovy začínáte nebo ho už nějakou chvilku používáte.

Groovy je stále aktuální i přesto, že už vyšla Java 8. Používám Groovy v Gradle, na mockování webových služeb v Soap UI a nejčastěji při psaní testů. Napíšu tak mnohem méně kódu. A není to cvičení pro cvičení, ale znamená to menší pravděpodobnost, že uděláte chybu, a méně kódu na čtení. Přičemž netrpí čitelnost, ba právě naopak. Jako příklad uveďme inicializaci objektů či práci s kolekcemi.

Dynamický jazyk

Trocha teorie nikoho nezabije, malé opakování spíše prospěje všem. Groovy je dynamický jazyk, ale co to znamená? Připomeňme si, že typování můžeme dělit na slabé a silné, či statické (typ proměnných se specifikuje v době kompilace) a dynamické. Silně a staticky je typovaná třeba Java. Slabě a dynamicky například JavaScript (piš, co chceš). Oproti tomu jazyk C je sice staticky typovaný, takže vás kompilátor klepne přes prsty, pokud byste chtěli používat API, které typu nepřísluší, ale na druhou stranu už vás nic neomezuje v tom, přetypovat proměnnou na úplně jiný typ. Dynamický jazyk neznamená slabě typovaný, jak si možná mnozí myslí. Groovy je dynamicky a přesto silně typovaný jazyk. Kompilátor vám tedy ledacos dovolí, ale běhové prostředí vás případně zastaví.

Z knihy jsem si vypůjčil příklad, jak jsou v Groovy a v Javě dispatchované metody (hrozný termín, ale překlad nemám).

Protože Groovy dispachuje podle typu za běhu, je v druhém případě použita implementace oracle(String). Použijete-li v Javě statický typ Object, ztrácíte sílu statického typování.<blockquote>Pokud jste ve své kariéře zatím neviděli moc dynamického programování, můžete se ptát, k čemu to je, když jste se bez toho doposud očividně obešli.</blockquote>

Statické typování

Mnoho programátorů žije v domění, že dynamické jazyky jsou vždy pomalejší než ty staticky kompilované. To není vždy pravda. Groovy je obecně téměř stejně rychlé jako Java. Ovšem jsou situace, kdy se cena za dynamický výběr metody stane relevantní jako při optimalizaci výkonu tight loop na kritické cestě.

Anotace @TypeChecked zapíná typovou kontrolu při kompilaci. Jednoduše vysvětleno třeba zde. Nicméně přijdete tak o dost dynamických vychytávek a možnost přidávat metody za běhu díky metaclass, viz přiložený příklad převodu jednotek.

Number.metaClass {
    getMm = { delegate }
    getCm = { delegate * 10.mm }
    getM = { delegate * 100.cm }
}
assert 1.m + 20.cm - 8.mm == 1.192.m

Oproti tomu anotace @CompileStatic zajistí, že kód bude staticky zkompilovaný téměř do stejného byte code jako Java. Bohužel se budete muset vzdát síly Groovy meta object protokolu. Doporučuji podrobnější vysvětlení na InfoQ.

API

Když v práci narazíte na něco nízkoúrovňového jako třeba výrobu biometrických cestovních pasů, oceníte, že Groovy má slušné API na konverzi z/do hex či base64 kódování.

Líbí se mi anotace @Delegate, díky které jsem zjednodušil práci s errorCollectorem v JUnit (i když s JUnit 5 to už bude jinak).

Potřebujete-li iterovat přes všechny prvky kolekce a znát i index, použijte metodu eachWithIndex ['Petr', 'Aleš', 'Václav'].eachWithIndex{ item, index -> println "$index: $item" }

Stackoverflow chybu můžete při rekurzi dostat i když máte dobře napsanou ukončovací podmínku, prostě jste potřeboval příliš mnoho paměti. Pokud máte tail-recursive funkci, to jest takovou, která posledním řádkem volá sama sebe a už nedělá nic jiného, mohli byste zásobník uvolnit. JVM takovou podporu bohužel nemá, proto je tu anotace TailRecursive, která funkci převede na iterativní volání. Koukněte na příklad. Ověřit můžete v GroovyConsole, kde stiskem vyvoláte ctrl + t AST (Abstract Syntax Tree) browser.

Při psaní parametrizovaných testů jsem potřeboval převést list listů na list polí foo.collect{ it as Object[] } Zjistil jsem, že to lze udělat ještě jinak a to foo*.toArray()

V GStringu zvládnete i lazy evaluation.

def x = 1
def y = "$x"
def z = "${ -> x}"//lazy evaluation
x = 2
assert y == "1"
assert z == "2"

Potřebujete-li synchronizovat metodu pro čtení, sáhněte po anotaci @WithReadLock. Pod pokličkou se používá ReentrantReadWriteLock z java.util.concurrent, ale nepotřebujete psát ten balast okolo.

Groovy frameworky

Naučit se syntaxi je otázka dní, naučit se idiomy nového jazyka možná vyžaduje pár týdnů, ale pracovat s novou knihovnou může lehce zabrat několik měsíců.

Asi není potřeba vyzdvihovat Gradle a Grails, ale existuje spoustu další frameworků postavených na Groovy, které stojí za povšimnutí. Zatím jsem nepoužil, tak si poznamenávám i pro sebe, kdyby se mi to v budoucnu hodilo.

Desktopové aplikace nemusíte psát v čistém Swingu, od toho je to Griffon, který se inspiroval u Grails.

Není nutné se učit .NET, abyste mohli vytvářet ActiveX nebo COM Windows komponenty, mrkněte na Scriptom

Mám klidné spaní, jelikož nepíšu paralelní zpracování. Nicméně, pokud bych musel, sáhl bych po vyšší míře abstrakce, než jsou vlákna, třeba aktory a knihovnu GPars. Mimochodem na jeho vzniku se podílel Václav Pech.

Gebish spojuje sílu WebDriveru (Selenium) s dotazovacími schopnostmi jQuery, robustností návrhového vzoru Page Object a možnostmi jazyka Groovy.

PillarOne by měl být nástroj na modelování risku v pojišťovnictví.

Je možné psát Android aplikace v Groovy, ale vyžaduje to speciální verzi kompilátoru. Groovy poskytuje jar soubory s klasifikátorem grooid.

Pustíte-li se více do Groovy, Gradle… budete potřebovat rozumnější zprávu instalací. Od toho tu je užitečný nástroj SDKMAN!, dříve GVM (Groovy enVironment Manager), inspirovaný RVM (Ruby). Milovníci Windows mají bohužel smůlu.

Související