Obsah
1. Nástroj Leiningen a programovací jazyk Clojure: tvorba vlastních knihoven pro veřejný repositář
2. Postup při vytvoření nové knihovny
3. Vytvoření kostry nové knihovny
4. Úprava projektového souboru a naprogramování vlastního těla knihovny
5. Uložení knihovny do veřejného repositáře
6. Vytvoření nového projektu, který bude knihovnu používat
7. Načtení všech závislých knihoven pro nově vytvořený projekt
8. Výpis CLASSPATH používaných projektem
9. Import knihovny a zavolání funkce z této knihovny
10. Repositář s dnešními demonstračními příklady
11. Odkazy na předchozí části tohoto seriálu
1. Nástroj Leiningen a programovací jazyk Clojure: tvorba vlastních knihoven pro veřejný repositář
Již v prvním článku série o programovacím jazyku Clojure a nástroji Leiningen jsme si popsali základní možnosti Leiningenu. Připomeňme si, že Leiningen se typicky používá pro vytváření nových projektů na základě předem připravené šablony, pro automatické stahování všech potřebných knihoven (i jejich závislostí), spouštění projektů, spouštění testů a v neposlední řadě taktéž pro spuštění interaktivní smyčky REPL, která vývojářům nabízí více možnosti, než standardní implementace REPLu dostupná přímo v Clojure (mezi přidané vlastnosti patří zejména automatické nastavení cest ke knihovnám apod.).
Leiningen je multiplatformním produktem, což znamená, že i ty vývojové týmy, jejichž členové pracují s různými operačními systémy, mohou možnosti nabízené Leiningenem využít. K Leiningenu lze v případě potřeby připojovat i další přídavné moduly (plugins), takže například existuje podpora pro spuštění webové aplikace takovým způsobem, že se změny provedené ve zdrojových kódech ihned promítnou do běžící aplikace bez nutnosti jejího restartu, což samozřejmě umožňuje rychlejší vývoj i testování.
Mezi již popsané možnosti nástroje Leiningen patří zejména:
- Vytvoření nového projektu na základě vybrané a předem připravené šablony. K dispozici jsou šablony běžné aplikace (doplněné o jednotkové testy, resp. přesněji řečeno o prázdnou kostru pro jednotkové testy), přídavného modulu pro samotný Leiningen atd. Základním příkazem pro vytvoření nového projektu je lein new, pro novou aplikaci pak lein new app název.
- Automatické stažení všech knihoven a jejich závislostí na základě konfigurace zapsané do souboru project.clj. Tuto funkci zajistí příkaz lein deps. Knihovny, na nichž projekt závisí, se ukládají do adresáře ~/.m2, takže jsou dostupné i dalším aplikacím (Leiningen je kompatibilní s Mavenem).
- Spuštění projektu s možností předání parametrů příkazového řádku. Příkaz je jednoduchý: lein run. Spouští se ta funkce, která je určena v projektovém souboru project.clj, typicky se jedná o funkci nazvanou main z modulu (jmenného prostoru) název_aplikace/core.
- Spuštění jednotkových testů, které mohou být vytvořeny společně s projektem (kostra jednoho testu je připravena automaticky). Snadno uhádnutelný příkaz, který jednotkové testy spustí, se jmenuje lein test.
- Provedení relativně rychlé kontroly syntaxe zdrojových kódů i kontroly existence volaných metod. Tuto činnost zajistí příkaz lein check.
- Lokální instalace projektu do specifikovaného adresáře (lein install).
- Příprava Java archivu (souboru s koncovkou .jar) takovým způsobem, aby bylo možné aplikaci nasadit i na jiném počítači, například na aplikační server. V rámci přípravy archivu se provádí překlad vybraných modulů do javovského bajtkódu (lein jar).
- Příprava Java archivu obsahujícího i všechny závislé knihovny včetně samotného Clojure. Takto vytvořený „uberjar“ je posléze možné nasadit na jakémkoli počítači vybaveném pouze JRE (běhovým prostředím jazyka Java). Tuto činnost zajistí příkaz lein uberjar.
- Spuštění smyčky REPL s nastavením cest ke všem potřebným knihovnám a modulům. Souběžně se otevře port, přes který je možné se smyčkou REPL komunikovat například z integrovaného vývojového prostředí, z Vimu apod. (lein repl).
- Každý příkaz Leiningenu je v rozumné míře popsán v nápovědě (lein help příkaz).
Nyní si k těmto již popsaným možnostem přidáme další funkci nástroje Leiningen. Ukážeme si, jakým způsobem je možné vytvořit novou knihovnu a uložit tuto knihovnu do repositáře dostupného na serveru Clojars. Následně bude tato velmi jednoduchá knihovna sestávající z jediné funkce, použita v demonstračním příkladu, kde proběhne její stažení, instalace do adresáře ~/.m2, import a následné zavolání funkce dostupné z právě nainstalované knihovny.
2. Postup při vytvoření nové knihovny
Vytvoření nové knihovny vyvinuté v programovacím jazyce Clojure a jednoduše dostupné dalším vývojářům, se skládá pouze z několika relativně snadno pochopitelných kroků. K jejich provedení musí být nainstalován nástroj Leiningen:
- Nejprve je nutné projít registrací uživatele (vývojáře) na stránce https://clojars.org/register. Jméno uživatele a heslo bude použito později při nahrávání knihovny na server Clojars. Pro jméno platí jistá omezení vyplývající z toho, že ze jména uživatele bude odvozeno jméno balíčku ve tvaru org.clojars.jméno_uživatele; ideálně se omezte na použití malých písmen z tabulky ASCII.
- Vytvoření projektu představujícího knihovnu. V projektu musí být uvedeno správné jméno balíčku ve tvaruorg.clojars.jméno_uživatele (protože projekt se prozatím nestane oficiálním projektem). Vzhledem k tomu, že se v případě knihovny nejedná o spustitelnou aplikaci, není zapotřebí v projektovém souboru specifikovat jméno vstupní funkce (main).
- Implementace celé knihovny podle požadavků vývojáře. Žádná zvláštní omezení se zde nekladou. Knihovna by měla obsahovat i jednotkové testy a dokumentaci, není to však striktně vyžadováno.
- Zveřejnění celé knihovny s využitím příkazu lein deploy clojars. Knihovna (popř. její nová verze) se prakticky ihned objeví v seznamu na serveru https://clojars.org/.
- Posléze je možné vytvořit i oficiální variantu knihovny, která bude podepsaná a bude mít lépe zapamatovatelné jméno. Tuto variantu si stručně popíšeme příště.
Všechny tyto kroky budou podrobněji popsány v navazujících kapitolách.
Obrázek 1: Registrace nového uživatele na serveru Clojars.
3. Vytvoření kostry nové knihovny
Základním krokem k plnohodnotné knihovně je vytvoření její kostry. Nejedná se o nic složitého, protože využijeme již známý a v tomto seriálu několikrát popsaný příkaz lein new app. Naši testovací knihovnu pojmenujeme clj-hello, a to z toho důvodu, že v ní bude implementována jediná funkce pro výpis zprávy „Hello world“ na standardní výstup (naše nároky tedy nejsou příliš vysoké:) Vytvoření kostry knihovny clj-hello se provede následujícím způsobem:
lein new app clj-hello Generating a project called test-hello based on the 'app' template.
Podle předpokladů se vygeneruje adresářová struktura představující kostru aplikace:
. ├── doc │ └── intro.md ├── LICENSE ├── project.clj ├── README.md ├── resources ├── src │ └── clj_hello │ └── core.clj ├── test │ └── clj_hello │ └── core_test.clj └── tree
Povšimněte si důležité maličkosti: zatímco v jazyce Clojure bude jmenný prostor nazvaný clj-hello, jména souborů a adresářů tomu neodpovídají, protože mají tvar clj_hello. Tato (v praxi poměrně otravná) konvence byla do jazyka Clojure a nástroje Leiningen zavedena kvůli plné kompatibilitě s programovacím jazykem Java.
Pro úplnost se ještě podívejme na obsah souboru project.clj, který obsahuje konfiguraci celé aplikace:
(defproject clj-hello "0.1.0-SNAPSHOT" :description "FIXME: write description" :url "http://example.com/FIXME" :license {:name "Eclipse Public License" :url "http://www.eclipse.org/legal/epl-v10.html"} :dependencies [[org.clojure/clojure "1.6.0"]] :main ^:skip-aot clj-hello.core :target-path "target/%s" :profiles {:uberjar {:aot :all}})
4. Úprava projektového souboru a naprogramování vlastního těla knihovny
Výše uvedený tvar projektového souboru project.clj byl nástrojem Leiningen vytvořen pro potřebu běžné aplikace a nikoli knihovny, což mj. znamená, že se zde nachází informace o jmenném prostoru obsahujícího funkci, která se má spustit v průběhu inicializace aplikace. Tuto část můžeme z projektového souboru zcela odstranit. Navíc se původně projekt jmenuje pouze clj-hello, ovšem toto jméno není možné použít při nahrávání knihovny na server Clojars – je před něj nutné přidat i jméno balíčku ve tvaru org.clojars.jméno_uživatele. Vzhledem k tomu, že autor článku se zaregistroval pod jménem „tisnik“, bude mít úplné jméno projektu tvar org.clojars.tisnik/clj-hello a soubor s konfigurací projektu bude vypadat následovně:
(defproject org.clojars.tisnik/clj-hello "0.1.0-SNAPSHOT" :description "Yet another hello world example :-)" :url "http://example.com/FIXME" :license {:name "Eclipse Public License" :url "http://www.eclipse.org/legal/epl-v10.html"} :dependencies [[org.clojure/clojure "1.6.0"]])
Druhou úpravou je odstranění souboru src/clj_hello/core.clj a nahrazení tohoto souboru novým zdrojovým kódem uloženým pod lepším (obvyklejším) jménem src/clj_hello/clj_hello.clj. Tento nový zdrojový soubor bude obsahovat deklaraci jmenného prostoru a taktéž funkci se jménem say-hello. Tato funkce představuje veškerou funkcionalitu právě vytvořené knihovny:
(ns clj-hello.clj-hello) (defn say-hello [] (println "Hello world!"))
Knihovna připravená pro „deploying“ na server Clojars, má následující adresářovou strukturu. Nejdůležitější soubory jsou zvýrazněny:
. ├── doc │ └── intro.md ├── LICENSE ├── project.clj ├── README.md ├── resources ├── src │ └── clj_hello │ └── clj_hello.clj ├── test │ └── clj_hello │ └── core_test.clj └── tree
5. Uložení knihovny do veřejného repositáře
Dalším krokem je uložení právě vytvořené nové knihovny do veřejného repositáře umístěného na serveru Clojars. Tuto akci zajistí nástroj Leiningen poloautomaticky; pouze postačuje zadat následující příkaz:
lein deploy clojars
Po zadání tohoto příkazu se provede kontrola konzistence knihovny, zjistí se, zda projektový soubor project.clj obsahuje veškeré potřebné údaje, naváže se spojení se serverem Clojars a nahraje se na něj knihovna zabalená do Java archivu (soubory s příponou .jar) doplněná o další metadata (soubory .pom a maven-metadata.xml). Vzhledem k tomu, že jsem do konfiguračního souboru neuložil jméno a heslo potřebné pro připojení k serveru Clojars, je nutné tyto dva údaje vyplnit (heslo se samozřejmě při zadávání nezobrazuje):
WARNING: please set :url in project.clj. No credentials found for clojars See `lein help deploying` for how to configure credentials to avoid prompts. Username: tisnik Password: nbusr123 Wrote /home/tester/temp/clj-hello/pom.xml Created /home/tester/temp/clj-hello/target/clj-hello-0.1.0-SNAPSHOT.jar Could not find metadata org.clojars.tisnik:clj-hello:0.1.0-SNAPSHOT/maven-metadata.xml in clojars (https://clojars.org/repo/) Sending org/clojars/tisnik/clj-hello/0.1.0-SNAPSHOT/clj-hello-0.1.0-20151107.211149-1.pom (3k) to https://clojars.org/repo/ Sending org/clojars/tisnik/clj-hello/0.1.0-SNAPSHOT/clj-hello-0.1.0-20151107.211149-1.jar (8k) to https://clojars.org/repo/ Could not find metadata org.clojars.tisnik:clj-hello/maven-metadata.xml in clojars (https://clojars.org/repo/) Sending org/clojars/tisnik/clj-hello/0.1.0-SNAPSHOT/maven-metadata.xml (1k) to https://clojars.org/repo/ Sending org/clojars/tisnik/clj-hello/maven-metadata.xml (1k) to https://clojars.org/repo/
Vše pro jistotu zkontrolujeme přímo na webovém rozhraní serveru Clojars:
Obrázek 2: Knihovna se skutečně objevila na stránkách serveru Clojars.
Obrázek 3: Zobrazení podrobností o knihovně clj-hello.
Obrázek 4: Do skupiny je možné přidávat i další uživatele.
Současně se v kořenovém adresáři projektu vytvoří soubor nazvaný pom.xml. Tento soubor bude při dalších úpravách knihovny automaticky přepisován, takže ho ani nemá cenu ukládat do repositáře. Ostatně pokud používáte pro správu verzí Git či Mercurial, je tato funkcionalita zajištěna automaticky, a to díky konfiguračním souborům .gitignore a .hgignore, které vytvořil nástroj Leiningen.
Obsah souboru pom.xml by měl být zhruba následující:
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.clojars.tisnik</groupId> <artifactId>clj-hello</artifactId> <packaging>jar</packaging> <version>0.1.0-SNAPSHOT</version> <name>clj-hello</name> <description>Yet another hello world example :-)</description> <url>http://example.com/FIXME</url> <licenses> <license> <name>Eclipse Public License</name> <url>http://www.eclipse.org/legal/epl-v10.html</url> </license> </licenses> <build> <sourceDirectory>src</sourceDirectory> <testSourceDirectory>test</testSourceDirectory> <resources> <resource> <directory>resources</directory> </resource> </resources> <testResources> <testResource> <directory>dev-resources</directory> </testResource> <testResource> <directory>resources</directory> </testResource> </testResources> <directory>target</directory> <outputDirectory>target/classes</outputDirectory> <plugins/> </build> <repositories> <repository> <id>central</id> <url>https://repo1.maven.org/maven2/</url> <snapshots> <enabled>false</enabled> </snapshots> <releases> <enabled>true</enabled> </releases> </repository> <repository> <id>clojars</id> <url>https://clojars.org/repo/</url> <snapshots> <enabled>true</enabled> </snapshots> <releases> <enabled>true</enabled> </releases> </repository> </repositories> <dependencies> <dependency> <groupId>org.clojure</groupId> <artifactId>clojure</artifactId> <version>1.6.0</version> </dependency> <dependency> <groupId>org.clojure</groupId> <artifactId>tools.nrepl</artifactId> <version>0.2.6</version> <exclusions> <exclusion> <groupId>org.clojure</groupId> <artifactId>clojure</artifactId> </exclusion> </exclusions> <scope>test</scope> </dependency> <dependency> <groupId>clojure-complete</groupId> <artifactId>clojure-complete</artifactId> <version>0.2.3</version> <exclusions> <exclusion> <groupId>org.clojure</groupId> <artifactId>clojure</artifactId> </exclusion> </exclusions> <scope>test</scope> </dependency> </dependencies> </project> <!-- This file was autogenerated by Leiningen. Please do not edit it directly; instead edit project.clj and regenerate it. It should not be considered canonical data. For more information see https://github.com/technomancy/leiningen -->
6. Vytvoření nového projektu, který bude knihovnu používat
Použití knihovny org.clojars.tisnik/clj-hello, která již byla na portálu Clojars úspěšně zaregistrována, je mnohem snazší, než její vytvoření. Ukážeme si to na velmi krátkém demonstračním příkladu pojmenovaném „test-hello“. Kostra tohoto příkladu vznikne příkazem:
lein new app test-hello Generating a project called test-hello based on the 'app' template.
Do souboru project.clj, který obsahuje konfiguraci projektu, musíme přidat název knihovny (knihoven), na nichž projekt závisí. V našem případě se jedná o zvýrazněný řádek, u něhož si povšimněte jak uvedení celého jména balíčku s knihovnou, tak i její verze (viz předchozí kapitoly a příslušné screenshoty):
(defproject test-hello "0.1.0-SNAPSHOT" :description "FIXME: write description" :url "http://example.com/FIXME" :license {:name "Eclipse Public License" :url "http://www.eclipse.org/legal/epl-v10.html"} :dependencies [[org.clojure/clojure "1.6.0"] [org.clojars.tisnik/clj-hello "0.1.0-SNAPSHOT"]] :main ^:skip-aot test-hello.core :target-path "target/%s" :profiles {:uberjar {:aot :all}})
Nyní je již projekt připraven knihovnu clj-hello využívat.
7. Načtení všech závislých knihoven pro nově vytvořený projekt
Po přidání nové knihovny do projektového souboru project.xml je již možné spustit další (v tomto seriálu zmíněný) příkaz nástroje Leiningen, který slouží pro stažení a lokální instalaci všech knihoven, na nichž projekt závisí. V našem případě by se měla stáhnout jen jediná nová knihovna, a to právě clj-hello. Ostatně se o tom můžeme sami snadno přesvědčit zadáním následujícího příkazu:
lein deps Retrieving org/clojars/tisnik/clj-hello/0.1.0-SNAPSHOT/clj-hello-0.1.0-20151107.211149-1.pom from clojars Retrieving org/clojars/tisnik/clj-hello/0.1.0-SNAPSHOT/clj-hello-0.1.0-20151107.211149-1.jar from clojars
Instalace knihovny se provede do adresáře ~/.m2/repository/org/clojars/tisnik/clj-hello/, jehož obsah bude zhruba následující (při prvním stažení zde nebudou uloženy dvě verze téže knihovny, pro ilustraci však uvádím možnost, kdy se knihovna mezitím změnila a existuje ve více stejně pojmenovaných verzích lišících se jen časem vzniku):
total 16 drwxr-xr-x 2 tester tester 4096 lis 8 22:07 0.1.0-SNAPSHOT -rw-r--r-- 1 tester tester 287 lis 7 22:36 maven-metadata-clojars.xml -rw-r--r-- 1 tester tester 40 lis 7 22:36 maven-metadata-clojars.xml.sha1 -rw-r--r-- 1 tester tester 179 lis 7 22:36 resolver-status.properties ./0.1.0-SNAPSHOT: total 68 -rw-r--r-- 1 tester tester 7926 lis 7 22:29 clj-hello-0.1.0-20151107.211149-1.jar -rw-r--r-- 1 tester tester 40 lis 7 22:29 clj-hello-0.1.0-20151107.211149-1.jar.sha1 -rw-r--r-- 1 tester tester 2878 lis 7 22:29 clj-hello-0.1.0-20151107.211149-1.pom -rw-r--r-- 1 tester tester 40 lis 7 22:29 clj-hello-0.1.0-20151107.211149-1.pom.sha1 -rw-r--r-- 1 tester tester 7926 lis 7 22:36 clj-hello-0.1.0-20151107.213602-2.jar -rw-r--r-- 1 tester tester 40 lis 7 22:36 clj-hello-0.1.0-20151107.213602-2.jar.sha1 -rw-r--r-- 1 tester tester 2878 lis 7 22:36 clj-hello-0.1.0-20151107.213602-2.pom -rw-r--r-- 1 tester tester 40 lis 7 22:36 clj-hello-0.1.0-20151107.213602-2.pom.sha1 -rw-r--r-- 1 tester tester 7926 lis 7 22:36 clj-hello-0.1.0-SNAPSHOT.jar -rw-r--r-- 1 tester tester 2878 lis 7 22:36 clj-hello-0.1.0-SNAPSHOT.pom -rw-r--r-- 1 tester tester 777 lis 8 22:07 maven-metadata-clojars.xml -rw-r--r-- 1 tester tester 40 lis 8 22:07 maven-metadata-clojars.xml.sha1 -rw-r--r-- 1 tester tester 202 lis 7 22:36 _maven.repositories -rw-r--r-- 1 tester tester 179 lis 8 22:07 resolver-status.properties
Zajímavý může být obsah automaticky vytvořeného souboru maven-metadata-clojars.xml, který naznačuje kompatibilitu mezi nástroji Leiningen a Maven:
<?xml version="1.0" encoding="UTF-8"?> <metadata> <groupId>org.clojars.tisnik</groupId> <artifactId>clj-hello</artifactId> <versioning> <versions> <version>0.1.0-SNAPSHOT</version> </versions> <lastUpdated>20151107213607</lastUpdated> </versioning> </metadata>
8. Výpis CLASSPATH používaných projektem
Jedním z velmi častých problémů, s nimiž se setkávají jak programátoři vyvíjející aplikace v Javě, tak i administrátoři, je zjištění popř. nastavení CLASSPATH, tj. adresářů a Java archivů, v nichž virtuální stroj Javy po svém spuštění hledá přeložené třídy popř. další potřebné soubory (resources). Podobný problém řeší i vývojáři používající programovací jazyk Clojure, kde je situace ještě poněkud komplikovanější kvůli pravidlům pojmenovávání zdrojových souborů, adresářů a jmenných prostorů (zjednodušeně řečeno se pomlčky ve jmenných prostorech převádí na podtržítka). Pokud je však projekt založen nástrojem Leiningen, je možné zjistit aktuální nastavení CLASSPATH velmi jednoduše; konkrétně pomocí příkazu lein classpath. Můžeme si to snadno vyzkoušet:
lein classpath
Výstupem tohoto příkazu je jediný dlouhý řádek, který jsem kvůli vyšší čitelnosti rozdělil na větší množství řádků v místě oddělovače jednotlivých cest:
/home/tester/temp/clojure-examples/test-hello/test: /home/tester/temp/clojure-examples/test-hello/src: /home/tester/temp/clojure-examples/test-hello/dev-resources: /home/tester/temp/clojure-examples/test-hello/resources: /home/tester/temp/clojure-examples/test-hello/target/base+system+user+dev/classes: /home/tester/.m2/repository/clojure-complete/clojure-complete/0.2.3/clojure-complete-0.2.3.jar: /home/tester/.m2/repository/org/clojure/tools.nrepl/0.2.6/tools.nrepl-0.2.6.jar: /home/tester/.m2/repository/org/clojars/tisnik/clj-hello/0.1.0-SNAPSHOT/clj-hello-0.1.0-SNAPSHOT.jar: /home/tester/.m2/repository/org/clojure/clojure/1.6.0/clojure-1.6.0.jar
Ze zvýrazněného řádku je patrné, že náš testovací projekt může pracovat i se staženou knihovnou clj-hello.
Jen pro zajímavost se podívejme, co stažený Java archiv obsahuje. Kvůli zpětné kompatibilitě používají tyto archivy formát ZIPu, takže výpis jejich interní struktury je jednoduchý (nástroj jar je pomalejší a má prapodivné parametry příkazové řádky :-):
unzip -l /home/tester/.m2/repository/org/clojars/tisnik/clj-hello/0.1.0-SNAPSHOT/clj-hello-0.1.0-SNAPSHOT.jar Archive: /home/tester/.m2/repository/org/clojars/tisnik/clj-hello/0.1.0-SNAPSHOT/clj-hello-0.1.0-SNAPSHOT.jar Length Date Time Name --------- ---------- ----- ---- 119 2015-11-07 22:36 META-INF/MANIFEST.MF 1864 2015-11-07 22:36 META-INF/maven/org.clojars.tisnik/clj-hello/pom.xml 299 2015-11-07 22:36 META-INF/leiningen/org.clojars.tisnik/clj-hello/project.clj 299 2015-11-07 22:36 project.clj 469 2015-11-07 22:36 META-INF/leiningen/org.clojars.tisnik/clj-hello/README.md 11218 2015-11-07 22:36 META-INF/leiningen/org.clojars.tisnik/clj-hello/LICENSE 0 2015-11-07 22:36 META-INF/ 0 2015-11-07 22:36 META-INF/maven/ 0 2015-11-07 22:36 META-INF/maven/org.clojars.tisnik/ 0 2015-11-07 22:36 META-INF/maven/org.clojars.tisnik/clj-hello/ 112 2015-11-07 22:36 META-INF/maven/org.clojars.tisnik/clj-hello/pom.properties 0 2015-11-07 22:31 clj_hello/ 80 2015-11-07 22:09 clj_hello/clj_hello.clj --------- ------- 14460 13 files
9. Import knihovny a zavolání funkce z této knihovny
Posledním krokem celého našeho snažení je zavolání funkce, která je deklarována v knihovně clj-hello. Před zavoláním funkce say-hello je nutné zpřístupnit celý jmenný prostor a načíst příslušný skript, což zajišťuje deklarace require, v níž je navíc specifikován i alias (nepovinné):
(ns test-hello.core (:gen-class)) (require '[clj-hello.clj-hello :as hello]) (defn -main "Entry point to this app" [& args] (hello/say-hello))
Funkcionalitu si můžeme ihned otestovat:
lein run Hello world!
10. Repositář s dnešními demonstračními příklady
Jak knihovna připravená pro publikaci na serveru Clojars, tak i demonstrační příklad, který tuto knihovnu využívá, byly uloženy, podobně jako v předchozích částech tohoto seriálu, do Git repositáře dostupného na adrese https://github.com/tisnik/clojure-examples. V tabulce zobrazené pod tímto odstavcem naleznete na zdrojové kódy knihovny i demonstračního příkladu přímé odkazy:
# | Příklad/knihovna | Github |
---|---|---|
1 | clj-hello | https://github.com/tisnik/clojure-examples/tree/master/clj-hello |
2 | test-hello | https://github.com/tisnik/clojure-examples/tree/master/test-hello |
11. Odkazy na předchozí části tohoto seriálu
- Leiningen: nástroj pro správu projektů napsaných v Clojure
http://www.root.cz/clanky/leiningen-nastroj-pro-spravu-projektu-napsanych-v-clojure/ - Leiningen: nástroj pro správu projektů napsaných v Clojure (2)
http://www.root.cz/clanky/leiningen-nastroj-pro-spravu-projektu-napsanych-v-clojure-2/ - Leiningen: nástroj pro správu projektů napsaných v Clojure (3)
http://www.root.cz/clanky/leiningen-nastroj-pro-spravu-projektu-napsanych-v-clojure-3/ - Leiningen: nástroj pro správu projektů napsaných v Clojure (4)
http://www.root.cz/clanky/leiningen-nastroj-pro-spravu-projektu-napsanych-v-clojure-4/ - Leiningen: nástroj pro správu projektů napsaných v Clojure (5)
http://www.root.cz/clanky/leiningen-nastroj-pro-spravu-projektu-napsanych-v-clojure-5/ - Leiningen: nástroj pro správu projektů napsaných v Clojure (6)
http://www.root.cz/clanky/leiningen-nastroj-pro-spravu-projektu-napsanych-v-clojure-6/ - Programovací jazyk Clojure a databáze (1.část)
http://www.root.cz/clanky/programovaci-jazyk-clojure-a-databaze-1-cast/ - Pluginy pro Leiningen
http://www.root.cz/clanky/leiningen-nastroj-pro-spravu-projektu-napsanych-v-clojure-pluginy-pro-leiningen/ - Programovací jazyk Clojure a knihovny pro práci s vektory a maticemi
http://www.root.cz/clanky/programovaci-jazyk-clojure-a-knihovny-pro-praci-s-vektory-a-maticemi/ - Programovací jazyk Clojure a knihovny pro práci s vektory a maticemi (2)
http://www.root.cz/clanky/programovaci-jazyk-clojure-a-knihovny-pro-praci-s-vektory-a-maticemi-2/ - Programovací jazyk Clojure: syntéza procedurálních textur s využitím knihovny Clisk
http://www.root.cz/clanky/programovaci-jazyk-clojure-synteza-proceduralnich-textur-s-vyuzitim-knihovny-clisk/ - Programovací jazyk Clojure: syntéza procedurálních textur s využitím knihovny Clisk (2)
http://www.root.cz/clanky/programovaci-jazyk-clojure-synteza-proceduralnich-textur-s-vyuzitim-knihovny-clisk-2/ - Programovací jazyk Clojure: syntéza procedurálních textur s využitím knihovny Clisk (dokončení)
http://www.root.cz/clanky/programovaci-jazyk-clojure-synteza-proceduralnich-textur-s-vyuzitim-knihovny-clisk-dokonceni/ - Seesaw: knihovna pro snadnou tvorbu GUI v jazyce Clojure
http://www.root.cz/clanky/seesaw-knihovna-pro-snadnou-tvorbu-gui-v-jazyce-clojure/ - Seesaw: knihovna pro snadnou tvorbu GUI v jazyce Clojure (2)
http://www.root.cz/clanky/seesaw-knihovna-pro-snadnou-tvorbu-gui-v-jazyce-clojure-2/ - Seesaw: knihovna pro snadnou tvorbu GUI v jazyce Clojure (3)
http://www.root.cz/clanky/seesaw-knihovna-pro-snadnou-tvorbu-gui-v-jazyce-clojure-3/ - Programovací jazyk Clojure a práce s Gitem
http://www.root.cz/clanky/programovaci-jazyk-clojure-a-prace-s-gitem/ - Programovací jazyk Clojure a práce s Gitem (2)
http://www.root.cz/clanky/programovaci-jazyk-clojure-a-prace-s-gitem-2/ - Programovací jazyk Clojure – triky při práci s řetězci
http://www.root.cz/clanky/programovaci-jazyk-clojure-triky-pri-praci-s-retezci/ - Programovací jazyk Clojure – triky při práci s kolekcemi
http://www.root.cz/clanky/programovaci-jazyk-clojure-triky-pri-praci-s-kolekcemi/ - Programovací jazyk Clojure – práce s mapami a množinami
http://www.root.cz/clanky/programovaci-jazyk-clojure-prace-s-mapami-a-mnozinami/ - Programovací jazyk Clojure – základy zpracování XML
http://www.root.cz/clanky/programovaci-jazyk-clojure-zaklady-zpracovani-xml/ - Programovací jazyk Clojure – testování s využitím knihovny Expectations
http://www.root.cz/clanky/programovaci-jazyk-clojure-testovani-s-vyuzitim-knihovny-expectations/ - Programovací jazyk Clojure – některé užitečné triky použitelné (nejenom) v testech
http://www.root.cz/clanky/programovaci-jazyk-clojure-nektere-uzitecne-triky-pouzitelne-nejenom-v-testech/ - Enlive – výkonný šablonovací systém pro jazyk Clojure
http://www.root.cz/clanky/enlive-vykonny-sablonovaci-system-pro-jazyk-clojure/
12. Odkazy na Internetu
- Clojars:
https://clojars.org/ - Seznam knihoven na Clojars:
https://clojars.org/projects - Clojure Cookbook: Templating HTML with Enlive
https://github.com/clojure-cookbook/clojure-cookbook/blob/master/07_webapps/7–11_enlive.asciidoc - An Introduction to Enlive
https://github.com/swannodette/enlive-tutorial/ - Enlive na GitHubu
https://github.com/cgrand/enlive - Expectations: příklady atd.
http://jayfields.com/expectations/ - Expectations na GitHubu
https://github.com/jaycfields/expectations - Lein-expectations na GitHubu
https://github.com/gar3thjon3s/lein-expectations - Testing Clojure With Expectations
https://semaphoreci.com/blog/2014/09/23/testing-clojure-with-expectations.html - Clojure testing TDD/BDD libraries: clojure.test vs Midje vs Expectations vs Speclj
https://www.reddit.com/r/Clojure/comments/1viilt/clojure_testing_tddbdd_libraries_clojuretest_vs/ - Testing: One assertion per test
http://blog.jayfields.com/2007/06/testing-one-assertion-per-test.html - Rewriting Your Test Suite in Clojure in 24 hours
http://blog.circleci.com/rewriting-your-test-suite-in-clojure-in-24-hours/ - Clojure doc: zipper
http://clojuredocs.org/clojure.zip/zipper - Clojure doc: parse
http://clojuredocs.org/clojure.xml/parse - Clojure doc: xml-zip
http://clojuredocs.org/clojure.zip/xml-zip - Clojure doc: xml-seq
http://clojuredocs.org/clojure.core/xml-seq - Parsing XML in Clojure
https://github.com/clojuredocs/guides - Clojure Zipper Over Nested Vector
https://vitalyper.wordpress.com/2010/11/23/clojure-zipper-over-nested-vector/ - Understanding Clojure's PersistentVector implementation
http://blog.higher-order.net/2009/02/01/understanding-clojures-persistentvector-implementation - Understanding Clojure's PersistentHashMap (deftwice…)
http://blog.higher-order.net/2009/09/08/understanding-clojures-persistenthashmap-deftwice.html - Assoc and Clojure's PersistentHashMap: part ii
http://blog.higher-order.net/2010/08/16/assoc-and-clojures-persistenthashmap-part-ii.html - Ideal Hashtrees (paper)
http://lampwww.epfl.ch/papers/idealhashtrees.pdf - Clojure home page
http://clojure.org/ - Clojure (downloads)
http://clojure.org/downloads - Clojure Sequences
http://clojure.org/sequences - Clojure Data Structures
http://clojure.org/data_structures - The Structure and Interpretation of Computer Programs: 2.2.1 Representing Sequences
http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-15.html#%_sec2.2.1 - The Structure and Interpretation of Computer Programs: 3.3.1 Mutable List Structure
http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-22.html#%_sec3.3.1 - Clojure – Functional Programming for the JVM
http://java.ociweb.com/mark/clojure/article.html - Clojure quick reference
http://faustus.webatu.com/clj-quick-ref.html - 4Clojure
http://www.4clojure.com/ - ClojureDoc (rozcestník s dokumentací jazyka Clojure)
http://clojuredocs.org/ - Clojure (na Wikipedia EN)
http://en.wikipedia.org/wiki/Clojure - Clojure (na Wikipedia CS)
http://cs.wikipedia.org/wiki/Clojure - SICP (The Structure and Interpretation of Computer Programs)
http://mitpress.mit.edu/sicp/ - Pure function
http://en.wikipedia.org/wiki/Pure_function - Funkcionální programování
http://cs.wikipedia.org/wiki/Funkcionální_programování - Čistě funkcionální (datové struktury, jazyky, programování)
http://cs.wikipedia.org/wiki/Čistě_funkcionální - Clojure Macro Tutorial (Part I, Getting the Compiler to Write Your Code For You)
http://www.learningclojure.com/2010/09/clojure-macro-tutorial-part-i-getting.html - Clojure Macro Tutorial (Part II: The Compiler Strikes Back)
http://www.learningclojure.com/2010/09/clojure-macro-tutorial-part-ii-compiler.html - Clojure Macro Tutorial (Part III: Syntax Quote)
http://www.learningclojure.com/2010/09/clojure-macro-tutorial-part-ii-syntax.html - Tech behind Tech: Clojure Macros Simplified
http://techbehindtech.com/2010/09/28/clojure-macros-simplified/ - Fatvat – Exploring functional programming: Clojure Macros
http://www.fatvat.co.uk/2009/02/clojure-macros.html - Eulerovo číslo
http://cs.wikipedia.org/wiki/Eulerovo_číslo - List comprehension
http://en.wikipedia.org/wiki/List_comprehension - List Comprehensions in Clojure
http://asymmetrical-view.com/2008/11/18/list-comprehensions-in-clojure.html - Clojure Programming Concepts: List Comprehension
http://en.wikibooks.org/wiki/Clojure_Programming/Concepts#List_Comprehension - Clojure core API: for macro
http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/for - cirrus machina – The Clojure for macro
http://www.cirrusmachina.com/blog/comment/the-clojure-for-macro/ - Riastradh's Lisp Style Rules
http://mumble.net/~campbell/scheme/style.txt - Dynamic Languages Strike Back
http://steve-yegge.blogspot.cz/2008/05/dynamic-languages-strike-back.html - Scripting: Higher Level Programming for the 21st Century
http://www.tcl.tk/doc/scripting.html - Java Virtual Machine Support for Non-Java Languages
http://docs.oracle.com/javase/7/docs/technotes/guides/vm/multiple-language-support.html - Třída java.lang.String
http://docs.oracle.com/javase/7/docs/api/java/lang/String.html - Třída java.lang.StringBuffer
http://docs.oracle.com/javase/7/docs/api/java/lang/StringBuffer.html - Třída java.lang.StringBuilder
http://docs.oracle.com/javase/7/docs/api/java/lang/StringBuilder.html - StringBuffer versus String
http://www.javaworld.com/article/2076072/build-ci-sdlc/stringbuffer-versus-string.html - Threading macro (dokumentace k jazyku Clojure)
https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/-> - Understanding the Clojure → macro
http://blog.fogus.me/2009/09/04/understanding-the-clojure-macro/ - clojure.inspector
http://clojure.github.io/clojure/clojure.inspector-api.html - The Clojure Toolbox
http://www.clojure-toolbox.com/ - Unit Testing in Clojure
http://nakkaya.com/2009/11/18/unit-testing-in-clojure/ - Testing in Clojure (Part-1: Unit testing)
http://blog.knoldus.com/2014/03/22/testing-in-clojure-part-1-unit-testing/ - API for clojure.test – Clojure v1.6 (stable)
https://clojure.github.io/clojure/clojure.test-api.html - Leiningen: úvodní stránka
http://leiningen.org/ - Leiningen: Git repository
https://github.com/technomancy/leiningen - leiningen-win-installer
http://leiningen-win-installer.djpowell.net/ - Clojure 1: Úvod
http://www.root.cz/clanky/clojure-aneb-jazyk-umoznujici-tvorbu-bezpecnych-vicevlaknovych-aplikaci-pro-jvm/ - Clojure 2: Symboly, kolekce atd.
http://www.root.cz/clanky/clojure-aneb-jazyk-umoznujici-tvorbu-bezpecnych-vicevlaknovych-aplikaci-pro-jvm-2-cast/ - Clojure 3: Funkcionální programování
http://www.root.cz/clanky/clojure-aneb-jazyk-umoznujici-tvorbu-bezpecnych-vicevlaknovych-aplikaci-pro-jvm-3-cast-funkcionalni-programovani/ - Clojure 4: Kolekce, sekvence a lazy sekvence
http://www.root.cz/clanky/clojure-aneb-jazyk-umoznujici-tvorbu-bezpecnych-vicevlaknovych-aplikaci-pro-jvm-4-cast-kolekce-sekvence-a-lazy-sekvence/ - Clojure 5: Sekvence, lazy sekvence a paralelní programy
http://www.root.cz/clanky/clojure-a-bezpecne-aplikace-pro-jvm-sekvence-lazy-sekvence-a-paralelni-programy/ - Clojure 6: Podpora pro paralelní programování
http://www.root.cz/clanky/programovaci-jazyk-clojure-6-futures-nejsou-jen-financni-derivaty/ - Clojure 7: Další funkce pro paralelní programování
http://www.root.cz/clanky/programovaci-jazyk-clojure-7-dalsi-podpurne-prostredky-pro-paralelni-programovani/ - Clojure 8: Identity, stavy, neměnné hodnoty a reference
http://www.root.cz/clanky/programovaci-jazyk-clojure-8-identity-stavy-nemenne-hodnoty-a-referencni-typy/ - Clojure 9: Validátory, pozorovatelé a kooperace s Javou
http://www.root.cz/clanky/programovaci-jazyk-clojure-9-validatory-pozorovatele-a-kooperace-mezi-clojure-a-javou/ - Clojure 10: Kooperace mezi Clojure a Javou
http://www.root.cz/clanky/programovaci-jazyk-clojure-10-kooperace-mezi-clojure-a-javou-pokracovani/ - Clojure 11: Generátorová notace seznamu/list comprehension
http://www.root.cz/clanky/programovaci-jazyk-clojure-11-generatorova-notace-seznamu-list-comprehension/ - Clojure 12: Překlad programů z Clojure do bajtkódu JVM I:
http://www.root.cz/clanky/programovaci-jazyk-clojure-12-preklad-programu-z-clojure-do-bajtkodu-jvm/ - Clojure 13: Překlad programů z Clojure do bajtkódu JVM II:
http://www.root.cz/clanky/programovaci-jazyk-clojure-13-preklad-programu-z-clojure-do-bajtkodu-jvm-pokracovani/ - Clojure 14: Základy práce se systémem maker
http://www.root.cz/clanky/programovaci-jazyk-clojure-14-zaklady-prace-se-systemem-maker/ - Clojure 15: Tvorba uživatelských maker
http://www.root.cz/clanky/programovaci-jazyk-clojure-15-tvorba-uzivatelskych-maker/ - Clojure 16: Složitější uživatelská makra
http://www.root.cz/clanky/programovaci-jazyk-clojure-16-slozitejsi-uzivatelska-makra/ - Clojure 17: Využití standardních maker v praxi
http://www.root.cz/clanky/programovaci-jazyk-clojure-17-vyuziti-standardnich-maker-v-praxi/ - Clojure 18: Základní techniky optimalizace aplikací
http://www.root.cz/clanky/programovaci-jazyk-clojure-18-zakladni-techniky-optimalizace-aplikaci/ - Clojure 19: Vývojová prostředí pro Clojure
http://www.root.cz/clanky/programovaci-jazyk-clojure-19-vyvojova-prostredi-pro-clojure/ - Clojure 20: Vývojová prostředí pro Clojure (Vimu s REPL)
http://www.root.cz/clanky/programovaci-jazyk-clojure-20-vyvojova-prostredi-pro-clojure-integrace-vimu-s-repl/ - Clojure 21: ClojureScript aneb překlad Clojure do JS
http://www.root.cz/clanky/programovaci-jazyk-clojure-21-clojurescript-aneb-preklad-clojure-do-javascriptu/ - Clojure.org: Vars and the Global Environment
http://clojure.org/Vars - Clojure.org: Refs and Transactions
http://clojure.org/Refs - Clojure.org: Atoms
http://clojure.org/Atoms - Clojure.org: Agents as Asynchronous Actions
http://clojure.org/agents - Transient Data Structureshttp://clojure.org/transients