Byla vydána nová major verze 28.0 programovacího jazyka Erlang (Wikipedie) a související platformy OTP (Open Telecom Platform, Wikipedie). Přehled novinek v příspěvku na blogu.
Český telekomunikační úřad zveřejnil Výroční zprávu za rok 2024 (pdf), kde shrnuje své aktivity v loňském roce a přináší i základní popis situace na trhu. Celkový objem přenesených mobilních dat za rok 2024 dosáhl dle odhadu hodnoty přibližně 1,73 tis. PB a jeho meziroční nárůst činí zhruba 30 %. Průměrná měsíční spotřeba dat na datovou SIM kartu odhadem dosáhla 12,5 GB – v předchozím roce šlo o 9,8 GB.
Z novinek představených na Google I/O 2025: Přehledy od AI (AI Overviews) se rozšiřují do dalších zemí. Užitečné, syntetizované přehledy od generativní AI jsou nově k dispozici i českým uživatelům Vyhledávače.
Šestice firem označovaných jako „MAMAAN“ – tedy Meta (Facebook, Instagram), Alphabet (Google), Microsoft, Apple, Amazon a Netflix – je zodpovědná za více než padesát procent světového internetového provozu. Dalšími velkými hráči jsou TikTok a Disney+. Společně tak zásadně určují podobu digitálního prostředí, spotřebitelského chování i budoucích trendů v oblasti technologií. I přesto, že se podíl těchto gigantů od roku 2023 o něco snížil, jejich dominantní postavení zvyšuje volání po regulaci.
Evropská komise (EK) navrhuje zavést plošný poplatek ve výši dvou eur (zhruba 50 Kč) za každý malý balík vstupující do Evropské unie. Poplatek se má týkat balíků v hodnotě do 150 eur (zhruba 3700 Kč), které v EU nepodléhají clu. V loňském roce bylo do EU doručeno kolem 4,6 miliardy takovýchto balíků. Poplatek má krýt náklady na kontroly rostoucího počtu zásilek levného zboží, které pochází především z Číny.
Dnes a zítra probíhá vývojářská konference Google I/O 2025. Sledovat lze na YouTube a na síti 𝕏 (#GoogleIO).
V Bostonu probíhá konference Red Hat Summit 2025. Vybrané přednášky lze sledovat na YouTube. Dění lze sledovat na síti 𝕏 (#RHSummit).
Společnost Red Hat oficiálně oznámila vydání Red Hat Enterprise Linuxu 10. Vedle nových vlastností přináší také aktualizaci ovladačů a předběžné ukázky budoucích technologií. Podrobnosti v poznámkách k vydání.
Tuto sobotu 24. května se koná historicky první komunitní den projektu Home Assistant. Zváni jsou všichni příznivci, nadšenci a uživatelé tohoto projektu. Pro účast je potřebná registrace. Odkazy na akce v Praze a v Bratislavě.
Troy Hunt představil Have I Been Pwned 2.0, tj. nový vylepšený web služby, kde si uživatelé mohou zkontrolovat, zda se jejich hesla a osobní údaje neobjevily v únicích dat a případně se nechat na další úniky upozorňovat.
1. Práce se soubory
1.1 Nutné základy
1.2 Metoda gets
1.3 Metoda getc
1.4 Metoda read
1.5 Metoda readlines
1.6 Metoda each
(each_line
)
1.7 Metoda each_byte
1.8 Metoda lineno
1.9 Zápis do souboru
2. Ošetření výjimek
2.1 O co se jedná
2.2 begin...rescue...ensure...end
3. Kontakt s operačním systémem
3.1 Standardní vstup a výstup
3.2 Návratová hodnota skriptu
3.3 Spuštění s parametry
3.4 Název skriptu
3.5 Proměnné prostředí
3.6 Spouštění externích příkazů
4. Závěr
Píšeme-li program nebo skript, vyskytnou se situace, kdy budeme potřebovat pracovat s externími textovými soubory a klasické přesměrování vstupu a výstupu nám přestane stačit.
Příkaz File.open(soubor, mód)
vrací objekt
typu File
a jako parametry jsou mu předány název souboru a
mód. Mód udává to, co se souborem zamýšlíme dělat:
zápis: | význam: |
---|---|
r |
Otevře soubor pro čtení, ukazatel je na začátku souboru. Pokud soubor neexistuje, je vyvolána výjimka (viz dále). |
r+ |
Otevře soubor pro čtení i zápis, ukazatel je na začátku souboru. Pokud soubor neexistuje, je vyvolána výjimka. |
w |
Otevře soubor pro zápis, ukazatel je na začátku souboru. Pokud soubor existuje, je jeho obsah vymazán, pokud neexistuje, je vytvořen nový. |
w+ |
Otevře soubor pro čtení i zápis, ukazatel je na začátku souboru. Pokud soubor existuje, je jeho obsah vymazán, pokud neexistuje, je vytvořen nový. |
a |
Otevře soubor pro zápis na konec souboru, pokud soubor neexistuje, je vytvořen nový. Ukazatel je na konci souboru. |
a+ |
Otevře soubor pro čtení a zápis na konec souboru, pokud soubor neexistuje, je vytvořen nový. Ukazatel pro čtení je na začátku souboru, ukazatel pro zápis je vždy na jeho konci. |
pohadka.txt
pro čtení,
použili bychom následující zápis:
fin = File.open("pohadka.txt", "r")Jakmile je naše práce se souborem hotova, je vhodné jej zase zavřít a uvolnit tak místo v paměti počítače. To provedeme pomocí metody
close
:
fin.close
gets
Ke čtení ze souboru poskytuje jazyk Ruby hned několik užitečných metod,
z nichž jako první si ukážeme gets
. Ta slouží k načítání
jednotlivých řádků.
Pro názornost si v pracovním adresáři vytvoříme soubor
pokus.txt
s následujícím obsahem:
export PS1='\u@\h:\w\$ ' alias ls='ls --color' alias vlna='vlna -v KkSsVvZzOoUuAaIi'
V tomto adresáři spustíme nám již dobře známý interpretr
irb
a podíváme se, jak to vlastně funguje:
irb(main):001:0> bashrc = File.open("pokus.txt", "r") => #<File:pokus.txt> irb(main):002:0> bashrc.gets => "export PS1='\\u@\\h:\\w\\$ '\n" irb(main):003:0> bashrc.gets => "alias ls='ls --color'\n" irb(main):004:0> bashrc.gets => "alias vlna='vlna -v KkSsVvZzOoUuAaIi'\n" irb(main):005:0> bashrc.gets => nil irb(main):006:0> bashrc.close => nil
Z příkladu vidíme, že jakmile narazíme na konec souboru, vrátí
gets
prázdnou hodnotu nil
. Jelikož je tato
považována za false
, lze toho s výhodou využít. Jednoduchý
program pro vypsání obsahu souboru na obrazovku by pak mohl vypadat třeba
takto:
irb(main):007:0> bashrc = File.open("pokus.txt", "r") => #<File:pokus.txt> irb(main):008:0> while radek = bashrc.gets irb(main):009:1> print radek irb(main):010:1> end export PS1='\u@\h:\w\$ ' alias ls='ls --color' alias vlna='vlna -v KkSsVvZzOoUuAaIi' => nil irb(main):011:0> bashrc.close => nil
getc
Ne vždy se nám hodí čtení souboru po celých řádcích. Pro načítání
jednotlivých znaků můžeme použít metodu getc
. Ta vrací celé
číslo, které reprezentuje ASCII hodnotu načteného znaku. Chceme-li mít na
výstupu znaky samotné, musíme na ně nejprve převést celočíselné hodnoty
pomocí metody chr
:
irb(main):012:0> bashrc = File.open("pokus.txt", "r") => #<File:pokus.txt> irb(main):013:0> while znak = bashrc.getc irb(main):014:1> print znak.chr irb(main):015:1> end export PS1='\u@\h:\w\$ ' alias ls='ls --color' alias vlna='vlna -v KkSsVvZzOoUuAaIi' => nil irb(main):016:0> bashrc.close => nil
read
Na rozdíl od getc
vrací metoda read
řetězec
znaků typu String
, jejichž počet můžeme explicitně určit:
irb(main):017:0> bashrc = File.open("pokus.txt", "r") => #<File:pokus.txt> irb(main):018:0> bashrc.read(6) => "export"
Uvedeme-li více znaků než soubor ve skutečnosti obsahuje, načtou se znaky do konce souboru a zbytek je vynechán:
irb(main):019:0> bashrc.read(100) => " PS1='\\u@\\h:\\w\\$ '\nalias ls='ls --color'\nalias vlna='vlna -v KkS sVvZzOoUuAaIi'\n" irb(main):020:0> bashrc.close => nil
Konečně vynecháme-li parametr úplně, dojde k načtení celého souboru.
readlines
Metoda readlines
se od předchozích zásadně odlišuje.
Nevrací totiž jednotlivé znaky nebo řetězce znaků, ale celé pole řádků v
souboru:
irb(main):021:0> bashrc = File.open("pokus.txt", "r") => #<File:pokus.txt> irb(main):022:0> radky = bashrc.readlines => ["export PS1='\\u@\\h:\\w\\$ '\n", "alias ls='ls --color'\n", "alias vln a='vlna -v KkSsVvZzOoUuAaIi'\n"] irb(main):023:0> bashrc.close => nil
Další zajímavou vlastností je, že nám umožňuje zadat řetězec, který má
sloužit jako oddělovač pro načítání jednotlivých položek pole (implicitně
je jím konec řádku '\n
'):
irb(main):024:0> bashrc = File.open("pokus.txt", "r") => #<File:pokus.txt> irb(main):025:0> cucky = bashrc.readlines(" ") => ["export ", "PS1='\\u@\\h:\\w\\$ ", "'\nalias ", "ls='ls ", "--color'\na lias ", "vlna='vlna ", "-v ", "KkSsVvZzOoUuAaIi'\n"] irb(main):026:0> bashrc.close => nil
each
(each_line
)O metodě each
(popř. jejím synonymu each_line
)
jsme již jednou hovořili v 5.
díle našeho seriálu, kde jsme ji použili pro procházení řetězce po
jednotlivých řádcích. Nejinak je tomu se soubory. Stejného výsledku jako
cyklus z části 1.2 tedy můžeme dosáhnout následujícím způsobem:
irb(main):027:0> bashrc = File.open("pokus.txt", "r") => #<File:pokus.txt> irb(main):028:0> bashrc.each { |radek| print radek } export PS1='\u@\h:\w\$ ' alias ls='ls --color' alias vlna='vlna -v KkSsVvZzOoUuAaIi' => #<File:pokus.txt> irb(main):029:0> bashrc.close => nil
Podobně jako u tomu bylo u metody readlines
, i zde je možné
specifikovat oddělovač.
each_byte
Také metodu each_byte
jsme již probírali v souvislosti s
prací s řetězci. Omezím se proto jen na příklad, který je pro změnu
ekvivalentem ukázky z části 1.3:
irb(main):030:0> bashrc = File.open("pokus.txt", "r") => #<File:pokus.txt> irb(main):031:0> bashrc.each_byte { |znak| print znak.chr } export PS1='\u@\h:\w\$ ' alias ls='ls --color' alias vlna='vlna -v KkSsVvZzOoUuAaIi' => #<File:pokus.txt> irb(main):032:0> bashrc.close => nil
lineno
Metoda lineno
vrací vždy aktuální číslo řádku, který je
právě zpracováván. To se hodí v řadě případů, my si to ukážeme na
jednoduchém číslování řádků na výstupu:
irb(main):033:0> bashrc = File.open("pokus.txt", "r") => #<File:pokus.txt> irb(main):034:0> bashrc.each { irb(main):035:1* |radek| irb(main):036:1* printf "%4d %s", bashrc.lineno, radek irb(main):037:1> } 1 export PS1='\u@\h:\w\$ ' 2 alias ls='ls --color' 3 alias vlna='vlna -v KkSsVvZzOoUuAaIi' => #<File:pokus.txt> irb(main):038:0> bashrc.close => nil
S drobnými úpravami bychom si takto mohli generovat například HTML soubory s výpisy našich zdrojových kódů.
O nic složitější než čtení není ani zápis do souboru. K tomuto účelu
přitom můžeme využívat všech nám dosud známých metod, jakými jsou
puts
, print
, nebo printf
. Jeden
příklad za všechny:
irb(main):039:0> fout = File.open("pokus.txt", "w") => #<File:pokus.txt> irb(main):040:0> fout.puts "Zapsano prikazem puts." => nil irb(main):041:0> fout.print "Zapsano prikazem print.\n" => nil irb(main):042:0> fout.printf "PI=%4.2f\n", 3.141592 => nil irb(main):043:0> fout.close => nil
Soubor pokus.txt
by měl nyní obsahovat následující text:
Zapsano prikazem puts. Zapsano prikazem print. PI=3.14
Zvláště při práci s uživatelskými daty nastávají situace, kdy hrozí, že při nesprávné kombinaci zadaných hodnot se náš program v důsledku vzniklé chyby zhroutí. Představte si program, který od uživatele přijímá dvě číselné hodnoty a vypisuje jejich podíl. Dojde-li v takovém programu na dělení nulou, vyvolá interpretr výjimku, vypíše chybové hlášení a program se předčasně ukončí:
~$ ruby puts "Zde budeme delit nulou: " puts 3/0 puts "Tato cast programu se uz ale neprovede. :'(" ^D Zde budeme delit nulou: -:2:in `/': divided by 0 (ZeroDivisionError) from -:2
Příkazy za místem vzniku chyby tak nebudou nikdy provedeny. Podobný problém může nastat i při pokusu otevřít neexistující soubor pro čtení:
~$ ruby fin = File.open("levektekadruzab", "r") puts "Tento text nikdy nikdo nespatri." fin.close ^D -:1:in `initialize': No such file or directory - levektekadruzab (Errno::EN OENT) from -:1:in `open' from -:1
Toto chování je nejen nepříjemné pro uživatele, ale dělá také špatnou vizitku autorovi programu. Ruby proto nabízí nástroje k ošetření výjimek, které by měl každý slušný programátor využívat.
begin...rescue...ensure...end
Víme-li, že v určité části kódu hrozí předčasné ukončení v důsledku vzniku chyby, můžeme tento „nebezpečný“ blok označit a v případě vyvolání výjimky na něj patřičným způsobem zareagovat. K tomuto účelu nabízí Ruby následující konstrukci:
begin potenciálně nebezpečný kód rescue [SeznamVýjimek, …] kód vykonaný v případě vyvolání výjimky ensure kód vykonaný za každou cenu end
Vyskytne-li se v části za begin
výjimka, vykoná se kód v
bloku za klíčovým slovem rescue
. Můžeme se tak sami
rozhodnout, jak zareagovat – zda vypsat varovné hlášení, zapsat
událost do logu, ukončit program nebo se z chyby nějakým způsobem
zotavit.
irb(main):044:0> a = 42; b = 0 => 0 irb(main):045:0> begin irb(main):046:1* puts a / b # nebezpecna cast irb(main):047:1> rescue irb(main):048:1> puts "Chyba, pokus o deleni nulou!" irb(main):049:1> end Chyba, pokus o deleni nulou! => nil
Pokud za klíčovým slovem neuvedeme konkrétní typ výjimky, je použit
implicitní StandardError
. Chceme-li ale reagovat na různé
výjimky rozdílným způsobem, můžeme použít bloků rescue
i
více:
irb(main):050:0> begin irb(main):051:1* puts a / c # c neni definovano irb(main):052:1> rescue ZeroDivisionError irb(main):053:1> puts "Chyba, pokus o deleni nulou!" irb(main):054:1> rescue NameError irb(main):055:1> puts "Chyba, pouziti nedefinovane promenne." irb(main):056:1> end Chyba, pouziti nedefinovane promenne. => nil
Je zřejmé, že chybová hlášení v ukázkách jsou značně nepřesná a mnohdy
je výhodnější nechat jejich formulaci na interpretru. Naštěstí máme k
dispozici proměnnou $!
, která uchovává informace o poslední
vyvolané výjimce. Příklad s dělením nulou bychom tak mohli přepsat
takto:
irb(main):057:0> begin irb(main):058:1* puts a / b irb(main):059:1> rescue irb(main):060:1> puts "ERROR: " + $! irb(main):061:1> end ERROR: divided by 0 => nil
Za klíčovým slovem ensure
uvádíme úsek kódu, který je třeba
vykonat vždy, ať už k výjimce dojde nebo ne. Typickým příkladem je
uzavření souboru:
irb(main):062:0> begin irb(main):063:1* logfile = File.open("pokus.log", "a") irb(main):064:1> puts a / b irb(main):065:1> rescue irb(main):066:1> logfile.puts "ERROR: #{$!}" irb(main):067:1> puts "V aplikaci nastala chyba a byla ukoncena." irb(main):068:1> exit 1 irb(main):069:1> ensure irb(main):070:1* logfile.close irb(main):071:1> end V aplikaci nastala chyba a byla ukoncena. ~$
Při vypisování informací na obrazovku uživatele je vhodné rozlišovat mezi běžnými informacemi a chybovými hlášeními. Ruby proto poskytuje následující konstanty:
konstanta: | význam: |
---|---|
STDIN |
Standardní vstup. |
STDOUT |
Standardní výstup. |
STDERR |
Standardní chybový výstup. |
Ve výchozím nastavení jsou příkazy pro čtení napojeny právě na
STDIN
a příkazy pro zápis na STDOUT
, není proto
třeba tyto explicitně specifikovat. Nutné je však uvést, chceme-li text
přesměrovat na standardní chybový výstup:
~$ ruby > pokus.txt 2> pokus.err puts "Vypis na standardni vystup." STDERR.puts "Vypis na standardni chybovy vystup." ^D ~$ cat pokus.err Vypis na standardni chybovy vystup. ~$ cat pokus.txt Vypis na standardni vystup.
Stejně jako mají svou návratovou hodnotu metody, tak i jednotlivé programy informují systém o stavu, v jakém skončily. Konvence říká, že při úspěšném splnění úkolu by měly vrátit hodnotu 0, při ukočení v chybovém stavu pak malé kladné nenulové číslo.
Pro vynucení ukončení programu na libovolném místě slouží příkaz
exit
, který jsem už nenápadně propašoval do příkladu v sekci
2.2. Jako volitelný parametr přijímá celočíselnou hodnotu, která bude
vrácena systému. Je-li parametr vynechán, program se ukončí s hodnotou 0.
Drtivá většina programů a skriptů se v systémech unixového typu (Linux, *BSD, Solaris aj.) drží zásady, že je lze spouštět i bez nutnosti další interakce s uživatelem, a to předáním potřebných hodnot už při jejich spuštění. Díky tomu je možné práci s nimi automatizovat prostřednictvím skriptů nebo k nim napsat grafickou nástavbu; je proto vhodné tento přístup zachovat.
Při spuštění skriptu jsou všechny zadané parametry uloženy ve speciální
proměnné ARGV
(synonymně $*
) typu
Array
a práce s ní pro nás tedy nebude ničím novým. V
pracovním adresáři vytvořte soubor pokus.rb
s následujícím
obsahem:
ARGV.each_index { |index| printf "%2d %s\n", index, ARGV[index] }
Tento skript vypíše každý zadaný parametr na samostatný číslovaný řádek. Připomínám, že jednotlivé položky jsou v poli číslovány od nuly. Na výstupu tedy dostaneme něco takového:
~$ ruby pokus.rb prvni druhy 'a tady treti' 0 prvni 1 druhy 2 a tady treti
Je-li dávkově spouštěno více aplikací, nemusí být z chybových hlášení na první pohled zřejmé, která aplikace je vypsala. Je proto slušné ve výpisu uvést její název.
Název skriptu uchovává proměnná $0
typu
String
. Použití si ukážeme na příkladu, který přijímá přesně
jeden parametr a při jakémkoli jiném počtu vypíše informace o svém
použití:
if ARGV.length != 1 STDERR.puts "#{$0}: Chybny pocet parametru." STDERR.puts "Pouziti: #{$0} RETEZEC" exit 1 end
Tento kód opět uložíme do souboru pokus.rb
. Spuštění bez
parametrů pak proběhne následovně:
~$ ruby pokus.rb pokus.rb: Chybny pocet parametru. Pouziti: pokus.rb RETEZEC
Proměnné prostředí systému uchovává proměnná ENV
typu
Hash
. Login uživatele tak můžeme vypsat např. takto:
~$ ruby puts ENV['USER'] ^D blackened
Ke spouštění externích příkazů poskytuje Ruby hned několik ve svém chování mírně se lišících nástrojů, z nichž některé si nyní ukážeme.
Prvním způsobem je uzavření příkazu mezi zpětné apostrofy. Zadaný příkaz
je spuštěn v kopii shellu a jeho standardní výstup je navrácen jako typ
String
. Výše uvedený příklad se jménem uživatele lze proto
napsat také tímto způsobem:
~$ ruby puts `whoami` ^D blackened
Příkaz system
spustí zadaný příkaz v kopii shellu. V
případě, že tento skončí s nulovou návratovou hodnotou, je vráceno
true
, v ostatních případech false
:
~$ ruby if system("ruby pokus.rb 'Hello, World!'") puts "Program probehl v poradku." else puts "Za behu programu nastala chyba." end ^D Program probehl v poradku.
Konečně příkaz exec
nahradí současný proces zadanou
aplikací:
~$ ruby exec("date") puts "Tato cast nebude nikdy vykonana." ^D St dub 11 02:06:51 CEST 2007
Tento seriál si od začátku kladl dva cíle – být stručný a srozumitelný. Posouzení, nakolik se mi to podařilo, nechám na čtenáři. Text jsem se nicméně snažil bohatě prokládat názornými ukázkami, protože právě a jen praxí se člověk učí nejlépe.
Díky této koncepci se pochopitelně na spoustu věcí nedostalo. Pokud jste se však dočetli až sem, měli byste již být schopni pracovat nejen s jazykem samotným, ale také si další informace dohledat v jiných zdrojích.
Nástroje: Tisk bez diskuse
Tiskni
Sdílej:
File.open("fajl.txt") do |file| file.each do |line| xxx end endTim se lisi metoda
open
od new,
ktera jinak pracuje stejne, ale nelze ji predat proc
objekt. Jinak pointa toho celeho je mj. taky v tom, ze netreba zavirat soubor, zavre se automaticky pri dokonceni bloku.
class File ; def to_s ; read ; end ; end
... aneb je krasne mit neuzavrene definice trid ;)