Hlavní navigace

Nástroj Leiningen a programovací jazyk Clojure: tvorba vlastních knihoven pro veřejný repositář Clojars

Pavel Tišnovský

Při popisu nástroje Leiningen, který se používá pro tvorbu a správu projektů vytvořených v jazyce Clojure, jsme se zmínili o způsobu deklarace knihoven, na nichž projekty závisí. S využitím Leiningenu není těžké vytvořit si i vlastní plnohodnotnou knihovnu a nabídnout ji k dispozici ostatním programátorům.

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

12. Odkazy na Internetu

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:

  1. 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.
  2. 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).
  3. 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.
  4. 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.
  5. Provedení relativně rychlé kontroly syntaxe zdrojových kódů i kontroly existence volaných metod. Tuto činnost zajistí příkaz lein check.
  6. Lokální instalace projektu do specifikovaného adresáře (lein install).
  7. 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).
  8. 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.
  9. 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).
  10. 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:

  1. 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.
  2. 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).
  3. 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.
  4. 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/.
  5. 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/clojar­s/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:

11. Odkazy na předchozí části tohoto seriálu

  1. Leiningen: nástroj pro správu projektů napsaných v Clojure
    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 (2)
    http://www.root.cz/clanky/leiningen-nastroj-pro-spravu-projektu-napsanych-v-clojure-2/
  3. 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/
  4. 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/
  5. 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/
  6. 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/
  7. Programovací jazyk Clojure a databáze (1.část)
    http://www.root.cz/clanky/programovaci-jazyk-clojure-a-databaze-1-cast/
  8. Pluginy pro Leiningen
    http://www.root.cz/clanky/leiningen-nastroj-pro-spravu-projektu-napsanych-v-clojure-pluginy-pro-leiningen/
  9. 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/
  10. 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/
  11. 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/
  12. 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/
  13. 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/
  14. Seesaw: knihovna pro snadnou tvorbu GUI v jazyce Clojure
    http://www.root.cz/clanky/seesaw-knihovna-pro-snadnou-tvorbu-gui-v-jazyce-clojure/
  15. 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/
  16. 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/
  17. Programovací jazyk Clojure a práce s Gitem
    http://www.root.cz/clanky/programovaci-jazyk-clojure-a-prace-s-gitem/
  18. Programovací jazyk Clojure a práce s Gitem (2)
    http://www.root.cz/clanky/programovaci-jazyk-clojure-a-prace-s-gitem-2/
  19. Programovací jazyk Clojure – triky při práci s řetězci
    http://www.root.cz/clanky/programovaci-jazyk-clojure-triky-pri-praci-s-retezci/
  20. Programovací jazyk Clojure – triky při práci s kolekcemi
    http://www.root.cz/clanky/programovaci-jazyk-clojure-triky-pri-praci-s-kolekcemi/
  21. Programovací jazyk Clojure – práce s mapami a množinami
    http://www.root.cz/clanky/programovaci-jazyk-clojure-prace-s-mapami-a-mnozinami/
  22. Programovací jazyk Clojure – základy zpracování XML
    http://www.root.cz/clanky/programovaci-jazyk-clojure-zaklady-zpracovani-xml/
  23. Programovací jazyk Clojure – testování s využitím knihovny Expectations
    http://www.root.cz/clanky/programovaci-jazyk-clojure-testovani-s-vyuzitim-knihovny-expectations/
  24. 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/
  25. 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

  1. Clojars:
    https://clojars.org/
  2. Seznam knihoven na Clojars:
    https://clojars.org/projects
  3. Clojure Cookbook: Templating HTML with Enlive
    https://github.com/clojure-cookbook/clojure-cookbook/blob/master/07_webapps/7–11_enlive.asciidoc
  4. An Introduction to Enlive
    https://github.com/swannodette/enlive-tutorial/
  5. Enlive na GitHubu
    https://github.com/cgrand/enlive
  6. Expectations: příklady atd.
    http://jayfields.com/expectations/
  7. Expectations na GitHubu
    https://github.com/jaycfi­elds/expectations
  8. Lein-expectations na GitHubu
    https://github.com/gar3thjon3s/lein-expectations
  9. Testing Clojure With Expectations
    https://semaphoreci.com/blog/2014/09/23/tes­ting-clojure-with-expectations.html
  10. Clojure testing TDD/BDD libraries: clojure.test vs Midje vs Expectations vs Speclj
    https://www.reddit.com/r/Clo­jure/comments/1viilt/cloju­re_testing_tddbdd_librari­es_clojuretest_vs/
  11. Testing: One assertion per test
    http://blog.jayfields.com/2007/06/tes­ting-one-assertion-per-test.html
  12. Rewriting Your Test Suite in Clojure in 24 hours
    http://blog.circleci.com/rewriting-your-test-suite-in-clojure-in-24-hours/
  13. Clojure doc: zipper
    http://clojuredocs.org/clo­jure.zip/zipper
  14. Clojure doc: parse
    http://clojuredocs.org/clo­jure.xml/parse
  15. Clojure doc: xml-zip
    http://clojuredocs.org/clojure.zip/xml-zip
  16. Clojure doc: xml-seq
    http://clojuredocs.org/clo­jure.core/xml-seq
  17. Parsing XML in Clojure
    https://github.com/clojuredocs/guides
  18. Clojure Zipper Over Nested Vector
    https://vitalyper.wordpres­s.com/2010/11/23/clojure-zipper-over-nested-vector/
  19. Understanding Clojure's PersistentVector implementation
    http://blog.higher-order.net/2009/02/01/understanding-clojures-persistentvector-implementation
  20. Understanding Clojure's PersistentHashMap (deftwice…)
    http://blog.higher-order.net/2009/09/08/understanding-clojures-persistenthashmap-deftwice.html
  21. Assoc and Clojure's PersistentHashMap: part ii
    http://blog.higher-order.net/2010/08/16/assoc-and-clojures-persistenthashmap-part-ii.html
  22. Ideal Hashtrees (paper)
    http://lampwww.epfl.ch/pa­pers/idealhashtrees.pdf
  23. Clojure home page
    http://clojure.org/
  24. Clojure (downloads)
    http://clojure.org/downloads
  25. Clojure Sequences
    http://clojure.org/sequences
  26. Clojure Data Structures
    http://clojure.org/data_structures
  27. 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
  28. 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
  29. Clojure – Functional Programming for the JVM
    http://java.ociweb.com/mar­k/clojure/article.html
  30. Clojure quick reference
    http://faustus.webatu.com/clj-quick-ref.html
  31. 4Clojure
    http://www.4clojure.com/
  32. ClojureDoc (rozcestník s dokumentací jazyka Clojure)
    http://clojuredocs.org/
  33. Clojure (na Wikipedia EN)
    http://en.wikipedia.org/wiki/Clojure
  34. Clojure (na Wikipedia CS)
    http://cs.wikipedia.org/wiki/Clojure
  35. SICP (The Structure and Interpretation of Computer Programs)
    http://mitpress.mit.edu/sicp/
  36. Pure function
    http://en.wikipedia.org/wi­ki/Pure_function
  37. Funkcionální programování
    http://cs.wikipedia.org/wi­ki/Funkcionální_programová­ní
  38. Čistě funkcionální (datové struktury, jazyky, programování)
    http://cs.wikipedia.org/wi­ki/Čistě_funkcionální
  39. 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
  40. Clojure Macro Tutorial (Part II: The Compiler Strikes Back)
    http://www.learningclojure­.com/2010/09/clojure-macro-tutorial-part-ii-compiler.html
  41. Clojure Macro Tutorial (Part III: Syntax Quote)
    http://www.learningclojure­.com/2010/09/clojure-macro-tutorial-part-ii-syntax.html
  42. Tech behind Tech: Clojure Macros Simplified
    http://techbehindtech.com/2010/09/28/clo­jure-macros-simplified/
  43. Fatvat – Exploring functional programming: Clojure Macros
    http://www.fatvat.co.uk/2009/02/clo­jure-macros.html
  44. Eulerovo číslo
    http://cs.wikipedia.org/wi­ki/Eulerovo_číslo
  45. List comprehension
    http://en.wikipedia.org/wi­ki/List_comprehension
  46. List Comprehensions in Clojure
    http://asymmetrical-view.com/2008/11/18/list-comprehensions-in-clojure.html
  47. Clojure Programming Concepts: List Comprehension
    http://en.wikibooks.org/wi­ki/Clojure_Programming/Con­cepts#List_Comprehension
  48. Clojure core API: for macro
    http://clojure.github.com/clo­jure/clojure.core-api.html#clojure.core/for
  49. cirrus machina – The Clojure for macro
    http://www.cirrusmachina.com/blog/com­ment/the-clojure-for-macro/
  50. Riastradh's Lisp Style Rules
    http://mumble.net/~campbe­ll/scheme/style.txt
  51. Dynamic Languages Strike Back
    http://steve-yegge.blogspot.cz/2008/05/dynamic-languages-strike-back.html
  52. Scripting: Higher Level Programming for the 21st Century
    http://www.tcl.tk/doc/scripting.html
  53. Java Virtual Machine Support for Non-Java Languages
    http://docs.oracle.com/ja­vase/7/docs/technotes/gui­des/vm/multiple-language-support.html
  54. Třída java.lang.String
    http://docs.oracle.com/ja­vase/7/docs/api/java/lang/Strin­g.html
  55. Třída java.lang.StringBuffer
    http://docs.oracle.com/ja­vase/7/docs/api/java/lang/Strin­gBuffer.html
  56. Třída java.lang.StringBuilder
    http://docs.oracle.com/ja­vase/7/docs/api/java/lang/Strin­gBuilder.html
  57. StringBuffer versus String
    http://www.javaworld.com/ar­ticle/2076072/build-ci-sdlc/stringbuffer-versus-string.html
  58. Threading macro (dokumentace k jazyku Clojure)
    https://clojure.github.io/clo­jure/clojure.core-api.html#clojure.core/->
  59. Understanding the Clojure → macro
    http://blog.fogus.me/2009/09/04/un­derstanding-the-clojure-macro/
  60. clojure.inspector
    http://clojure.github.io/clo­jure/clojure.inspector-api.html
  61. The Clojure Toolbox
    http://www.clojure-toolbox.com/
  62. Unit Testing in Clojure
    http://nakkaya.com/2009/11/18/unit-testing-in-clojure/
  63. Testing in Clojure (Part-1: Unit testing)
    http://blog.knoldus.com/2014/03/22/tes­ting-in-clojure-part-1-unit-testing/
  64. API for clojure.test – Clojure v1.6 (stable)
    https://clojure.github.io/clo­jure/clojure.test-api.html
  65. Leiningen: úvodní stránka
    http://leiningen.org/
  66. Leiningen: Git repository
    https://github.com/techno­mancy/leiningen
  67. leiningen-win-installer
    http://leiningen-win-installer.djpowell.net/
  68. Clojure 1: Úvod
    http://www.root.cz/clanky/clojure-aneb-jazyk-umoznujici-tvorbu-bezpecnych-vicevlaknovych-aplikaci-pro-jvm/
  69. Clojure 2: Symboly, kolekce atd.
    http://www.root.cz/clanky/clojure-aneb-jazyk-umoznujici-tvorbu-bezpecnych-vicevlaknovych-aplikaci-pro-jvm-2-cast/
  70. 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/
  71. 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/
  72. 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/
  73. Clojure 6: Podpora pro paralelní programování
    http://www.root.cz/clanky/programovaci-jazyk-clojure-6-futures-nejsou-jen-financni-derivaty/
  74. Clojure 7: Další funkce pro paralelní programování
    http://www.root.cz/clanky/programovaci-jazyk-clojure-7-dalsi-podpurne-prostredky-pro-paralelni-programovani/
  75. 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/
  76. 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/
  77. Clojure 10: Kooperace mezi Clojure a Javou
    http://www.root.cz/clanky/programovaci-jazyk-clojure-10-kooperace-mezi-clojure-a-javou-pokracovani/
  78. Clojure 11: Generátorová notace seznamu/list comprehension
    http://www.root.cz/clanky/programovaci-jazyk-clojure-11-generatorova-notace-seznamu-list-comprehension/
  79. 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/
  80. 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/
  81. Clojure 14: Základy práce se systémem maker
    http://www.root.cz/clanky/programovaci-jazyk-clojure-14-zaklady-prace-se-systemem-maker/
  82. Clojure 15: Tvorba uživatelských maker
    http://www.root.cz/clanky/programovaci-jazyk-clojure-15-tvorba-uzivatelskych-maker/
  83. Clojure 16: Složitější uživatelská makra
    http://www.root.cz/clanky/programovaci-jazyk-clojure-16-slozitejsi-uzivatelska-makra/
  84. Clojure 17: Využití standardních maker v praxi
    http://www.root.cz/clanky/programovaci-jazyk-clojure-17-vyuziti-standardnich-maker-v-praxi/
  85. Clojure 18: Základní techniky optimalizace aplikací
    http://www.root.cz/clanky/programovaci-jazyk-clojure-18-zakladni-techniky-optimalizace-aplikaci/
  86. Clojure 19: Vývojová prostředí pro Clojure
    http://www.root.cz/clanky/programovaci-jazyk-clojure-19-vyvojova-prostredi-pro-clojure/
  87. 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/
  88. Clojure 21: ClojureScript aneb překlad Clojure do JS
    http://www.root.cz/clanky/programovaci-jazyk-clojure-21-clojurescript-aneb-preklad-clojure-do-javascriptu/
  89. Clojure.org: Vars and the Global Environment
    http://clojure.org/Vars
  90. Clojure.org: Refs and Transactions
    http://clojure.org/Refs
  91. Clojure.org: Atoms
    http://clojure.org/Atoms
  92. Clojure.org: Agents as Asynchronous Actions
    http://clojure.org/agents
  93. Transient Data Structureshttp://clojure.or­g/transients
