© 2013 All rights reserved.
2

Seriál Ruby on Rails 7: Datové typy: String

Práce s řetězci v Ruby. Vysvětlení některých základních operací s řetězci.

Předchozí dva datové typy byly poměrně jednoduché, operace s nimi jsou vcelku intuitivní, a ve velké míře matematicky logické. První složitější datový typ, se kterým jsme se opět již setkali v některých ukázkových příkladech, je String.

Typ String poznáme v kódu, nebo zapisujeme, vymezen do jednoduchých apostrofů nebo uvozovek. V obou případech vzniká nová instance třídy String, rozdíl je v chování interpretu a zpracování výsledného řetězce.

I když se na první pohled jeví oba řádky identické, z pohledu interpretu a zpracování hodnot jsou úplně rozdílně, rozdíl způsobí právě uvozovací znaky, které použijeme.

Jednodušší je psaní textu do apostrofů. Slovem jednodušší se myslí z pohledu zpracování. Interpret v takovém případě řetězec vezme přesně tak jak je a tak jej zpracuje. Nekontroluje jeho obsah a nezdržuje se jeho podrobným zpracováním, na rozdíl od textu uvedeného v uvozovkách.

Uvozovky dodávají práci s řetězci nový rozměr. Text uvozený v uvozovkách bude interpretem podrobně rozebrán a upraven přesně podle jeho syntaxe, toto zpracování je samozřejmě složitější a programátor se musí sám rozhodnout, kterou z možností využije a kterou právě potřebuje.

Zpětné lomítko

První zajímavou věcí v řetězci uvedeném v uvozovkách je zpětné lomítko. Zpětné lomítko nám umožňuje vytvářet jednoduché konvence, které interpret Ruby zpracovává a vyhodnocuje. Podívejte se na tabulku povolených konvencí:

t znak tabulátoru
n znak konce řádku
r odentrování na nový řádek, oproti n odřádkuje i když řetězec nepokračuje
t znak tabulátoru
s znak prázdné mezery
\ znak zpětného lomítka
znak uvozovky

V Ruby existuje takových notací mnohem více, ovšem pro naše účely nám prozatím budě těchto několik stačit.

Můžeme si je vyzkoušet na příkladu:

Oba příklady budou parterem zpracovány a vyhodnoceny a až poté vráceny na výstup.
Zajímavá je poslední notace, která nám umožňuje psát uvozovku ve Stringu uvozeném v uvozovkách. Tuto nutnost můžeme simulovat textem psaným v apostrofech:

Zpracování výrazů v řetězci

Krom jednoduchých notací pomocí zpětného lomítka můžeme přímo v řetězci zpracovávat i složitější struktury. Toto zpracování opět vyvoláme speciální konvencí, která má tvar #{}. Všechny výrazy uvedeny mezi složenými závorkami jsou poté zpracovány a vyhodnoceny. Do řetězce je vytištěn pouze výsledek tohoto výrazu:

Při psaní výrazů se nemusíme nijak omezovat a můžeme vyhodnocovat i proměnné obsahující hodnotu. Pokud je výraz platný, interpret jej dokáže zpracovat:

Uvědomte si ovšem, že každý příklad je možné simulovat pomocí apostrofů, kde výrazy sice vyhodnocovány nejsou, ale zato jsou zpracovány rychleji (interpret je nemusí parsovat).

Velikost znaků v řetězci – capitalize, downcase, upcase, swapcase

Pro práci s řetězci nám Ruby nabízí opravdu bohatou zásobu nejrůznějších funkcí. Jaké první se podívejme na skupinu 4 funkcí, které dokáží upravit velikosti jednotlivých znaků v řetězci. Tyto funkce mají společné to, že na rozdíl od jiných funkcí, zachovávají význam a sturkturu řetězce, pouze v něm mění velikosti písmen:

  • capitalize – převede první znak na velký, ostatní znaky převede na malé
  • downcase – převede všechny znaky na malé
  • upcase – převede všechny znaky na velké
  • swapcase – prohodí velikosti písmen, malá písmena převede na velká a naopak.

Length

Funkce nám umožňuje zjistit délku řetězce. Tuto délku vrací jako typ FixNum, případně BigNum. Hodnota se počítá včetně bílých znaků na konci a na začátku řetězce.

Funkce správně vyhodnotí i délku řetězce, který obsahuje speciální notace. Tyto notace jsou nejdříve vyhodnoceny, a až poté je zjištěna délka výsledného řetězce. Můžete si vyzkoušet následující příklad:

Obsah řetězce – include?, index, empty?

Dost často se setkáte s problémem, kdy budete potřebovat zjistit o řetězci nějaké informace. Ruby nám nabízí již připravené řešení v podobě několika základních funkcí, pomocí kterých můžete svůj problém řešit, nebo na nich minimálně své řešení postavit:

  • include? – zjistí, zda řetězec obsahuje znak, nebo jiný řetězec
  • index – zjistí, na jaké pozici řetězec obsahuje daný znak, nebo jiný řetězec.
  • empty? – zjistí, zda je řetězec prázdný.

