Ruby on Rails a revoluce ve vývoji pro web. Část první: Ruby

Framework pro vývoj webových aplikací a stránek Ruby on Rails si za poslední dva tři roky získal takovou slávu, že jedni jsou nadšeni zcela nad míru běžně obvyklou a kážou Rails kudy chodí, druzí mluví o „pouhé módě“, „skvělém marketingu 37 Signals“ a „zbytečném hype“.
Z pohledu na významné vývojářské blogy či weby nebo videa, kde v patnácti minutách naprogramujete kompletní blog člověk rozhodně získá dojem, že Rails jsou mýtická „stříbrná kulka“ softwarového vývoje, technologie, jejíž pouhé použití či nasazení několikanásobně zvyšuje produktivitu. A k dovršení všeho na Ruby on Rails běží nejslavnější aplikace a stránky současného webu: Basecamp, Shopify, Cork'd, A List Apart či Twitter.
Není třeba si tedy klást (řečnické) otázky jako „Je Ruby on Rails stříbrná kulka?“ a podobně, ale můžeme rovnou vyložit karty. Řekněme to narovinu:
Jestliže se zabýváte vývojem pro web, Ruby on Rails je to nejzajímavější, co se za poslední dva roky na tomto poli objevilo. Rails je killer app webového vývoje.
Panebože! Slyším ty výkřiky! Ne Ajax? Ne PHP 5? Ne Script.aculo.us? Ne … Zend framework? Ne Adobe Apollo... tedy AIR? Ne. A nejenom proto, že Rails v sobě Ajax i Script.aculo.us zahrnují (a v jistém smyslu, k němuž se vrátíme, teprve akcelerují, neboli „staví na koleje“).
Rails jsou jedinečné (a v tomto smyslu „nejzajímavější“) proto, že kromě mnoha ryze technických konceptů a inovací vnesly do webového vývoje zásadní intelektuální koncepty a nové myšlenky. To je ohled, který v debatách ohledně Ruby on Rails pravidelně zapadá. Debaty ohledně Rails totiž trpí známým syndromem „to není nic nového pod sluncem“. Poučná je v tomto smyslu debata k článku „Proč bylo Ruby on Rails možné napsat pouze a jedině v Ruby?“. V ní se diskutující pravidelně vracejí k objevné myšlence, že „to samé“ je možné udělat v Pythonu nebo v Perlu, že Model-View-Controller není nic nového, že lepší než Rails je framework Django pro Python nebo Catalyst pro Perl. A další variace: to umí .NET/Java/atd. už dávno a líp, a navíc mají IDE, a striktní typování. PHP je rozšířenější, a rychlejší, a levnější na provoz. A s „free-hostingem“. Jenže na webu se nyní o ničem nemluví s takovým nadšením jako o Rails, a jasná volba pro všechny obdivované start-upy není ani .NET, ani Python. Ani PHP.
Tato diskuse totiž posuzuje Rails z omezeně technologického pohledu. A z omezeně technologického pohledu je Ruby on Rails skutečně jen další MVC webový framework. Co však Rails činí zajímavé a jedinečné jsou netechnické (ve striktním slova smyslu), intelektuální a sociální aspekty, kterými se chci zabývat v těchto článcích. Právě ty ve vývojářích vyvolávají pocit „všechno v Rails a už nikdy jinak“ a právě ty vyvolaly mohutnou vlnu nadšení a nové energie pro vývoj na webu. Postoj „všechno už tu bylo, všechno je pořád stejné, je to prostě práce“ jistě v nikom příliš entuziasmu nevzbudí. Nejprve však krátký úvod či opakování.
Co je Ruby a co je Ruby on Rails
Ruby on Rails je vývojový framework postavený na bázi vzoru Model-View-Controller (podobně jako za všechny např. Apache Struts či klon Rails pro PHP CakePHP), který automaticky mapuje URL na vnitřní řídící prvky aplikace, abstrahuje přístup k datům v databázi pomocí Object-relational mapping („řádky“ v databázi se převedou na instance objektů, „sloupce“ na jejich atributy) a obsahuje rozsáhlé pomocné knihovny pro snadné generování HTML, práci s Ajaxem, formátování dat a další. „Naučit se Ruby on Rails“ tedy znamená seznámit se s konvencemi a principy, na nichž je postavené („kde jsou šablony?“, „jak zpracuji data z formuláře?“) a naučit se programovací jazyk, který Rails používají: Ruby. Protože Ruby je základem frameworku Ruby on Rails, a jeho koncepce Rails zásadně ovlivnila, zastavíme se nejprve u něj.
Ruby, tedy programovací jazyk samotný, v němž jsou Rails napsány a v němž píšete Rails aplikace, je relativně nový jazyk, který vytvořil Yukihiro Matsumoto („Matz“), a který vychází ze základního principu: programování je tvořivá činnost, která vám má přinášet radost:
„Věřím, že — alespoň do jisté míry — je smyslem života být šťastný. Na základě tohoto přesvědčení je Ruby navrženo tak, že je nejenom snadné, ale i zábavné v něm programovat. Ruby vám umožňuje soustředit se na kreativní stránku programování, a nepřidělává vám další starosti.“
Podobnou větu v předmluvě k referenční příručce programovacího jazyka by pravděpodobně čekal málokdo. Ostatní principy Ruby jsou však z tohoto základního principu odvozené — přestože se podobné uvažování o softwarovém vývoji může zdát hardcore geekům trochu divné. Výchozí motivací Matsumota bylo vytvořit jazyk, s nímž bude radost pracovat a který dá programátorovi co nejkomfortnější vyjadřovací prostředky. Fakt, že to znamená dokonale objektově orientovaný jazyk, perfektně integrované regulární výrazy, snadno čitelnou, úspornou syntaxi a pohodlné iterátory typu 10.times {puts "ahoj"}, je přitom zcela vedlejší. Matsumoto se totiž přímo odvolává na hypotézu jazykového relativismu, která tvrdí, že vnímání světa a způsob myšlení je radikálním způsobem ovlivněno právě vyjadřovacími prostředky, tedy jazykem, kterým mluvíme. Tato hypotéza tvrdí nejenom to, že v různých jazycích myslíme různým způsobem. Ve své radikální podobě tato hypotéza v teorii Ludwiga Wittgensteina tvrdí, že to, co nemohu v jazyce vyjádřit, nemohu ani myslet (Filosofická zkoumání, §243 a následující).
Matsumoto tuto hypotézu vztahuje i na jazyky zvané programovací: programovací jazyk je totiž specifickým případem umělého jazyka, který má syntaxi, gramatiku i slovní zásobu, stejně jako jazyky přirozené. Vykládá ji tak, že čím pohodlněji se mohu vyjádřit, tím pohodlněji mohu i myslet — a v programování jde pochopitelně především o myšlení, o „výsledek“: o to, co má program dělat („nahradit všechny výrazy XXX v řetězci za YYY“, „vypsat všechny články z databáze publikované tento měsíc“, atd.). Syntaxe, gramatika, slovní zásoba, to jsou vyjadřovací prostředky, které usnadňují či znesnadňují vyjádření samotné — nejsou však vůči vyjadřované „myšlence“ nijak sekundární. Napsat program, který nahradí výraz XXX za YYY lze stejně tak v Javě, PHP, Ruby nebo assembleru, ale pohodlnost, s jakou tuto (triviální) myšlenku v jednotlivých jazycích vyjádříte, bude dost rozdílná. „V assembleru můžete napsat všechno. Nikdo ale už nechce psát v assembleru“ (Yukihiro Matsumoto, The Philosophy of Ruby).
Upozornění! Následující text srovnává syntaxi Ruby a PHP. Účelem srovnání není dokazovat, která syntaxe je „lepší“. Účelem je demonstrovat filosofii, na které je Ruby založena. Možná se vám tato filosofie bude zdát mylná, nepodstatná nebo lhostejná. Možná se vám bude zdát, že to je „stejně jedno“, že je jazyk jako jazyk a navíc je důležitější striktní typování, výkonnostní parametry nebo paletka Změnit všechny výskyty… ve „vašem IDE“. Pak vás následující argumentace asi nepřesvědčí.
Právě určitá expresivita jazyka, tedy snadnost, s jakou vyjadřuje myšlenky (programátora) je základní vlastností a rozlišovacím znakem Ruby. Rozdíl mezi „příkazem“, tak jak si jej v duchu řekneme, a skutečným kódem je v Ruby minimální. Srovnejte následující úryvek kódu v PHP, důvěrně známý všem webovým programátorům:
if ( !empty($this->email) ) echo $this->email;
Stejný úryvek v Ruby, resp. v rozšíření Rails:
print self.email unless self.email.blank?
Srovnání není určeno k posouzení toho, který jazyk je „lepší“, protože to vždy znamená otázku „lepší k čemu?“ nebo „lepší pro koho?“ a ty si zde neklademe, protože si je pokládá každý sám za sebe. Oba zápisy jsou si velmi podobné — na rovině syntaxe však první příklad připomíná spíše rovnici (matematický symbol negace, závorky), zatímco příklad druhý vypadá jako jednoduchá věta v přirozeném jazyce: „Vypiš proměnnou, pokud není prázdná“. Print something to screen, unless that something is blank — dokonce se správným slovosledem. Podmínka unless zde slouží jako modifikátor (modifier) příkazu print. To, který způsob zápisu se vám zdá přehlednější, záleží zčásti na tom, zda myslíte spíše „v rovnici“, nebo „ve větě“, a především na tom, na co jste zvyklí. Díky síle zvyku se často syntaxe Ruby zdá na první pohled „divná“. Ale při řešení abstraktních problémů je přeci jen většina z nás zvyklá přemýšlet „ve větách“, dal by se shrnout přístup Ruby.
„Vypiš proměnnou, pokud není prázdná“ je velmi, velmi triviální myšlenka. Tuto triviální myšlenku můžeme vyjádřit buď složitým, nebo jednoduchým zápisem. Symbol negace, striktní pravidla pro použití závorek — to vše je trivialitě oné myšlenky v zásadě cizí. V tom je tento příklad příznačný: programátoři webových aplikací velmi často na podobnou kontrolu hodnoty proměnné nedbají. Je otázka, zda a nakolik v tom má prsty přílišná striktnost syntaxe PHP. (Je přitom jisté, že chyby v nesprávně uzavřených nebo překřížených závorkách jsou v PHP jedny z nejčastějších.)
Vezměme si však jiný příklad, převzatý z nejoriginálnější učebnice jazyka Ruby, Why's Poignant Guide to Ruby:
5.times { print "Hurá! " }
=> ‚Hurá! Hurá! Hurá! Hurá! Hurá!‘
Five times print "Hurá", neboli „pětkrát napiš ‚Hurá!‘“ je opět věta v přirozeném jazyce, v angličtině, a opět se správným slovosledem. Vidíme, že zahrnuje „matematické znaky“ (složené uvozovky), ty ale slouží víceméně jako interpunkce — například pomlčky nebo čárky --, pro oddělení částí souvětí.
Tato „literární povaha“ je pro Ruby zcela zásadní a velmi ovlivnila právě framework Ruby on Rails. Jak říká vývojář Dan Benjamin: „Ruby vám umožňuje se skvěle vyjádřit, a nemusíte u toho psát tucty řádků komenářů — kód v Ruby je srozumitelný sám od sebe“. I programátor, který Ruby neovládá, velmi dobře porozumí kódu, jako je:
print ["banán", "citron", "ananas"].sort.last.capitalize
=> ‚Citron‘
„Porozumí“ přitom znamená: „odhadne výstup programu“, porozumí tomu, co program udělá (tedy oné „myšlence“), nikoliv nutně syntaxi. Důležité je, že uvedenému kousku kódu porozumí i neprogramátor se základní znalostí angličtiny, na rozdíl od identického kódu např. v PHP:
$a = Array("banán", "citron", "ananas");
sort($a);
print ucwords( end($a) );
=> ‚Citron‘
Z tohoto důvodu je Ruby oblíbeným a často používaným programovacím jazykem pro výuku programování. Jak říká autor knihy Learn to Program, Chris Pine, Ruby je ideálním jazykem pro výuku programování, protože psát v něm programy je za á snadné a za bé je to zábava. (Úplně jinou kapitolou v použití Ruby pro výuku programování je projekt Ruby artisty Why The Lucky Stiffa Hackety Hack, k němuž se zajisté ještě vrátíme.)
Na uvedených úryvcích kódu je ihned vidět jedna důležitá vlastnost Ruby: řetězení (chainability). Metody, které jsou volány na objektu (v tomto případě poli), vrací objekt samotný, takže lze volání metod řetězit a předávat si jej mezi nimi. (Řetězení prostřednictvím Rails ovlivnilo mnoho dalších projektů, typicky např. JavaScript frameworky Prototype.js, JQuery nebo Fry.)
Řetězení se neuplatňuje jen v případě triviálních operací jako je seřazení pole, ale i v daleko sofistikovanějších výstupech (s výjimkou přetypovací metodyto_a, neboli to array je uvedený kód na první pohled srozumitelný):
# http://www.ruby-doc.org/stdlib/libdoc/net/http/rdoc/classes/Net/HTTP.html
require 'net/http'
print Net::HTTP.get('www.google.cz', '/').match("<title>(.*)<\/title>").to_a.last
=> ‚Google‘
Podobně jako podmínkové modifikátory (print variable unless variable.blank?) je řetězení silnou zbraní Ruby, protože umožňuje psát velmi čitelný a úsporný kód: jak říká známý teorém o jazyce Python, „V úspornosti je síla“ (Succinctness is power). Nebo, jak praví známý aforismus, počítačový kód má být v první řadě čitelný pro lidi, a jen mimochodem též pro stroje.
Proč je tomu tak? Jak říká Matz: Úsporný kód znamená méně chyb — čím méně řádků kódu, tím méně chyb. A méně chyb znamená, že se cítíte chytřejší.
To je to, co Matz v uvedené přednášce nazývá „efektivita měřená počtem úderů do klávesnice“ (efficiency in keystrokes) — nikoliv efektivita z hlediska výpočetního výkonu, ale z hlediska produktivity. Úspornost a čitelnost kódu, snadno zapamatovatelná syntaxe bez obtížné „interpunkce“ — to vše slouží k tomu, aby se programátor mohl soustředit na „myšlenku“ a ne na to, jak ji vyjádřit. Lze říci, že všechny ostatní, ryze technické vlastnosti Ruby jsou podřízeny tomuto principu. Kruh se uzavírá:
Programujeme proto, že nás to baví. I když programujeme pro peníze, stejně chceme, aby nás to bavilo.
Proč tak rozsáhlý úvod do Ruby v článku, který má Ruby on Rails ve svém názvu? Protože základní principy Ruby zde shrnuté ovlivnily návrh celého frameworku Rails (ať již se jedná o princip „konvence má přednost před konfigurací“, o využití známých návrhových vzorů jako je Active Record, a další). Takže až potkáme podobný úryvek kódu:
# http://api.rubyonrails.com/classes/ActiveSupport/CoreExtensions/Numeric/Time.html#M000394
10.minutes.ago
=> Sat May 26 19:52:58 +0200 2007
nebo:
# http://api.rubyonrails.com/classes/ActionView/Helpers/DateHelper.html#M000575
t = Article.find_by_id(1).published_at
=> Sat May 26 19:02:12 +0200 2007
time_ago_in_words(t)
=> ‚about one hour‘
budeme přesně vědět, odkud vítr vane. Popularita Ruby skokově vzrostla právě díky Ruby on Rails — jak říká samotný Matz: „Rails jsou pro Ruby killer app“. Rails samotné se pak staly populárními díky tomu, že se přesně trefily do neuspokojivé situace na poli vývoje pro web, kterému vládlo (a vládne) PHP, se svými světlými i temnými stránkami, s nedostatečně ukotvenými pravidly vývoje, kdy každý vývojář objevuje Ameriku. Vzbudily v komunitě vývojářů nadšení, protože usnadnily práci s Ajaxem a vizuálními efekty a umožnily vývojářům soustředit se konečně na to, co chtějí udělat, než na to, jak toho dosáhnout. Co je ale na Rails tak fascinujícího, že o málokteré technologii se mluví s takovým nadšením? Proč prodeje knih o Ruby on Rails rostou na angloamerickém trhu nejrychleji z celé oblasti web designu? Právě tomu se bude věnovat další článek.
Poznámky a odkazy:
Všechny uvedené příklady Ruby si můžete vyzkoušet ve webové verzi konzole: http://tryruby.hobix.com/.
První vydání základní referenční příručky k Ruby, The Pickaxe Book, je přístupné online: http://www.ruby-doc.org/docs/ProgrammingRuby/
Pro neředěný zážitek z Ruby a s Ruby ovšem doporučuji dobrodružný cestopis Why's (Poignant) Guide to Ruby: http://www.poignantguide.net/
Pro další článek nemusíte znát nic více než ono video, které všechno začalo (alespoň v mém případě)
Poděkování patří Vítku Burdovi, Vráťovi Čermákovi, Petru Krontorádovi, Pavlu Šimkovi a Václavu Vančurovi za cenné podněty, připomínky, rady a opravy při přípravě článku.
~
24 komentářů