Našli jste v článku chybu?
Vitalia.cz: Jmenuje se Janina a žije bez cukru

Jmenuje se Janina a žije bez cukru

Podnikatel.cz: Změny v cestovních náhradách 2017

Změny v cestovních náhradách 2017

Lupa.cz: Proč firmy málo chrání data? Chovají se logicky

Proč firmy málo chrání data? Chovají se logicky

Měšec.cz: Air Bank zruší TOP3 garanci a zdražuje kurzy

Air Bank zruší TOP3 garanci a zdražuje kurzy

120na80.cz: 5 nejčastějších mýtů o kondomech

5 nejčastějších mýtů o kondomech

Měšec.cz: U levneELEKTRO.cz už reklamaci nevyřídíte

U levneELEKTRO.cz už reklamaci nevyřídíte

Vitalia.cz: Proč vás každý zubař posílá na dentální hygienu

Proč vás každý zubař posílá na dentální hygienu

Vitalia.cz: Potvrzeno: Pobyt v lese je skvělý na imunitu

Potvrzeno: Pobyt v lese je skvělý na imunitu

120na80.cz: Co všechno ovlivňuje ženskou plodnost?

Co všechno ovlivňuje ženskou plodnost?

Vitalia.cz: Mondelez stahuje rizikovou čokoládu Milka