Ruby samozřejmě nabízí více podobně zaměřených funkcí, prozatím si ale vystačíme s tímto základem. Jednotlivé funkce si můžeme ukázat na příkladech.

Funkce include? vrací pouze hodnoty pravda nebo nepravda (true, false):

Index pracuje víceméně podobně, pouze s tím rozdílem, že návratová hodnota je číselný typ FixNum, který obsahuje pozici hledaného řetězce. V případě že řetězec nebyl nalezen, vrací hodnotu nil:

Poslední funkce kterou máme v této skupině uvedenou, funkce empty? opět vrací pouze hodnotu true nebo false, kdy se kontroluje, zda je řetězec prázdný:

Úprava řetězce – squeeze, strip, reverse, insert, slice, delete

Další skupina funkcí, na které se podíváme nám umožňuje již přímo řetězec upravovat, a měnit jeho tvar a strukturu.

V řetězci můžeme nahrazovat znaky, můžeme v něm měnit pořadí znaků a podobně:

  • squeeze – nahradí po sobě jdoucí stejné znaky pouze jedním znakem
  • strip – odstraní z řetězce prázdné znaky na začátku a na konci
  • reverse – vrací řetězec s obráceným pořadím znaků
  • insert – vkládá na určitou pozici řetězce jiný řetězec
  • slice – ořeže řetězec na určitou velikost
  • delete – smaže z řetězce jeho část

Jak je vidět, funkcí pro úpravu řetězců je opravdu dost a možnosti, jak se řetězcem manipulovat je celá řada.

Squeeze funguje tak, že nahrazuje po sobě jdoucí stejné znaky pouze jedním z těchto znaků. Dokáže tak například promazat přebytečné mezery v textu.

Funkci můžeme volat několika způsoby:

  • bez parametrů funkce vymaže všechny po sobě jdoucí znaky. Projde celý řetězec a pokud jsou v něm dva po sobě jdoucí znaky stejné, nechá pouze jeden z nich.
  • pokud jako parametr uvedeme znak, funkce právě tento znak bude v řetězci nahrazovat
  • navíc můžeme uvést výčet znaků, které funkce akceptovat a se kterými bude pracovat

Funkci strip bychom mohli brát jako takovou jednodušší alternativu k squeeze, kdy tato funkce dokáže nahradit bílé znaky na začátku a na konci řetězce. Funkce nemá žádný parametr, který by do něj vstupoval, ale automaticky bere v potaz všechny bílé znaky:

Reverse vrací nový řetězec, který má změněné pořadí všech znaků v řetězci. Tato funkce jednoduše vezme celý řetězec a bez jediné změny jej převrátí:

Funkce insert je co se týká použití vcelku jednoduchá, nemusíte v ní hledat žádnou složitost. Obsahuje dva vstupní parametry, z nichž první je číslo značící pozici znaku v řetězci a druhý je právě řetězec, který na danou pozici umístí: Pozice 0 je potom začátek řetězce.

Pozici můžeme zadat navíc jako zápornou hodnotu, v takovém případě se počítá od konce:

Pro ořez řetězce máme u funkce slice několik možností pro zadání podmínky ořezání. Prozatím si ukážeme pouze dvě možnosti, časem se dostaneme i k dalším (pomocí regulárních výrazů).

  • zadání rozmezí dvou čísel FixNum, kde první určuje počátek a druhé počet znaků, které v řetězci po ořezání zůstanou. První ze dvou čísel může být záporné, poté se opět počítá od konce řetězce
  • zadání rozmezím dvou celých čísel, kdy rozmezí funguje stejně jako u první možnosti

Ořezat tedy můžeme řetězec jednoduše, ale co když chceme jeho část vymazat a neznáme rozmezí, ale obsah právě té části, kterou chceme z řetězce odstranit – právě k tomu účelu nám slouží funkce delete.

Jako parametr můžeme zadat podobně jako ve funkci squeeze buď řetězec, nebo rozmezí znaků, nebo řetězců, které chceme vymazat. Funkce vrací nový řetězec, který již požadovanou část neobsahuje:

Pro práci s řetězci existuje další spousta funkcí, ke kterým se postupně dostaneme s dalšími a dalšími vědomostmi. Prozatím si vystačíme s tímto základem.

Comments are closed for this page

Tesil jsem se, ze se treba dozvim neco vic o RoR, ale 7 dilu a zatim jen datove typy ruby…bude nekdy i RoR? 🙂

Postupne, hned po Ruby.

About
Hi, i am programmer from the Czech Republic. I love web development (Ruby, Ruby on Rails, PHP, Nette) and iOS development (Objective-C, Cocoa).
To cooperate, here is my phone:
+420 608 836