Meta-ekosystém Ruby

V jazyce Ruby se příjemně pracuje, protože má okolo sebe silný ekosystém různých nástrojů, knihoven a frameworků. Ke vzniku takového ekosystému je ale potřeba meta-ekosystém nástrojů, které zjednodušují život vývojářům jeho součástí. Ruby takovýto meta-ekosystém má a v článku si ukážeme jeho nejdůležitější součásti.

Jeden z důvodů, proč je příjemné pracovat v jazyce Ruby, je ekosystém nástrojů, knihoven a frameworků, který okolo tohoto jazyka existuje. Takový ekosystém ale nevznikne jen tak náhodou. Pokud by bylo napsání, otestování, zdokumentování a zveřejnění např. vlastní knihovny těžké, dělal by to málokdo a ekosystém by se nikdy nerozvinul.

Ukazuje se, že ve světě Ruby existuje meta-ekosystém nástrojů, které právě s těmito úlohami pomáhají. Programátor se tak může soustředit na samotný kód knihovny a nestráví spoustu času řešením nezábavných podružností. Psaní a zveřejňování knihoven v Ruby je tak velmi snadné a ekosystém díky tomu vzkvétá.

Pojďme si tento meta-ekosystém Ruby stručně představit a ukázat si, jak konkrétně programátorům ulehčuje práci. Projdeme přitom stručně jednotlivé aspekty psaní typické knihovny: kód, testy, dokumentaci a zveřejnění.

Kód

Meta-ekosystém Ruby se projevuje už při psaní kódu. Na rozdíl od mnoha jiných jazyků má totiž Ruby poměrně jasně dané konvence, jak kód psát a jak ho rozdělit do souborů a adresářů. Vyvinuly se živelně, ale existují i různá shrnutí, z nichž nejznámější je asi to od GitHubu.

Díky konvencím prakticky všechny knihovny vypadají co do stylu a struktury stejně a dá se v nich jednoduše zorientovat. To nesmírně usnadňuje přispívání do nich, což v důsledku vede k rozvoji ekosystému.

Testy

V mnohých jazycích se na psaní testů používá nějaký JUnit-like framework. Ten obvykle dovoluje testy strukturovat jen do dvojúrovňové hierarchie třída-metoda a neumožňuje je detailněji popisovat (krom komentářů v kódu). Tato omezení často vedou k nechuti psát testy a k jejich špatné struktuře.

V Ruby jde díky jeho expresivitě testy psát lépe. Řada rubyistů používá RSpec, což je DSL, ve kterém lze testy neomezeně strukturovat podle jednotlivých testovaných aspektů a popisovat je.

Pro ukázku, takto popisně můžou vypadat třeba testy jednoduchého zásobníku (strukturované podle jednotlivých metod a jejich funkcionality):

describe SimpleStack do
  # Před každým testem si připravíme prázdný a plný zásobník.
  before :each do
    @empty_stack = SimpleStack.new

    @full_stack = SimpleStack.new
    @full_stack.push "A"
    @full_stack.push "B"
    @full_stack.push "C"
  end

  # Popis metody pop.
  describe "pop" do
    it "raises an exception on an empty stack" do
      lambda { @empty_stack.pop }.should raise_error(RuntimeError)
    end

    it "returns top item" do
      @full_stack.pop.should == "C"
    end

    it "removes top item" do
      @full_stack.pop
      @full_stack.top.should == "B"
    end
  end

  # Popis metody push.
  describe "push" do
    it "adds item to the top" do
      @full_stack.push "D"
      @full_stack.top.should == "D"
    end
  end
end

Takovéto testy je snadné psát i číst. I to je jeden z důvodů, proč testy obsahuje drtivá většina knihoven v Ruby.

Pokud je váš projekt zveřejněn na GitHubu, můžete ho nechat testovat automaticky po každém commitu pomocí veřejného continuous integration serveru Travis CI. Ten umí testy spouštět proti různým verzím a implementacím Ruby (Rubinius, JRuby), a také proti různým verzím jiných knihoven či frameworků (typicky Rails). Obojí velmi usnadňuje vývoj.

Pro pořádek je nutno dodat, že v Travis CI jde testovat projekty v mnoha běžných jazycích. Možnosti nastavení pro Ruby jsou ale nejbohatší.

Máte Ruby rádi nebo byste se ho chtěli naučit? V pražské pobočce SUSE v něm děláme mnoho projektů, velkou část z nich open source. Přidejte se k nám.

Dokumentace