Mondelez stahuje rizikovou čokoládu Milka

Měšec.cz: Jak levně odeslat balík přímo z domu?

Jak levně odeslat balík přímo z domu?

Vitalia.cz: Když přijdete o oko, přijdete na rok o řidičák

Když přijdete o oko, přijdete na rok o řidičák

Podnikatel.cz: Chtějte údaje k dani z nemovitostí do mailu

Chtějte údaje k dani z nemovitostí do mailu

Podnikatel.cz: Udávání kvůli EET začalo

Udávání kvůli EET začalo

Podnikatel.cz: Podnikatelům dorazí varování od BSA

Podnikatelům dorazí varování od BSA

Podnikatel.cz: Udávání a účtenková loterie, hloupá komedie

Udávání a účtenková loterie, hloupá komedie

Vitalia.cz: Spor o mortadelu: podle Lidlu falšovaná nebyla

Spor o mortadelu: podle Lidlu falšovaná nebyla

Vitalia.cz: Láska na vozíku: Přitažliví jsme pro tzv. pečovatelky

Láska na vozíku: Přitažliví jsme pro tzv. pečovatelky

Lupa.cz: Insolvenční řízení kvůli cookies? Vítejte v ČR

Insolvenční řízení kvůli cookies? Vítejte v ČR

Měšec.cz: Kdy vám stát dá na stěhování 50 000 Kč?

Kdy vám stát dá na stěhování 50 000 Kč?