Každá knihovna, má-li být použitelná nejen pro autora, potřebuje dokumentaci. Asi nejčastěji používaným nástrojem pro generování dokumentace v Ruby je YARD. Zvládá jak dokumentaci vysokoúrovňovou (REDAME, popis principů, příklady,…), tak nízkoúrovňovou (popis API jednotlivých tříd a metod). Dokumentace tříd a metod syntakticky trochu připomíná JavaDoc:

# Exception raised when a command execution fails.
class ExecutionFailed < StandardError
  # ...

  # Initializes a new {ExecutionFailed} instance.
  #
  # @param [Array<Array<String>>] commands the executed commands
  #   as an array where each item is again an array containing
  #   an executed command in the first element and its arguments
  #   in the remaining ones
  # @param [Process::Status] status the executed command exit status
  # @param [String, nil] stdout the output the executed command
  #   wrote to stdout
  # @param [String, nil] stderr the output the executed command
  #   wrote to stderr
  # @param [String, nil] message the exception message
  def initialize(commands, status, stdout, stderr, message = nil)
    super(message)
    @commands = commands
    @status   = status
    @stdout   = stdout
    @stderr   = stderr
  end
end

YARD toho umí celkem hodně. Pro pohodlné psaní dokumentace je ale nejdůležitější funkcí živý náhled. Stačí spustit yard server --reload v adresáři vašeho projektu a nasměrovat prohlížeč na adresu localhost:8808. Po každém uložení zdrojových souborů se dokumentace přegeneruje a vy hned vidíte změny.

Vzhled dokumentace vygenerované YARDem

Po napsání dokumentace obvykle vyvstane problém – kam s ní? Ruby má jednoduchou odpověď: RubyDoc.info. Pokud máte svůj projekt na GitHubu, můžete na tento server jeho dokumentaci nahrát několika kliknutími. Pokud jste projekt vydali jako gem (o tom za chvíli), bude tam dokonce automaticky. U vydaných gemů je automaticky k dispozici i dokumentace ke starším verzím (to často jinde chybí).

Existence RubyDoc.info znamená, že u dokumentace není vůbec třeba řešit hosting a uživatelé mají dokumentaci ke všem knihovnám soustředěnou na jednom místě. Opět plus pro rozvoj ekosystému.

Zveřejnění

Po dopsání, otestování a zdokumentování kódu nastane čas ho zveřejnit. Na rozdíl od mnoha jiných prostředí je to v Ruby záležitost na dvě minuty (pokud to neděláte úplně poprvé).

Ruby na distribuci kódu používá systém balíčků – “gemů”. Podobně jako u dokumentace existuje centrální server RubyGems.org, kam můžete svůj balíček nahrát a ostatní si ho odsud můžou stáhnout. K vytvoření gemu stačí přidat do vašeho projektu soubor s metadaty (název projektu, popis, verze, autor, seznam souborů,…) a následně spustit dva jednoduché příkazy, které vytvoří balíček a nahrají ho na server. 

Nemusíte tedy ručně řešit žádné balení, vymýšlet kam knihovnu nahrát apod. Asi nemusím říkat, jak klíčový vliv to má na množství zveřejněných knihoven a na jejich rychlý vývoj.

Závěr

Věřím, že se mi podařilo stručně nastínit, jak různé nástroje meta-ekosystému Ruby usnadňují vytváření knihoven a umožňují soustředit se na podstatné věci místo řešení podružností. Díky tomu je ekosystém Ruby bohatý a práce v tomto jazyce příjemná. A pokud máte zkušenosti z jiných prostředí a máte pocit, že některý z aspektů probraných v článku zvládá lépe než Ruby, rád se o tom dozvím.

Autor je vývojář se zájmem o programovací jazyky, webové aplikace a problémy programování jako takového. Vystudoval informatiku na MFF UK a během studií zde i trochu učil. Aktuálně pracuje v SUSE.

Komentáře: 21

Přehled komentářů

retro Bundler
David Majda Re: Bundler
Tomáš Jukin Re: Bundler
asfas asdas
Tomáš Jukin Re: asdas
David Majda Re: asdas
omelkes Re: asdas
David Majda Re: asdas
omelkes Re: asdas
David Majda Re: asdas
vetesnik Re: asdas
srigi Re: asdas
Čelo Re: asdas
janminarik Re: asdas
vidya Re: asdas
janminarik Re: asdas
lmb Re: asdas
janminarik Re: asdas
vetesnik Re: asdas
Tomáš Jukin Skvělý článek Davide!
andrej.k yard pre javadoc
Zdroj: https://www.zdrojak.cz/?p=3719