s = "witaj"
s.concat(" wiecie")    # Synonim <<. Metoda modyfikujca. Zwraca nowy obiekt s.
s.insert(5, " kochany") # To samo co s[5, 0] = " kochany". Zmienia s. Zwraca nowy obiekt s.
s.slice(0,5)            # To samo co s[0,5]. Zwraca podacuch.
s.slice!(5,8)           # Usuwanie. To samo co s[5,8]="". Zwraca usunity podacuch.
s.eql?("witaj wiecie")   # Prawda. To samo co ==.

s.length         # => 13: liczy znaki w Ruby 1.9, bajty w 1.8.
s.size           # => 13: size jest synonimem.
s.bytesize       # => 14: dugo w bajtach  tylko w Ruby 1.9.
s.empty?         # => false
"".empty?        # => true

s = "hello"
# Znajdowanie pooenia podacucha lub acucha pasujcego do wzorca.
s.index('l')         # => 2: indeks pierwszej litery l w acuchu.
s.index(?l)          # => 2: dziaa take z kodami znakw.
s.index(/l+/)        # => 2: dziaa take z wyraeniami regularnymi.
s.index('l',3)       # => 3: indeks pierwszej litery l w acuchu na lub za pozycj 3.
s.index('Ruby')      # => nil: szukany acuch nie zosta znaleziony.
s.rindex('l')        # => 3: indeks ostatniego po prawej l w acuchu.
s.rindex('l',2)      # => 2: indeks ostatniego po prawej l w acuchu na lub przed pozycj 2.
# Szukanie przedrostkw i przyrostkw: od Ruby 1.9.
s.start_with? "hell" # => true.  Zauwa, e nazwa to start_with, a nie starts_with.
s.end_with? "bells"  # => false
# Sprawdzanie obecnoci podacucha.
s.include?("ll")     # => true: hello zawiera ll.
s.include?(?H)       # => false: hello nie zawiera znaku H.
# Dopasowywanie do wzorca za pomoc wyrae regularnych.
s =~ /[aeiouy]{2}/   # => nil: w sowie hello nie ma dwch samogosek po kolei.
s.match(/[aeiouy]/) {|m| m.to_s} # => "e": zwraca pierwsz samogosk.
# Dzielenie acuchw na podacuchy wedug acucha lub wzorca rozdzielajcego.
"to jest to".split     # => ["to", "jest", "to"]: domylny podzia wedug spacji.
"hello".split('l')     # => ["he", "", "o"]
"1, 2,3".split(/,\s*/) # => ["1","2","3"]: przecinek i opcjonalna spacja.
# Podzia acucha na dwie czci plus znak rozdzielajcy. Tylko Ruby 1.9.
# Te metody zawsze zwracaj tablic zawierajc trzy acuchy:
"banan".partition("an")   # => ["b", "an", "an"]
"banana".rpartition("an") # => ["ban", "an", "a"]: zaczyna od prawej.
"a123b".partition(/\d+/)  # => ["a", "123", "b"]: dziaa take z wyraeniami regularnymi.
# Wyszukiwanie i zamienianie pierwszego (sub, sub!) lub wszystkich (gsub, gsub!)
# wystpie okrelonego acucha lub wzorca.
# Wicej informacji na temat metod sub i gsub podanych jest przy opisie wyrae regularnych.
s.sub("l", "L")            # => "heLlo": zamienia tylko pierwsze wystpienie.
s.gsub("l", "L")           # => "heLLo": zamienia wszystkie wystpienia.
s.sub!(/(.)(.)/, '\2\1')   # => "ehllo": dopasowuje i zamienia miejscami dwie pierwsze litery.
s.sub!(/(.)(.)/, "\\2\\1") # => "hello": podwjne ukoniki dla podwjnych cudzysoww.
# Metody sub i gsub mog take obliczy acuch do wstawienia w bloku.
# Dopasowuje pierwsz liter kadego sowa i zamienia j na wielk.
"hello world".gsub(/\b./) {|match| match.upcase } # => "Hello World".
# W Ruby 1.9 mona poda tablic asocjacyjn zawierajc odwzorowania dopasowa na tekst zamiany.
s.gsub(/[aeiouy]/,"a"=>0, "e"=>1, "i"=>2)  # => "h1ll"

# Metody zmieniajce wielko liter.
s = "hello"   # Metody te dziaaj tylko na znakach ASCII.
s.upcase      # => "HELLO".
s.upcase!     # => "HELLO"; modyfikuje obiekt s na miejscu.
s.downcase    # => "hello".
s.capitalize  # => "Hello": pierwsza litera wielka, reszta mae.
s.capitalize! # => "Hello": modyfikuje obiekt s na miejscu.
s.swapcase    # => "hELLO": modyfikuje wielko kadej litery.
# Porwnywanie z rozpoznawaniem wielkoci liter (tylko litery ASCII).
# Metoda casecmp dziaa jak <=>, a wic zwraca -1 dla mniejszoci, 0 dla rwnoci i +1 dla wikszoci.
"world".casecmp("WORLD")  # => 0
"a".casecmp("B")          # => -1 (<=> zwraca w tym przypadku 1).

s = "hello\r\n"      # acuch ze znakiem koca wiersza.
s.chomp!             # => "hello": usunito jeden znak koca wiersza.
s.chomp              # => "hello": nie ma adnego znaku koca wiersza, a wic nic si nie zmienia.
s.chomp!             # => nil: zwrcenie wartoci nil oznacza brak zmian.
s.chomp("o")         # => "hell": usunito o z koca acucha.
$/ = ";"             # Ustawienie globalnego separatora rekordw $/ na rednik.
"hello;".chomp       # => "hello": tym razem metoda chomp usuwa rednik.

# Metoda chop usuwa kocowy znak lub znak koca wiersza (\n, \r lub \r\n).
s = "hello\n"
s.chop!              # => "hello": usunito znak koca wiersza. Obiekt s zosta zmodyfikowany.
s.chop               # => "hell": zosta usunity ostatni znak. Obiekt s nie zosta zmodyfikowany.
"".chop              # => "": nie ma znakw do usunicia.
"".chop!             # => nil: nic si nie zmienio.
# Usunicie wszsytkich biaych znakw (wliczajc znaki \t, \r, \n) z lewej strony, prawej strony lub obu stron.
# Metody strip!, lstrip! i rstrip! modyfikuj acuch na miejscu.
s = "\t hello \n"   # Biae znaki na pocztku i na kocu.
s.strip             # => "hello".
s.lstrip            # => "hello \n".
s.rstrip            # => "\t hello".
# Wyrwnanie do lewej, wyrwnanie do prawej lub wyrodkowanie acucha w polu o szerekoci n znakw.
# Nie ma modyfikujcych wersji tych metod. Zobacz take metod printf.
s = "x"
s.ljust(3)          # => "x  "
s.rjust(3)          # => "  x"
s.center(3)         # => " x "
s.center(5, '-')    # => "--x--": jako dopenienie mona stosowa nie tylko spacje.
s.center(7, '-=')   # => "-=-x-=-": dozwolone s rne znaki jako dopenienie.

s = "A\nB"                       # Trzy znaki ASCII w dwch wierszach.
s.each_byte {|b| print b, " " }  # Drukuje 65 10 66 .
s.each_line {|l| print l.chomp}  # Drukuje AB.
# Sekwnecyjna iteracja po znakach jako jednoznakowych acuchach.
# Dziaa w Ruby 1.9 i Ruby 1.8 z bibliotek jcode:
s.each_char { |c| print c, " " } # Drukuje A \n B .
# Iteracja przez wszystkie znaki jako jednoznakowe acuchy.
# Nie dziaa w przypadku acuchw wielobajtowych w Ruby 1.8.
# Dziaa (powoli) dla acuchw wielobajtowych w Ruby 1.9:
0.upto(s.length-1) {|n| print s[n,1], " "}
# W Ruby 1.9 bajty, wiersze i znaki s aliasami.
s.bytes.to_a                     # => [65,10,66]: alias dla each_byte.
s.lines.to_a                     # => ["A\n","B"]: alias dla each_line.
s.chars.to_a                     # => ["A", "\n", "B"] alias dla each_char.

"10".to_i          # => 10: konwertuje acuch na liczb cakowit.
"10".to_i(2)       # => 2: argument okrela podstaw systemu liczenia: od base-2 do base-36.
"10x".to_i         # => 10: przyrostek niebdcy liczb zostaje zignorowany. To samo dotyczy liczb szesnastkowych i semkowych.
" 10".to_i         # => 10: wiodce spacje s ignorowane.
"ten".to_i         # => 0: nie zgasza wyjtku po podaniu nieprawidowych danych.
"10".oct           # => 8: przetwarza acuch jako liczb cakowit o podstawie 8.
"10".hex           # => 16: przewarza acuch jako liczb cakowit szesnastkow.
"0xff".hex         # => 255: liczby szesnastkowe mog zaczyna si od prefiksu 0x.
" 1.1 dozen".to_f  # => 1.1: przetwarza wiodc liczb zmiennoprzecinkow.
"6.02e23".to_f     # => 6.02e+23: notacja wykadnicza jest obsugiwana.
"one".to_sym       # => :one -- konwersja acucha na symbol.
"two".intern       # => :two -- metoda intern jest synonimem metody to_sym.

# Zwikszanie acucha:
"a".succ                      # => "b": nastpca litery a. Istnieje te metoda succ!
"aaz".next                    # => "aba": metoda next jest synonimem powyszej metody. Istnieje te metoda next!
"a".upto("e") {|c| print c }  # Drukuje abcde. Iterator upto jest oparty na metodzie succ.
# Odwracanie acucha:
"hello".reverse     # => "olleh". istnieje te metoda reverse!.
# Debugging.
"hello\n".dump      # => "\"hello\\n\"": Stosuje znaki zastpcze dla znakw specjalnych.
"hello\n".inspect   # Dziaa podobnie jak metoda dump.
# Translacja z jednego zestawu znakw na inny.
"hello".tr("aeiouy", "AEIOUY") # => "hEllO": zamienia samogoski na wielkie litery. Istnieje te metoda tr!.
"hello".tr("aeiouy", " ")      # => "h ll ": konwertuje samogoski na spacje.
"bead".tr_s("aeiouy", " ")     # => "b d": konwertuje i usuwa duplikaty.
# Sumy kontrolne.
"hello".sum          # => 532: saba 16-bitowa suma kontrolna.
"hello".sum(8)       # => 20: 8-bitowa suma kontrolna zamiast 16-bitowej.
"hello".crypt("ab")  # => "abl0JrMf6tlhw": jednokierunkowa kryptograficzna suma kontrolna.
                     # Przekazuje dwa znaki alfanumeryczne jako domieszk.
                     # Wynik moe by zaleny od platformy.
# Liczenie liter, usuwanie liter, usuwanie duplikatw.
"hello".count('aeiouy')  # => 2: liczy mae samogoski.
"hello".delete('aeiouy') # => "hll": usuwa mae samogoski. Istnieje te metoda delete!.
"hello".squeeze('a-z')   # => "helo": usuwa zbiory liter. Istnieje te metoda squeeze!.
# Kiedy zostanie podanych wicej ni jeden argument, zostanie uyte przecicie zbiorw.
# Argumenty zaczynajce si od znaku ^ s negowane.
"hello".count('a-z', '^aeiouy')   # => 3: liczy mae spgoski.
"hello".delete('a-z', '^aeiouy')  # => "eo: usuwa mae spgoski.

n, animal = 2, "myszy"
"#{n+1} lepe #{animal}"  # => 3 lepe myszy.

# Alternatywy dla zaprezentowanej wyej interpolacji.
printf('%d lepe %s', n+1, animal)  # Drukuje '3 lepe myszy', zwraca warto nil.
sprintf('%d lepe %s', n+1, animal) # => '3 lepe myszy'.
'%d lepe %s' % [n+1, animal]  # Jeli jest wicej ni jeden argument, naley uy tablicy po prawej stronie.
# Formatowanie liczb.
'%d' % 10         # => '10': %d  dziesitne liczby cakowite.
'%x' % 10         # => 'a': liczby cakowite szesnastkowe.
'%X' % 10         # => 'A': due cakowite liczby szesnastkowe.
'%o' % 10         # => '12': liczby cakowite semkowe.
'%f' % 1234.567   # => '1234.567000': liczby zmiennoprzecinkowe o penej dugoci.
'%e' % 1234.567   # => '1.234567e+03': wymusza notacj wykadnicz.
'%E' % 1234.567   # => '1.234567e+03': notacja wykadnicza z liter E.
'%g' % 1234.567   # => '1234.57': sze znaczcych cyfr.
'%g' % 1.23456E12 # => '1.23456e+12': Uywaj %f lub %e w zalenoci od rzdu wielkoci.
# Szeroko pola.
'%5s' % '<<<'     # '  <<<': wyrwnanie do prawej w polu o szerokoci piciu znakw.
'%-5s' % '>>>'    # '>>>  ': wyrwnanie do lewej w polu o szerokoci piciu znakw.
'%5d' % 123       # '  123': pole ma szeroko piciu znakw.
'%05d' % 123      # '00123': dopenienie zerami w polu o szerokoci piciu znakw.
# Precyzja.
'%.2f' % 123.456  # '123.46': dwie cyfry po przecinku.
'%.2e' % 123.456  # '1.23e+02': dwie cyfry po przecinku = trzy znaczce cyfry.
'%.6e' % 123.456  # '1.234560e+02': zwr uwag na dodane zero.
'%.4g' % 123.456  # '123.5': cztery znaczce cyfry.
# Poczenie pl i precyzji.
'%6.4g' % 123.456 # ' 123.5': cztery znaczce cyfry w polu o szerokoci szeciu znakw.
'%3s' % 'ruby'    # 'ruby': argument acuchowy przekracza szeroko pola.
'%3.3s' % 'ruby'  # 'rub': precyzja wymusza obcicie acucha.
# Wiele argumentw do sformatowania.
args = ['Syntax Error', 'test.rb', 20]  # Tablica argumentw.
"%s: in '%s' line %d" % args    # => "Syntax Error: in 'test.rb' line 20".
# Te same argumenty interpolowane w innej kolejnoci! Dobre do internacjonalizacji.
"%2$s:%3$d: %1$s" % args        # => "test.rb:20: Syntax Error".

a = [1,2,3,4,5,6,7,8,9,10]  # Tablica dziesiciu liczb cakowitych.
b = a.pack('i10')           # Pakuje 10 4-bajtowych liczb cakowitych (i) do acucha binarnego b.
c = b.unpack('i*')          # Dekoduje wszystkie (*) 4-bajtowe liczby cakowite z acucha binarnego b.
c == a                      # => true
m = 'witaj wiecie'         # Komunikat do zakodowania.
data = [m.size, m]          # Najpierw dugo, potem bajty.
template = 'Sa*'            # Liczba typu short bez znaku, dowolna liczba znakw ASCII.
b = data.pack(template)     # => "\v\000witaj wiecie".
b.unpack(template)          # => [11, "witaj wiecie"].

/Ruby?/  # Dopasowuje tekst Rub, po ktrym moe opcjonalnie by litera y.

/ruby?/i  # Bez rozrniania wielkich i maych liter: dopasowuje "ruby" lub "RUB" itd.
/./mu     # Dopasowuje znaki Unicode w trybie Multiline.

%r|/|         # Dopasowuje jeden ukonik, nie potrzeba znaku unikowego.
%r[</(.*)>]i  # Mona te uywa znakw znacznikw w tej skadni.

/\(\)/     # Dopasowuje otwierajcy i zamykajcy nawias.
/\\/       # Dopasowuje jeden lewy ukonik.

money = /[$\u20AC\u{a3}\u{a5}]/ # Dopasowuje symbol dolara, euro, funta lub jena.

prefix = ","
/#{prefix}\t/   # Dopasowuje przecinek, po ktrym znajduje si znak ASCII tabulatora.

[1,2].map{|x| /#{x}/}   # => [/1/, /2/]
[1,2].map{|x| /#{x}/o}  # => [/1/, /1/]

Regexp.new("Ruby?")                          # /Ruby?/
Regexp.new("ruby?", Regexp::IGNORECASE)      # /ruby?/i
Regexp.compile(".", Regexp::MULTILINE, "u")  # /./mu

pattern = "[a-z]+"                # Jedna lub wicej liter.
suffix = Regexp.escape("()")      # Te znaki s traktowane literalnie.
r = Regexp.new(pattern + suffix)  # /[a-z]+\(\)/

# Dopasowuje dowoln z piciu nazw jzykw.
pattern = Regexp.union("Ruby", "Perl", "Python", /Java(Script)?/)
# Dopasowuje pust par nawiasw, nawiasw kwadratowych lub klamr. Stosowanie sekwencji specjalnych jest zautomatyzowane.
Regexp.union("()", "[]", "{}")   # => /\(\)|\[\]|\{\}/

# Znaki literalne.
/ruby/             # Dopasowuje ruby. Wikszo znakw dopasowuje same siebie.
/Y/                # Dopasowuje symbol jena. Znaki wielobajtowe s obsugiwane
                   # przez Ruby 1.9 i Ruby 1.8.
# Klasy znakw.
/[Rr]uby/          # Dopasowuje Ruby lub ruby.
/rub[ye]/          # Dopasowuje ruby lub rube.
/[aeiouy]/         # Dopasowuje kad pojedyncz ma samogosk.
/[0-9]/            # Dopasowuje kad cyfr, to samo co /[0123456789]/.
/[a-z]/            # Dopasowuje kad ma liter ASCII.
/[A-Z]/            # Dopasowuje kad wielk liter ASCII.
/[a-zA-Z0-9]/      # Dopasowuje kade z powyszych.
/[^aeiouy]/        # Dopasowuje wszystko, co nie jest ma samogosk.
/[^0-9]            # Dopasowuje wszystko, co nie jest cyfr.
# Klasy znakw specjalnych.
/./                # Dopasowuje kady znak z wyjtkiem nowego wiersza.
/./m               # W trybie wielowierszowym znak . dopasowuje nowy wiersz.
/\d/               # Dopasowuje cyfr  /[0-9]/.
/\D/               # Dopasowuje kady znak niebdcy cyfr  /[^0-9]/.
/\s/               # Dopasowuje biae znaki  /[ \t\r\n\f]/.
/\S/               # Dopasowuje znaki niebdce biaymi  /[^ \t\r\n\f]/.
/\w/               # Dopasowuje jeden znak sowa  ze zbioru /[A-Za-z0-9_]/.
/\W/               # Dopasowuje jeden znak niebdcy znakiem sowa  nalecy do zbioru /[^A-Za-z0-9_]/.
# Repetition.
/ruby?/            # Dopasowuje rub lub ruby  litera y jest opcjonalna.
/ruby*/            # Dopasowuje rub plus 0 lub wicej liter y.
/ruby+/            # Dopasowuje rub plus 1 lub wicej liter y.
/\d{3}/            # Dopasowuje dokadnie trzy cyfry.
/\d{3,}/           # Dopasowuje trzy lub wicej cyfr.
/\d{3,5}/          # Dopasowuje 3, 4 lub 5 cyfr.
# Powtarzanie niezachanne  dopasowywanie najmniejszej liczby powtrze.
/<.*>/             # Powtarzanie zachanne  dopasowuje <ruby>perl>.
/<.*?>/            # Niezachanne  dopasowuje <ruby> w <ruby>perl>.
                   # Kolejne niezachanne  ??, +? i {n,m}?.
# Grupowanie za pomoc nawiasw.
/\D\d+/            # Bez grupowania  + powtarza \d.
/(\D\d)+/          # Zgrupowane  + powtarza par \D\d.
/([Rr]uby(, )?)+/  # Dopasowuje Ruby, Ruby, ruby, ruby itd.
# Odwoania wstecz  ponowne dopasowywanie wczeniej dopasowanych grup.
/([Rr])uby&\1ails/ # Dopasowuje ruby&rails lub Ruby&Rails.
/(['"])[^\1]*\1/   # acuch w cudzysowach pojedynczych lub podwjnych.
                   #   \1 dopasowuje to, co dopasowaa pierwsza grupa.
                   #   \2 dopasowuje to, co dopasowaa druga grupa itd.
# Nazwane grupy i odwoania wstecz w Ruby 1.9: dopasowanie 4-literowaego palindromu.
/(?<first>\w)(?<second>\w)\k<second>\k<first>/
/(?'first'\w)(?'second'\w)\k'second'\k'first'/ # Alternatywna skadnia.
# Alternatywne rozwizania.
/ruby|rube/        # Dopasowuje ruby lub rube.
/rub(y|le))/       # Dopasowuje ruby lub ruble.
/ruby(!+|\?)/      # Dopasowuje ruby z jednym lub wicej znakw ! albo jednym znakiem ?.
# Zakotwiczenia  okrelanie pozycji dopasowania.
/^Ruby/            # Dopasowuje Ruby na pocztku acucha lub wewntrznego wiersza.
/Ruby$/            # Dopasowuje Ruby na kocu acucha lub wiersza.
/\ARuby/           # Dopasowuje Ruby na pocztku acucha.
/Ruby\Z/           # Dopasowuje Ruby na kocu acucha.
/\bRuby\b/         # Dopasowuje Ruby na granicy sowa.
/\brub\B/          # \B jest granic cigu znakw niebdcego caym sowem:
                   #   Dopasowuje rub w rube i ruby, ale niesamodzielne.
/Ruby(?=!)/        # Dopasowuje Ruby, jeli znajduje si po nim wykrzyknik.
/Ruby(?!!)/        # Dopasowuje Ruby, jeli nie ma po nim wykrzyknika.
# Specjalna skadnia z nawiasami.
/R(?#comment)/     # Dopasowuje R. Caa reszta jest komentarzem.
/R(?i)uby/         # Nie rozrnia maych i wielkich liter, dopasowujc uby.
/R(?i:uby)/        # To samo.
/rub(?:y|le))/     # Grupowanie tylko bez tworzenia odwoania wstecz typu \1.
# Opcja x dopuszcza komentarze i ignoruje biae znaki.
/  # To nie jest komentarz Ruby. To jest literalna cz
   # wyraenia regularnego, ktra jest ignorowana.
   R      # Dopasowuje pojedyncz liter R,
   (uby)+ # po ktrej znajduje si jeden lub wicej cigw uby.
   \      # Dla nieignorowanych spacji naley uywa wstecznych ukonikw.
/x                 # Ogranicznik zamykajcy. Nie zapomnij o opcji x!

pattern = /Ruby?/i      # Dopasowuje Rub lub Ruby bez rozrniania wielkoci liter.
pattern =~ "backrub"    # Zwraca 4.
"rub ruby" =~ pattern   # 0
pattern =~ "r"          # nil

"hello" =~ /e\w{2}/     # 1: Dopasowanie litery e, po ktrej znajduj si dwa znaki.
$~.string               # hello  cay acuch.
$~.to_s                 # ell  cz, ktra pasowaa.
$~.pre_match            # h  cz znajdujca si przed dopasowanym fragmentem.
$~.post_match           # o  cz znajdujca si za dopasowanym fragmentem.

# To jest wzorzec z trzema podwzorcami.
pattern = /(Ruby|Perl)(\s+)(rocks|sucks)!/
text = "Ruby\trocks!"     # Tekst pasujcy do wzorca.
pattern =~ text           # => 0: wzorzec dopasowa pierwszy znak.
data = Regexp.last_match  # => Sprawdzenie szczegowych informacji o dopasowaniu.
data.size                 # => 4: Obiekty MatchData zachowuj si jak tablice.
data[0]                   # => "Ruby\trocks!": cay dopasowany tekst.
data[1]                   # => Ruby  tekst pasujcy do pierwszego podwzorca.
data[2]                   # => \t  tekst pasujcy do drugiego podwzorca.
data[3]                   # => rocks  tekst pasujcy do trzeciego podwzorca.
data[1,2]                 # => ["Ruby", "\t"]
data[1..3]                # => ["Ruby", "\t", "rocks"]
data.values_at(1,3)       # => ["Ruby", "rocks"]  tylko wybrane indeksy.
data.captures             # => ["Ruby", "\t", "rocks"]  tylko podwzorce.
Regexp.last_match(3)      # => "rocks": to samo, co Regexp.last_match[3].
# Pocztek i koniec dopasowania.
data.begin(0)             # => 0: indeks pocztkowy caego dopasowania.
data.begin(2)             # => 4: indeks pocztkowy drugiego podwzorca.
data.end(2)               # => 5: indeks kocowy drugiego podwzorca.
data.offset(3)            # => [5,10]: pocztek i koniec trzeciego podwzorca.

# Tylko Ruby 1.9.
pattern = /(?<lang>Ruby|Perl) (?<ver>\d(\.\d)+) (?<review>rocks|sucks)!/
if (pattern =~ "Ruby 1.9.1 rocks!")
  $~[:lang]            # => "Ruby".
  $~[:ver]             # => "1.9.1".
  $~["review"]         # => "rocks".
  $~.offset(:ver)      # => [5,10] pocztek i koniec numeru wersji.
end
# Nazwy grup i rzutowanie nazw grup na numery grup.
pattern.names          # => ["lang", "ver", "review"].
pattern.named_captures # => {"lang"=>[1],"ver"=>[2],"review"=>[3]}.

# Tylko Ruby 1.9.
if /(?<lang>\w+) (?<ver>\d+\.(\d+)+) (?<review>\w+)/ =~ "Ruby 1.9 rules!"
  lang     # => "Ruby".
  ver      # => "1.9".
  review   # => "rules".
end

if data = pattern.match(text)  # Lub  data = text.match(pattern).
  handle_match(data)
end

pattern.match(text) {|data| handle_match(data) }

"ruby123"[/\d+/]              # "123".
"ruby123"[/([a-z]+)(\d+)/,1]  # "ruby".
"ruby123"[/([a-z]+)(\d+)/,2]  # "123".

r = "ruby123"
r.slice!(/\d+/)  # Zwraca 123, zamienia r na ruby.

s = "jeden, dwa, trzy"
s.split            # ["jeden,","dwa,","trzy"]  domylny znak rozdzielajcy  spacja.
s.split(", ")      # ["jeden","dwa","trzy"]  znak rozdzielajcy wpisany bezporednio.
s.split(/\s*,\s*/) # ["jeden","dwa","trzy"]  spacja koo przecinka jest opcjonalna.

text = "hello world"
pattern = /l/
first = text.index(pattern)       # 2  pierwsze dopasowanie zaczyna si na drugim znaku.
n = Regexp.last_match.end(0)      # 3  koniec pierwszego dopasowania.
second = text.index(pattern, n)   # 3  wznowienie szukania od tego miejsca.
last = text.rindex(pattern)       # 9  metoda rindex szuka od koca.

phone = gets                    # Odczytanie numeru telefonicznego.
phone.sub!(/#.*$/, "")          # Usunicie komentarzy Rubiego.
phone.gsub!(/\D/, ' '=>'-')     # Ruby 1.9: usunicie wszystkiego z wyjtkiem cyfr, dodatkowo zamienia spacje na mylniki.

text.gsub!("rails", "Rails")     # Zamienia wszystkie wystpienia rails na Rails.

text.gsub!(/\brails\b/, "Rails") # Zamienia pierwsz liter na wielk.

text.gsub(/\bruby\b/i, '<b>\0</b>')

text.gsub(/\bruby\b/i, "<b>#{$&}</b>")

# Usuwa pary cudzysoww z acucha.
re = /(?<quote>['"])(?<body>[^'"]*)\k<quote>/
puts "To sa 'cudzyslowy'".gsub(re, '\k<body>')

# Uycie liter o takiej samej wielkoci w nazwach jzykw programowania.
text = "RUBY Java perl PyThOn"         # Tekst do zmodyfikowania.
lang = /ruby|java|perl|python/i        # Wzorzec do dopasowania.
text.gsub!(lang) {|l| l.capitalize }   # Poprawienie wielkoci liter.

pattern = /(['"])([^\1]*)\1/   # acuch znakw w pojedynczych lub podwjnych cudzysowach.
text.gsub!(pattern) do
  if ($1 == '"')   # Jeli to jest acuch w podwjnych cudzysowach,
    "'#$2'"        # zostanie zamieniony na pojedyncze cudzysowy.
  else             # Jeli cudzysowy byy pojedyncze,
    "\"#$2\""      # zostan zamienione na podwjne.
  end
end

# Predykaty oglne.
0.zero?        # => true (czy to jest zero?).
1.0.zero?      # => false
0.0.nonzero?   # => nil (dziaa jak false).
1.nonzero?     # => 1 (dziaa jak true).
1.integer?     # => true
1.0.integer?   # => false
1.scalar?      # => true: nie liczba zespolona. Ruby 1.9.
1.0.scalar?    # => true: nie liczba zespolona. Ruby 1.9.
Complex(1,2).scalar? # => false: liczba zespolona. W Ruby 1.8 naley doda wiersz require 'complex'.
# Predykaty dla liczb cakowitych.
0.even?        # => true (Ruby 1.9).
0.odd?         # => false
# Predykaty dla liczb zmiennoprzecinkowych.
ZERO, INF, NAN = 0.0, 1.0/0.0, 0.0/0.0  # Stae do testowania.
ZERO.finite?   # => true: czy ta liczba jest skoczona?
INF.finite?    # => false
NAN.finite?    # => false
ZERO.infinite? # => nil: czy ta liczba jest nieskoczona? Dodatnia czy ujemna?
INF.infinite?  # => 1
-INF.infinite? # => -1
NAN.infinite?  # => nil
ZERO.nan?      # => false: czy ta liczba jest nieliczb?
INF.nan?       # => false
NAN.nan?       # => true

# Metody zaokrglajce.
1.1.ceil     # =>  2 zaokrglanie w gr  najmniejsza liczba cakowita >= od argumentu.
-1.1.ceil    # => -1  zaokrglanie w gr  najmniejsza liczba cakowita >= od argumentu.
1.9.floor    # =>  1  zaokrglanie w d  najwiksza liczba cakowita <= od argumentu.
-1.9.floor   # => -2   zaokrglanie w d  najwiksza liczba cakowita <= od argumentu.
1.1.round    # =>  1  zaokrglenie do najbliszej liczby cakowitej.
0.5.round    # =>  1  zaokrglanie w stron nieskoczonoci, kiedy w poowie drogi pomidzy liczbami cakowitymi.
-0.5.round   # => -1  lub zaokrglanie w kierunku nieskoczonoci ujemnej.
1.1.truncate # =>  1  odcicie czci uamkowej  zaokrglanie w stron zera.
-1.1.to_i    # => -1  synonim metody truncate.

# Dla kadej wartoci klasy Numeric w Ruby 1.9.
[n.abs, n<=>0]                # Warto bezwzgldna oraz znak.
[n.abs, n.angle]              # Wielko oraz kt (mona uy n.polar).
[n.numerator, n.denominator]  # Licznik oraz mianownik.
[n.real, n.imag]              # Cz rzeczywista oraz urojona.
# Stae Float:mog by zalene od implementacji.
[Float::MAX, Float::MIN]      # => [1.79769313486232e+308, 2.2250738585072e-308].
Float::EPSILON # => 2.22044604925031e-16  najmniejsza rozpoznawalna rnica pomidzy dwiema liczbami zmiennoprzecinkowymi.

# Stae.
Math::PI               # => 3.14159265358979
Math::E                # => 2.71828182845905
# Pierwiastki.
Math.sqrt(25.0)        # => 5.0  pierwiastek kwadratowy.
Math.cbrt(27.0)        # => 3.0  pierwiastek szecienny; Ruby 1.9 i pniejsze.
27.0**(1.0/3.0)        # => 3.0  pierwiastek szecienny obliczony za pomoc operatora **.
# Logarytmy
Math.log10(100.0)      # => 2.0  logarytm o podstawie 10.
Math.log(Math::E**3)   # => 3.0  logarytm naturalny (o podstawie e).
Math.log2(8)           # => 3.0  logarytm o podstawie 2. Ruby 1.9 i pniejsze.
Math.log(16, 4)        # => 2.0  2nd arg to log() is the base. Ruby 1.9.
Math.exp(2)            # => 7.38905609893065  to samo, co Math::E**2.
# Trygonometria.
include Math           # Oszczdza pisanie  pozwala opuci przedrostek Math.
sin(PI/2)              # => 1.0  sinus. Argument jest podawany w radianach, nie stopniach.
cos(0)                 # => 1.0  cosinus.
tan(PI/4)              # => 1.0  tangens.
asin(1.0)/PI           # => 0.5  arcus sinus. Zobacz te metody acos i atan.
sinh(0)                # => 0.0  sinus hiperboliczny. Take cosh, tanh.
asinh(1.0)             # => 0.0  funkcja odwrotna do sinusa hiperbolicznego. Take acosh, atanh.
# Konwersja wsprzdnych kartezjaskich (x,y) na wsprzdne biegunowe (theta, r).
theta = atan2(y,x)     # Kt pomidzy osi X a lini (0,0)-(x,y).
r = hypot(x,y)         # Przeciwprostoktna  sqrt(x**2 + y**2).
# Rne funkcje.
f,e = frexp(1024.0)    # => [0.5, 11]: rozkad x na [f,e], x = f*2**e
x = ldexp(f, e)        # => 1024: oblicza x = f*2**e
erf(0.0)               # => 0.0: funkcja bdu.
erfc(0.0)              # => 1.0: 1-erf(x): komplementarna funkcja bdu.
gamma(5)               # => 24.0: zmiennoprzecinkowa funkcja gamma.
lgamma(100)            # => [359.134205369575, 1]: logarytm gamma.

require "bigdecimal"      # Zaadowanie biblioteki standardowej.
dime = BigDecimal("0.1")  # Przekazanie acucha do konstruktora, nie Float.
4*dime-3*dime == dime     # true przy uyciu klasy BigDecimal, ale false w klasie Float.
# Obliczanie miesicznych rat kredytu hipotecznego przy uyciu klasy BigDecimal.
# Zastosowanie trybu zaokrglania banker's rounding i ograniczenie do 20 cyfr.
BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_HALF_EVEN)
BigDecimal.limit(20)
principal = BigDecimal("200000")  # Zawsze przekazuje acuchy do konstruktora.
apr = BigDecimal("6.5")           # Roczna stopa oprocentowania.
years = 30                        # Okres kredytu w latach.
payments = years*12               # 12 miesicznych rat w roku.
interest = apr/100/12             # Konwersja rocznej stopy oprocentowania na miesiczn.
x = (interest+1)**payments        # Zauwa potgowania przy uyciu klasy BigDecimal.
monthly = (principal * interest * x)/(x-1)  # Obliczenie raty miesicznej.
monthly = monthly.round(2)        # Zaokrglenie do dwch miejsc po przecinku.
monthly = monthly.to_s("f")       # Konwersja na acuch nadajcy si do czytania przez czowieka.

require "complex"           # Ruby 1.8, w Ruby 1.9 metody Math dziaajce na liczbach zespolonych.
c = Complex(0.5,-0.2)       # => .5-.2i.
Complex.polar(1,Math::PI/2) # => Complex(0.0, 1.0): utworzenie na podstawie wsprzdnych biegunowych.
i = 1.im                    # => Complex(0, 1): zamiana na liczb urojon.
(2.re - 3.5.im).to_s        # => "2.5-3.5i": metoda re tylko w Ruby 1.9.
r,i = c.real, c.imag        # => [0.5,-0.2]: Cz rzeczywista, cz urojona.
m,a = c.polar               # => [dugo, kt]: Tak samo jak [c.abs,c.angle].
d = c.conj                  # => .5+.2i: zmiana znaku czci urojonej.
z = "0+0i".to_c             # Funkcja konwersji String na Complex  tylko Ruby 1.9.
10.times { z = z*z + c }    # Iteracja obliczajca fraktale zbioru Julii.
1.im**2                     # => Complex(-1,0): i*i == -1.
x = Math.sin(z)             # Modu 'complex' przedefiniowuje funkcje Math.
require 'cmath'             # Ruby 1.9: definicja moduu CMath dla matematyki na liczbach zespolonych.
CMath.sqrt(-1)==Complex::I  # => true

require "rational"           # Zaadowanie biblioteki.
penny = Rational(1, 100)     # Cent to 1/100 dolara.
require "mathn"              # Wymusza, aby dzielenie liczb cakowitych zwracao liczby cakowite.
nickel = "5/100".to_r        # Konwersja String na Rational: tylko Ruby 1.9.
dime = 10.quo 100            # => Rational(1,10).
change = 2*dime + 3*penny    # => Rational(23,100).
change.numerator             # => 23: licznik.
change.denominator           # => 100: mianownik.
change.to_f                  # => 0.23: konwersja na liczb Float.
(nickel * dime).to_s         # => "1/200".

require "matrix"
# Reprezentacja punktu (1,1) jako wektor [1,1].
unit = Vector[1,1]
# Jednostkowa macierz do transformacji.
identity = Matrix.identity(2)  # Macierz 2x2.
identity*unit == unit          # true  brak transformacji.
# Macierz skaluje punkt przez sx,sy.
sx,sy = 2.0, 3.0;
scale = Matrix[[sx,0], [0, sy]]
scale*unit             # => [2.0, 3.0]  przeskalowany punkt.
# Niniejsza macierz obraca przeciwnie do ruchu wskazwek zegara wok rodka ukadu.
theta = Math::PI/2     # 90 stopni.
rotate = Matrix[[Math.cos(theta), -Math.sin(theta)],
                [Math.sin(theta),  Math.cos(theta)]]
rotate*unit            # [-1.0, 1.0]  Obrt o 90 stopni.
# Dwie transformacje w jednym.
scale * (rotate*unit)  # [-2.0, 3.0].

rand       # => 0.964395196505186
rand       # => 0.390523655919935
rand(100)  # => 81
rand(100)  # => 32

srand(0)                # Ziarno o znanej wartoci.
[rand(100),rand(100)]   # => [44,47]  sekwencja liczb pseudolosowych.
srand(0)                # Wyzerowanie ziarna, aby powtrzy sekwencj.
[rand(100),rand(100)]   # => [44,47]

# Tworzenie obiektw klasy Time.
Time.now        # Zwraca obiekt reprezentujcy aktualny czas.
Time.new        # Synonim Time.now.
Time.local(2007, 7, 8)          # July 8, 2007.
Time.local(2007, 7, 8, 9, 10)   # July 8, 2007, 09:10am  czas lokalny.
Time.utc(2007, 7, 8, 9, 10)     # July 8, 2007, 09:10 UTC.
Time.gm(2007, 7, 8, 9, 10, 11)  # July 8, 2007, 09:10:11 GMT (to samo, co UTC).
# Jedna mikrosekunda przed rozpoczciem nowego milenium w Londynie.
# Obiektu tego bdziemy uywa w wielu przykadach poniej.
t = Time.utc(2000, 12, 31, 23, 59, 59, 999999)
# Skadniki obiektu klasy Time.
t.year    # => 2000.
t.month   # => 12  grudzie.
t.day     # => 31.
t.wday    # => 0  dzie tygodnia  0 oznacza niedziel.
t.yday    # => 366  dzie roku  2000 by rokiem przestpnym.
t.hour    # => 23  zegar dwudziestoczterogodzinny.
t.min     # => 59.
t.sec     # => 59.
t.usec    # => 999999  mikrosekundy, nie milisekundy.
t.zone    # => UTC  nazwa strefy czasowej.
# Zebranie wszystkich skadnikw w tablicy 
# [sec,min,hour,day,month,year,wday,yday,isdst,zone].
# Zauwa brak mikrosekund.
values = t.to_a    # => [59, 59, 23, 31, 12, 2000, 0, 366, false, "UTC"]
# Tego typu tablice mona przekazywa do metod Time.local i Time.utc.
values[5] += 1     # Zwikszenie roku.
Time.utc(*values)  # => Mon Dec 31 23:59:59 UTC 2001.
# Strefy czasowe i przestawianie czasu.
t.zone       # => UTC  zwraca nazw strefy czasowej.
t.utc?       # => true  t jest w strefie czasowej UTC.
t.utc_offset # => 0  UTC jest przesunite o 0 sekund wzgldem UTC.
t.localtime  # Konwersja na lokaln stref czasow. Modyfikuje obiekt klasy Time!
t.zone       # => PST (lub inna nazwa loklanej strefy czasowej).
t.utc?       # => false
t.utc_offset # => -28800  8 godzin przed UTC.
t.gmtime     # Konwersja z powrotem na UTC. Kolejny mutator.
t.getlocal   # Zwraca nowy obiekt klasy Time w lokalnej strefie.
t.getutc     # Zwraca nowy obiekt klasy Time w strefie UTC.
t.isdst      # => false: strefa UTC nie ma przestawienia czasu. Zauwa brak znaku ?.
t.getlocal.isdst # => false: nie ma przestawienia czasu w zimie.
# Predykaty dotyczce dni tygodnia  Ruby 1.9.
t.sunday?    # => true
t.monday?    # => false
t.tuesday?   # itd.
# Formatowanie dat i godzin.
t.to_s       # => Sun Dec 31 23:59:59 UTC 2000  Ruby 1.8.
t.to_s       # => 2000-12-31 23:59:59 UTC  Ruby 1.9 uywa formatu ISO-8601.
t.ctime      # => Sun Dec 31 23:59:59 2000  inny podstawowy format.
# Metoda strftime interpoluje skadniki daty i godziny do acucha szablonu.
# Formatowanie niezalene od lokalizacji.
t.strftime("%Y-%m-%d %H:%M:%S") # => 2000-12-31 23:59:59  format ISO-8601.
t.strftime("%H:%M")             # => 23:59  format 24-godzinny.
t.strftime("%I:%M %p")          # => 11:59 PM  format 12-godzinny.
# Formaty zalene od lokalizacji.
t.strftime("%A, %B %d")         # => Sunday, December 31.
t.strftime("%a, %b %d %y")      # => Sun, Dec 31 00  rok w formacie dwucyfrowym.
t.strftime("%x")                # => 12/31/00  format zaleny od lokalizacji.
t.strftime("%X")                # => 23:59:59.
t.strftime("%c")                # To samo co ctime.
# Przetwarzanie dat i godzin.
require 'parsedate'    # Obszerna biblioteka do przetwarzania dat i godzin.
include ParseDate      # Doczenie parsedate() jako funkcji globalnej.
datestring = "2001-01-01"
values = parsedate(datestring)  # [2001, 1, 1, nil, nil, nil, nil, nil].
t = Time.local(*values)         # => Mon Jan 01 00:00:00 -0800 2001.
s = t.ctime                     # => Mon Jan  1 00:00:00 2001.
Time.local(*parsedate(s))==t    # => true
s = "2001-01-01 00:00:00-0500"  # Pnoc w Nowym Jorku.
v = parsedate(s)                # => [2001, 1, 1, 0, 0, 0, "-0500", nil].
t = Time.local(*v)              # Gubi informacj o strefie czasowej!
# Dziaania arytmetyczne na czasie.
now = Time.now          # Aktualny czas.
past = now - 10         # 10 sekund wstecz. Time - liczba => Time.
future = now + 10       # 10 sekund od teraz. Time + liczba => Time.
future - now            # => 10  Time - Time => liczba sekund.
# Porwnywanie czasu.
past <=> future         # => -1
past < future           # => true
now >= future           # => false
now == now              # => true
# Metody pomocnicze dziaajce na jednostkach innych ni sekundy.
class Numeric
  # Konwersja odstpw czasu na sekundy.
  def milliseconds; self/1000.0; end
  def seconds; self; end
  def minutes; self*60; end
  def hours; self*60*60; end
  def days; self*60*60*24; end
  def weeks; self*60*60*24*7; end
  # Konwersja sekund na inne odstpy czasu.
  def to_milliseconds; self*1000; end
  def to_seconds; self; end
  def to_minutes; self/60.0; end
  def to_hours; self/(60*60.0); end
  def to_days; self/(60*60*24.0); end
  def to_weeks; self/(60*60*24*7.0); end
end
expires = now + 10.days     # 10 dni od teraz.
expires - now               # => 864000.0 sekund.
(expires - now).to_hours    # => 240.0 godzin.
# Czas reprezentowany wewntrznie w sekundach od (zalenie od platformy) epoki.
t = Time.now.to_i    # => 1184036194 sekund od epoki.
Time.at(t)           # => sekundy od epoki do obiektu Time.
t = Time.now.to_f    # => 1184036322.90872  zawiera 908720 mikrosekund.
Time.at(0)           # => Wed Dec 31 16:00:00 -0800 1969  epoka w czasie lokalnym.

(5..7).each {|x| print x }                 # Drukuje 567.
(5..7).each_with_index {|x,i| print x,i }  # Drukuje 506172.

(1..10).each_slice(4) {|x| print x } # Drukuje [1,2,3,4][5,6,7,8][9,10].

(1..5).each_cons(3) {|x| print x }    # Drukuje [1,2,3][2,3,4][3,4,5].

data = [1,2,3,4]                        # Kolekcja umoliwiajca iteracj.
roots = data.collect {|x| Math.sqrt(x)} # Zbiera pierwiastki kwadratowe podanych danych.
words = %w[witaj wiecie]               # Inna kolekcja.
upper = words.map {|x| x.upcase }       # Rzutowanie na wielkie litery.

(1..3).zip([4,5,6]) {|x| print x.inspect } # Drukuje [1,4][2,5][3,6].
(1..3).zip([4,5,6],[7,8]) {|x| print x}    # Drukuje 14725836.
(1..3).zip('a'..'c') {|x,y| print x,y }    # Drukuje 1a2b3c.
p (1..3).zip('a'..'z')                     # Drukuje [[1,"a"],[2,"b"],[3,"c"]].
p (1..3).zip('a'..'b')                     # Drukuje [[1,"a"],[2,"b"],[3,nil]].

(1..3).to_a       # => [1,2,3]
(1..3).entries    # => [1,2,3]

require 'set'
(1..3).to_set     # => #<Set: {1, 2, 3}>.

e = [1..10].to_enum              # Uywa metody Range.each.
e = "test".enum_for(:each_byte)  # Uywa metody String.each_byte.
e = "test".each_byte             # Uywa metody String.each_byte.

"Ruby".each_char.max       # => y  metoda iteracyjna enumeratora.
iter = "Ruby".each_char    # Utworzenie enumeratora.
loop { print iter.next }   # Drukuje Ruby  iterator zewntrzny.
print iter.next            # Drukuje R  iterator uruchamia si od pocztku automatycznie.
iter.rewind                # Wymuszenie ponownego rozpoczcia iteracji.
print iter.next            # Ponownie drukuje R.

# Drukuje 0:R\n1:u\n2:b\n3:y\n.
"Ruby".each_char.with_index.each {|c,i| puts "#{i}:#{c} }

w = Set['gruszka','Burak','marchewka']  # Zbir sw do posortowania.
w.sort                         # ['Burak','gruszka','marchewka']  alfabetycznie.
w.sort {|a,b| b<=>a }          # ['marchewka','gruszka','Burak']  odwrotnie.
w.sort {|a,b| a.casecmp(b) }   # ['Burak','gruszka','marchewka']  ignorowanie wielkoci liter.
w.sort {|a,b| b.size<=>a.size} # ['marchewka','gruszka','Burak']  odwrotnie wedug dugoci.

# Sortowanie bez rozrniania wielkoci liter.
words = ['marchewka', 'Burak', 'gruszka']
words.sort_by {|x| x.downcase}       # => ['Burak', 'gruszka', 'marchewka'].

primes = Set[2, 3, 5, 7]
primes.include? 2        # => true
primes.member? 1         # => false

# Znajduje pierwsz podtablic zawierajc liczb 1.
data = [[1,2], [0,1], [7,8]]
data.find {|x| x.include? 1}     # => [1,2]
data.detect {|x| x.include? 3}   # => nil  nie ma takiego elementu.

data.find_index [0,1]              # => 1  pasuje drugi element.
data.find_index {|x| x.include? 1} # => 0  pasuje pierwszy element.
data.find_index {|x| x.include? 3} # => nil  nie ma takiego elementu.

(1..8).select {|x| x%2==0}    # => [2,4,6,8]  pobiera liczby parzyste.
(1..8).find_all {|x| x%2==1}  # => [1,3,5,7]  wyszukuje liczby nieparzyste.

primes = [2,3,5,7]
primes.reject {|x| x%2==0}  # => [3,5,7]  odrzuca liczby parzyste.

(1..8).partition {|x| x%2==0}  # => [[2, 4, 6, 8], [1, 3, 5, 7]].

# Grupuje nazwy jzykw programowania wedug pierwszej litery nazwy.
langs = %w[ java perl python ruby ]
groups = langs.group_by {|lang| lang[0] }
groups # => {"j"=>["java"], "p"=>["perl", "python"], "r"=>["ruby"]}.

langs = %w[ java perl python ruby ]
langs.grep(/^p/)                    # => [perl, python]  zaczynaj si od p.
langs.grep(/^p/) {|x| x.capitalize} # => [Perl, Python]  poprawia na wielkie litery.
data = [1, 17, 3.0, 4]
ints = data.grep(Integer)           # => [1, 17, 4]  tylko liczby cakowite.
small = ints.grep(0..9)             # [1,4]  tylko z przedziau.

p (1..5).first(2)      # => [1,2]
p (1..5).take(3)       # => [1,2,3]
p (1..5).drop(3)       # => [4,5]

[1,2,3,nil,4].take_while {|x| x }  # => [1,2,3]  pobiera, a do zwrcenia wartoci nil.
[nil, 1, 2].drop_while {|x| !x }   # => [1,2]  odrzuca pocztkowe wartoci nil.

[10, 100, 1].min    # => 1
['a','c','b'].max   # => 'c'
[10, 'a', []].min   # => ArgumentError  tych elementw nie mona porwna.

langs = %w[java perl python ruby]    # Ktra nazwa jest najdusza?
langs.max {|a,b| a.size <=> b.size } # => python  blok porwnuje 2.
langs.max_by {|word| word.length }   # => python  tylko Ruby 1.9.

(1..100).minmax                   # => [1,100] min, max jako liczby.
(1..100).minmax_by {|n| n.to_s }  # => [1,99]  min, max jako acuchy.

c = -2..2
c.all? {|x| x>0}    # => false  nie wszystkie wartoci s > 0.
c.any? {|x| x>0}    # => true  niektre wartoci s > 0.
c.none? {|x| x>2}   # => true adna warto nie jest > 2.
c.one? {|x| x>0}    # => false  wicej ni jedna warto jest > 0.
c.one? {|x| x>2}    # => false  adna warto nie jest > 2.
c.one? {|x| x==2}   # => true  jedna warto == 2.
[1, 2, 3].all?      # => true  adna warto nie jest nil ani false.
[nil, false].any?   # => false  brak wartoci typu true.
[].none?            # => true  brak wartoci niebdcych nil ani false.

a = [1,1,2,3,5,8]
a.count(1)                # => 2  dwa elementy s rwne 1.
a.count {|x| x % 2 == 1}  # => 4  cztery elementy s nieparzyste.

# Ile jest liczb ujemnych?
(-2..10).inject(0) {|num, x| x<0 ? num+1 : num }  # => 2
# Suma dugoci sw.
%w[groch z kapusta].inject(0) {|total, word| total + word.length }  # => 13

sum = (1..5).inject {|total,x| total + x}  # => 15
prod = (1..5).inject {|total,x| total * x} # => 120
max = [1,3,2].inject {|m,x| m>x ? m : x}   # => 3
[1].inject {|total,x| total + x}           # => 1  blok nie jest wywoywany

sum = (1..5).reduce(:+)                    # => 15
prod = (1..5).reduce(:*)                   # => 120
letters = ('a'..'e').reduce("-", :concat)  # => "-abcde"

[1,2,3]             # Podstawowy litera tablicowy.
[]                  # Pusta tablica.
[]                  # Tablice mona modyfikowa  ta pusta tablica jest inna.
%w[a b c]           # => ['a', 'b', 'c']  tablica sw.
Array[1,2,3]        # => [1,2,3]  to samo co litera tablicowy.
# Tworzenie tablic za pomoc metody new().
empty = Array.new             # []  zwraca now pust tablic.
nils = Array.new(3)           # [nil, nil, nil]  trzy elementy nil.
copy = Array.new(nils)        # Robi kopi istniejcej tablicy.
zeros = Array.new(4, 0)       # [0, 0, 0, 0]  cztery elementy 0.
count = Array.new(3){|i| i+1} # [1,2,3]  trzy elementy obliczone przez blok.
# Naley uwaa na powtarzajce si obiekty.
a=Array.new(3,'a')  # => ['a','a','a']  trzy referencje do tego samego acucha.
a[0].upcase!        # Zamiana pierwszego elementu na wielk liter.
a                   # => ['A','A','A']  wszystkie te acuchy to ten sam acuch!
a=Array.new(3){'b'} # => ['b','b','b']  trzy osobne acuchy.
a[0].upcase!;       # Zamiana pierwszego na wielk liter.
a                   # => ['B','b','b']  pozostae acuchy pozostaj niezmienione.

# Dugo tablicy.
[1,2,3].length     # => 3
[].size            # => 0  synonim metody length.
[].empty?          # => true
[nil].empty?       # => false
[1,2,nil].nitems   # => 2  liczba elementw nie bdcych nil.
[1,2,3].nitems {|x| x>2} # => 1  liczba elementw pasujcych do bloku (Ruby 1.9 oraz Ruby 1.8.7).
# Indeksowanie pojedynczych elementw.
a = %w[a b c d]    # => ['a', 'b', 'c', 'd']
a[0]               # => 'a'  pierwszy element.
a[-1]              # => 'd'  ostatni element.
a[a.size-1]        # => 'd'  ostatni element.
a[-a.size]         # => 'a'  pierwszy element.
a[5]               # => nil  nie ma takiego elementu.
a[-5]              # => nil  nie ma takiego elementu.
a.at(2)            # => 'c'  to samo, co [] dla pojedynczego argumentu.
a.fetch(1)         # => 'b'  rwnie to samo co [] i at.
a.fetch(-1)        # => 'd'  dziaa z argumentami ujemnymi.
a.fetch(5)         # => IndexError!  nie pozwala na wyjcie poza granice.
a.fetch(-5)        # => IndexError!  nie pozwala na wyjcie poza granice.
a.fetch(5, 0)      # => 0  zwraca drugi argument, jeli wyjdzie poza granice.
a.fetch(5){|x|x*x} # => 25  oblicza warto, jeli wyjdzie poza granice.
a.first            # => 'a'  pierwszy element.
a.last             # => 'd'  ostatni element.
a.choice           # Ruby 1.9  zwraca jeden losowy element.
# Indeksowanie podtablic.
a[0,2]             # => ['a','b']  dwa elementy, zaczynajc od 0.
a[0..2]            # => ['a','b','c']  elementy z indeksem nalecym do zbioru.
a[0...2]           # => ['a','b']  trzy kropki zamiast dwch.
a[1,1]             # => ['b']  pojedynczy element jako tablica.
a[-2,2]            # => ['c','d']  dwa ostatnie elementy.
a[4,2]             # => []  pusta tablica na kocu.
a[5,1]             # => nil  dalej nic nie ma.
a.slice(0..1)      # => ['a','b']  slice to synonim [].
a.first(3)         # => ['a','b','c']  trzy pierwsze elementy.
a.last(1)          # => ['d']  ostatni element jako tablica.
# Wybieranie dowolnych wartoci.
a.values_at(0,2)         # => ['a','c']
a.values_at(4, 3, 2, 1)  # => [nil, 'd','c','b']
a.values_at(0, 2..3, -1) # => ['a','c','d','d']
a.values_at(0..2,1..3)   # => ['a','b','c','b','c','d']

a = [1,2,3]        # Tablica pocztkowa.
# Zmienianie wartoci elementw.
a[0] = 0           # Modyfikacja istniejcego elementu  a = [0,2,3].
a[-1] = 4          # Zmiana ostatniego elementu  a = [0,2,4].
a[1] = nil         # Ustawienie drugiego elementu na nil  a = [0,nil,4].
# Dodawanie elementw do tablicy.
a = [1,2,3]        # Tablica pocztkowa.
a[3] = 4           # Dodanie czwartego elementu do tablicy  a = [1,2,3,4].
a[5] = 6           # Elementy mona pomija  a = [1,2,3,4,nil,6].
a << 7             # => [1,2,3,4,nil,6,7].
a << 8 << 9        # => [1,2,3,4,nil,6,7,8,9]  mona tworzy acuchy operatorw.
a = [1,2,3]        # Nowa krtka tablica pocztkowa.
a + a              # => [1,2,3,1,2,3]  operator + czy dwie tablice w now tablic.
a.concat([4,5])    # => [1,2,3,4,5]  modyfikacja tablicy a. Zauwa brak znaku !.
# Wstawianie elementw za pomoc metody insert.
a = ['a', 'b', 'c']
a.insert(1, 1, 2)  # Tablica a zawiera teraz elementy ['a',1,2,'b','c']. Jak a[1,0] = [1,2].
# Usuwanie (i zwracanie) wybranych elementw wedug indeksw.
a = [1,2,3,4,5,6]
a.delete_at(4)     # => 5  a = [1,2,3,4,6].
a.delete_at(-1)    # => 6  a = [1,2,3,4].
a.delete_at(4)     # => nil  a pozostaje bez zmian.
# Usuwanie elementw wedug wartoci.
a.delete(4)        # => 4  a = [1,2,3].
a[1] = 1           # a = [1,1,3].
a.delete(1)        # => 1  a = [3]  obie jedynki zostay usunite.
a = [1,2,3]
a.delete_if {|x| x%2==1} # Usunicie wartoci nieparzystych  a = [2].
a.reject! {|x| x%2==0}   # Tak jak delete_if  a = [].

# Usuwanie elementw i podtablic za pomoc metody slice!.
a = [1,2,3,4,5,6,7,8]
a.slice!(0)        # => 1  usuwa element 0  a = [2,3,4,5,6,7,8].
a.slice!(-1,1)     # => [8]  usuwa podtablic z koca  a = [2,3,4,5,6,7].
a.slice!(2..3)     # => [4,5]  dziaa z przedziaami  a = [2,3,6,7].
a.slice!(4,2)      # => []  pusta tablica za kocem  a pozostaje bez zmian.
a.slice!(5,2)      # => nil  a = [2,3,6,7,nil]!
# Zastpowanie podtablic za pomoc metody []=.
# Aby usun elementy, naley przypisa pust tablic.
# Aby wstawi elementy, naley przypisa do fragmentu o zerowej szerokoci.
a = ('a'..'e').to_a    # => ['a','b','c','d','e'].
a[0,2] = ['A','B']     # Teraz a = ['A', 'B', 'c', 'd', 'e'].
a[2...5]=['C','D','E'] # Teraz a = ['A', 'B', 'C', 'D', 'E'].
a[0,0] = [1,2,3]       # Wstawianie elementw na pocztku tablicy a.
a[0..2] = []           # Usunicie tych elementw.
a[-1,1] = ['Z']        # Zastpienie ostatniego elementu innym.
a[-1,1] = 'Z'          # Dla pojedynczego elementu tablica jest opcjonalna.
a[1,4] = nil           # Ruby 1.9  teraz a = ['A',nil].
                       # Ruby 1.8 teraz a = ['A']  nil dziaa jak [].
# Inne metody.
a = [4,5]
a.replace([1,2,3])     # Teraz a = [1,2,3].
a.fill(0)              # Teraz a = [0,0,0].
a.fill(nil,1,3)        # Teraz a = [0,nil,nil,nil].
a.fill('a',2..4)       # Teraz a = [0,nil,'a','a','a'].
a[3].upcase!           # Teraz a = [0,nil,'A','A','A'].
a.fill(2..4) { 'b' }   # Teraz a = [0,nil,'b','b','b'].
a[3].upcase!           # Teraz a = [0,nil,'b','B','b'].
a.compact              # => [0,'b','B','b']  kopiowanie z usuniciem wartoci nil.
a.compact!             # usunicie wartoci nil na miejscu  teraz a = [0,'b','B','b'].
a.clear                # Teraz a = [].

a = ['a','b','c']
a.each {|elt| print elt }          # Podstawowy iterator each drukuje abc.
a.reverse_each {|e| print e}       # Iterator tablicowy drukuje cba.
a.cycle {|e| print e }             # Ruby 1.9  drukuje "abcabcabc..." w nieskoczono.
a.each_index {|i| print i}         # Iterator tablicowy drukuje 012.
a.each_with_index{|e,i| print e,i} # Enumerable  drukuje a0b1c2.
a.map {|x| x.upcase}               # Enumerable  zwraca ['A','B','C'].
a.map! {|x| x.upcase}              # Tablicowy  modyfikuje na miejscu.
a.collect! {|x| x.downcase!}       # collect! jest synonimem map!.
# Searching methods
a = %w[h e l l o]
a.include?('e')                    # => true
a.include?('w')                    # => false
a.index('l')                       # => 2  indeks pierwszego dopasowania.
a.index('L')                       # => nil  nic nie dopasowano.
a.rindex('l')                      # => 3  szukanie wstecz.
a.index {|c| c =~ /[aeiouy]/}      # => 1  indeks pierwszej samogoski. Ruby 1.9 oraz Ruby 1.8.7.
a.rindex {|c| c =~ /[aeiouy]/}     # => 4  indeks ostatniej samogoski. Ruby 1.9 oraz Ruby 1.8.7.
# Sortowanie.
a.sort     # => %w[e h l l o]  skopiowanie tablicy a i posortowanie tej kopii.
a.sort!    # Sortowanie na miejscu  teraz tablica a = ['e','h','l','l','o'].
a = [1,2,3,4,5]               # Nowa tablica do posortowania na liczby parzyste i nieparzyste.
a.sort! {|a,b| a%2 <=> b%2}   # Porwnywanie elementw modulo 2.
# Tasowanie elementw  przeciwiestwo sortowania. Tylko Ruby 1.9.
a = [1,2,3]     # Tablica uporzdkowana.
puts a.shuffle  # Tasuje losowo. Np. [3,1,2]. Istnieje te metoda shuffle!.

[1,2] <=> [4,5]      # => -1 poniewa 1 < 4.
[1,2] <=> [0,0,0]    # => +1 poniewa 1 > 0.
[1,2] <=> [1,2,3]    # => -1 poniewa pierwsza tablica jest krtsza.
[1,2] <=> [1,2]      # => 0  s rwne.
[1,2] <=> []         # => +1  pusta tablica jest zawsze mniejsza od tablicy niepustej.

a = []
a.push(1)     # => [1]  a = [1]
a.push(2,3)   # => [1,2,3]  a = [1,2,3]
a.pop         # => 3  a = [1,2]
a.pop         # => 2  a = [1]
a.pop         # => 1  a = []
a.pop         # => nil  a nadal = []

a = []
a.push(1)     # => [1]  a = [1]
a.push(2)     # => [1,2]  a = [1,2]
a.shift       # => 1  a = [2]
a.push(3)     # => [2,3]  a = [2,3]
a.shift       # => 2  a = [3]
a.shift       # => 3  a = []
a.shift       # => nil  a = []

[1,3,5] & [1,2,3]           # => [1,3]  przecicie zbiorw.
[1,1,3,5] & [1,2,3]         # => [1,3]  duplikaty zostay usunite.
[1,3,5] | [2,4,6]           # => [1,3,5,2,4,6]  scalenie zbiorw.
[1,3,5,5] | [2,4,6,6]       # => [1,3,5,2,4,6]  duplikaty zostay usunite.
[1,2,3] - [2,3]             # => [1]  rnica zbiorw.
[1,1,2,2,3,3] - [2, 3]      # => [1,1]  nie wszystkie duplikaty zostay usunite.
small = 0..10.to_a          # Zbir maych liczb.
even = 0..50.map {|x| x*2}  # Zbir liczb parzystych.
smalleven = small & even    # Przecicie zbiorw.
smalleven.include?(8)       # => true  sprawdzanie przynalenoci do zbioru.
[1, 1, nil, nil].uniq       # => [1, nil]  usunicie duplikatw. Istnieje te metoda uniq!.

a = [1,2,3]
# Iteruje wszystkie moliwe tablice dwuelementowe (kolejno ma znaczenie).
a.permutation(2) {|x| print x }  # Drukuje [1,2][1,3][2,1][2,3][3,1][3,2].
# Iteruje wszystkie moliwe podzbiory dwuelementowe (kolejno nie ma znaczenia).
a.combination(2) {|x| print x }  # Drukuje [1, 2][1, 3][2, 3].
# Zwraca iloczyn kartezjaski dwch zbiorw.
a.product(['a','b'])       # => [[1,"a"],[1,"b"],[2,"a"],[2,"b"],[3,"a"],[3,"b"]].
[1,2].product([3,4],[5,6]) # => [[1,3,5],[1,3,6],[1,4,5],[1,4,6] itd. ].

h = { :a => 1, :b => 2}   # Pocztkowa tablica asocjacyjna.
a = h.to_a                # => [[:b,2], [:a,1]]  tablica asocjacyjna.
a.assoc(:a)               # => [:a,1]  podtablica klucza :a.
a.assoc(:b).last          # => 2  warto klucza :b.
a.rassoc(1)               # => [:a,1]  podtablica wartoci 1.
a.rassoc(2).first         # => :b  klucz wartoci 2.
a.assoc(:c)               # => nil
a.transpose               # => [[:a, :b], [1, 2]]  zamiana miejscami wierszy i kolumn.

# Konwersja na acuchy.
[1,2,3].join              # => 123  konwersja elementw na acuch i poczenie ich.
[1,2,3].join(", ")        # => 1, 2, 3  opcjonalny znak oddzielajcy.
[1,2,3].to_s              # => [1, 2, 3] w Ruby 1.9.
[1,2,3].to_s              # => 123 w Ruby 1.8.
[1,2,3].inspect           # => [1, 2, 3]  lepsze do debugowania w Ruby 1.8.
# Konwersja binarna za pomoc metody pack. Zobacz take metod String.unpack.
[1,2,3,4].pack("CCCC")    # => "\001\002\003\004"
[1,2].pack('s2')          # => "\001\000\002\000"
[1234].pack("i")          # => "\322\004\000\000"
# Inne metody.
[0,1]*3                   # => [0,1,0,1,0,1]  operator * odpowiada za powtarzanie.
[1, [2, [3]]].flatten     # => [1,2,3]  rekursywne spaszczanie. Istnieje te metoda flatten!.
[1, [2, [3]]].flatten(1)  # => [1,2,[3]]  okrela liczb poziomw. Ruby 1.9.
[1,2,3].reverse           # => [3,2,1]  istnieje te metoda reverse!.
a=[1,2,3].zip([:a,:b,:c]) # => [[1,:a],[2,:b],[3,:c]]  metoda moduu Enumerable.
a.transpose               # => [[1,2,3],[:a,:b,:c]]  zamienia miejscami wiersze i kolumny.

{ :one => 1, :two => 2 }  # Podstawowa skadnia literau tablicy asocjacyjnej.
{ :one, 1, :two, 2 }      # To samo przy uyciu wycofywanej skadni Ruby 1.8.
{ one: 1, two: 2 }        # To samo przy uyciu skadni Ruby 1.9. Klucze s symbolami.
{}                        # Nowy pusty obiekt klasy Hash.
Hash.new                  # => {}  tworzy pust tablic asocjacyjn.
Hash[:one, 1, :two, 2]    # => {one:1, two:2}

puts :a=>1, :b=>2   # Nawiasy klamrowe opuszczone w wywoaniu.
puts a:1, b:2       # Skadnia Ruby 1.9 jest take dozwolona.

h = { :one => 1, :two => 2 }
h[:one]       # => 1  znajduje warto skojarzon z kluczem.
h[:three]     # => nil  nie ma takiego klucza w tablicy.
h.assoc :one  # => [:one, 1]  znajduje par klucz-warto. Ruby 1.9.
h.index 1     # => :one  szuka klucza skojarzonego z podan wartoci.
h.index 4     # => nil  nie ma adnego klucza dla tej wartoci.
h.rassoc 2    # => [:two, 2]  para klucz-warto pasujca do wartoci. Ruby 1.9.

h = { :a => 1, :b => 2 }
# Sprawdzanie obecnoci kluczy w tablicy asocjacyjnej  szybkie.
h.key?(:a)       # true  :a jest kluczem w tablicy h.
h.has_key?(:b)   # true  has_key? jest synonimem metody key?.
h.include?(:c)   # false  include? jest kolejnym synonimem.
h.member?(:d)    # false  member? to jeszcze jeden synonim.
# Sprawdzanie obecnoci wartoci  wolne.
h.value?(1)      # true  tablica h zawiera warto 1.
h.has_value?(3)  # false  has_value? jest synonimem metody value?.

h = { :a => 1, :b => 2 }
h.fetch(:a)      # => 1  dziaa jak operator [] dla istniejcych kluczy.
h.fetch(:c)      # Zgasza wyjtek IndexError dla nieistniejcego klucza.
h.fetch(:c, 33)  # => 33  uywa podanej wartoci, jeli klucz nie zostanie znaleziony.
h.fetch(:c) {|k| k.to_s } # => c  wywouje blok, jeli klucz nie zostanie znaleziony.

h = { :a => 1, :b => 2, :c => 3 }
h.values_at(:c)         # => [3]  wartoci zwrcone w tablicy jednowymiarowej.
h.values_at(:a, :b)     # => [1, 2]  przekazanie dowolnej liczby argumentw.
h.values_at(:d, :d, :a) # => [nil, nil, 1].

h = { :a => 1, :b => 2, :c => 3 }
h.select {|k,v| v % 2 == 0 } # => [:b,2] Ruby 1.8.
h.select {|k,v| v % 2 == 0 } # => {:b=>2} Ruby 1.9.

h = {}        # Pocztkowa pusta tablica asocjacyjna.
h[:a] = 1     # Map :a=>1.  Teraz h = {:a=>1}.
h.store(:b,2) # Bardziej rozwleky sposb. Teraz h = {:a=>1, :b=>2}.

# Zastpuje wszystkie pary klucz warto w tablicy h parami z innej tablicy.
h.replace({1=>:a, 2=>;b})  # Teraz tablica h jest rwna tablicy podanej jako argument.

# Scalenie tablic asocjacyjnych h i j i zapisanie ich w nowej tablicy k.
# Jeli tablice h i j maj takie same klucze, zostan dla nich uyte wartoci z tablicy j.
k = h.merge(j)
{:a=>1,:b=>2}.merge(:a=>3,:c=>3)  # => {:a=>3,:b=>2,:c=>3}.
h.merge!(j)   # Modyfikuje tablic h na miejscu.
# Jeli zosta podany blok, za jego pomoc nastpi rozstrzygnicie, ktrej wartoci uy.
h.merge!(j) {|key,h,j| h }      # Uycie wartoci z tablicy h.
h.merge(j) {|key,h,j| (h+j)/2 } # Uycie redniej obu wartoci.
# Metoda update jest synonimem metody merge!.
h = {a:1,b:2}     # Uycie skadni Ruby 1.9 i opuszczenie klamr.
h.update(b:4,c:9) {|key,old,new| old }  # Teraz h = {a:1, b:2, c:9}.
h.update(b:4,c:9) # Teraz h = {a:1, b:4, c:9}.

h = {:a=>1, :b=>2}
h[:a] = nil      # Teraz tablica h = {:a=> nil, :b=>2 }.
h.include? :a    # => true
h.delete :b      # => 2  zwraca usunit warto. Teraz tablica h = {:a=>nil}.
h.include? :b    # => false
h.delete :b      # => nil  klucz nie zosta znaleziony.
# Wywoanie bloku, jeli klucz nie zostanie znaleziony.
h.delete(:b) {|k| raise IndexError, k.to_s } # IndexError!

h = {:a=>1, :b=>2, :c=>3, :d=>"four"}
h.reject! {|k,v| v.is_a? String }  # => {:a=>1, :b=>2, :c=>3 }.
h.delete_if {|k,v| k.to_s < 'b' }  # => {:b=>2, :c=>3 }.
h.reject! {|k,v| k.to_s < 'b' }    # => nil  brak zmian.
h.delete_if {|k,v| k.to_s < 'b' }  # => {:b=>2, :c=>3 }  tablica nie zostaa zmieniona.
h.reject {|k,v| true }             # => {}  tablica h nie zostaa zmieniona.

h.clear    # Teraz tablica h = {}.

h = { :a=>1, :b=>2, :c=>3 }
# Rozmiar tablicy asocjacyjnej  liczba par klucz-warto.
h.length     # => 3
h.size       # => 3  metoda size jest synonimem metody length.
h.empty?     # => false
{}.empty?    # => true
h.keys       # => [:b, :c, :a]  tablica jednowymiarowa zawierajca klucze.
h.values     # => [2,3,1]  tablica jednowymiarowa zawierajca wartoci.
h.to_a       # => [[:b,2],[:c,3],[:a,1]]  tablica jednowymiarowa zawierajca pary.
h.flatten    # => [:b, 2, :c, 3, :a, 1]  spaszczona tablica jednowymiarowa. Ruby 1.9.
h.sort       # => [[:a,1],[:b,2],[:c,3]]  posortowana tablica jednowymiarowa zawierajca pary.
h.sort {|a,b| a[1]<=>b[1] } # Sortowanie par wedug wartoci zamiast kluczy.

h = { :a=>1, :b=>2, :c=>3 }
# Iterator each() iteruje po parach [klucz,warto].
h.each {|pair| print pair }    # Drukuje [:a, 1][:b, 2][:c, 3].
# Dziaa take z dwoma argumentami blokowymi.
h.each do |key, value|
  print "#{key}:#{value} "     # Drukuje a:1 b:2 c:3.
end
# Iteracja po kluczach, wartociach lub obu.
h.each_key {|k| print k }      # Drukuje abc.
h.each_value {|v| print v }    # Drukuje 123.
h.each_pair {|k,v| print k,v } # Drukuje a1b2c3. Jak iterator each.

h = { :a=> 1, :b=>2 }
print h.shift[1] while not h.empty?   # Drukuje 12.

empty = {}
empty["one"]   # nil

empty = Hash.new(-1)   # Okrelenie wartoci domylnej podczas tworzenia tablicy asocjacyjnej.
empty["one"]           # => -1
empty.default = -2     # Zmiana wartoci domylnej na jak inn warto.
empty["two"]           # => -2
empty.default          # => -2  zwrcenie wartoci domylnej.

# Jeli ten klucz nie jest zdefiniowany, zwraca nastpny.
plus1 = Hash.new {|hash, key| key.succ }
plus1[1]      # 2
plus1["one"]  # "onf"  zobacz metod String.succ.
plus1.default_proc  # Zwraca obiekt klasy Proc obliczajcy wartoci domylne.
plus1.default(10)   # => 11  warto domylna zwrcona dla klucza 10.

# Niniejsza leniwie inicjowana tablica asocjacyjna rzutuje liczby cakowite na ich silnie:
fact = Hash.new {|h,k| h[k] = if k > 1: k*h[k-1] else 1 end }
fact      # {}  na pocztku tablica jest pusta.
fact[4]   # 24  4! = 24.
fact      # {1=>1, 2=>2, 3=>6, 4=>24}  teraz tablica nie jest pusta.

fact.fetch(5)   # IndexError  nie znaleziono klucza.

key = {:a=>1}      # Ta tablica asocjacyjna bdzie kluczem w innej tablicy asocjacyjnej!
h = { key => 2 }   # Ta tablica ma modyfikowalny klucz.
h[key]             # => 2  pobiera warto zwizan z kluczem.
key.clear          # Modyfikacja klucza.
h[key]             # => nil  dla zmodyfikowanego klucza nie znaleziono adnej wartoci.
h.rehash           # Naprawa tablicy asocjacyjnej po modyfikacji klucza.
h[key]             # => 2  teraz warto jest znowu znajdowana.

h = {:a=>1, :b=>2}
h.invert        # => {1=>:a, 2=>:b}  zamiana miejscami kluczy i wartoci.

{:a=>1, :b=>2}.to_s    # => a1b2 w Ruby 1.8; {:a=>1, :b=>2} w 1.9.
{:a=>1, :b=>2}.inspect # => {:a=>1, :b=>2} w obu wersjach jzyka.

(1..5).to_set              # => #<Set: {5, 1, 2, 3, 4}>.
[1,2,3].to_set             # => #<Set: {1, 2, 3}>.

Set.new(1..5)              # => #<Set: {5, 1, 2, 3, 4}>.
Set.new([1,2,3])           # => #<Set: {1, 2, 3}>.
Set.new([1,2,3]) {|x| x+1} # => #<Set: {2, 3, 4}>.

Set["krowa", "winia", "kura"]   # => #<Set: {"krowa", "winia", "kura"}>.

s = Set.new(1..3)   # => #<Set: {1, 2, 3}>.
s.include? 1        # => true
s.member? 0         # => false  metoda member? jest synonimem.

s = Set[2, 3, 5]
t = Set[2, 3, 5, 7]
s.subset? t            # => true
t.subset? s            # => false
s.proper_subset? t     # => true
t.superset? s          # => true
t.proper_superset? s   # => true
s.subset? s            # => true
s.proper_subset? s     # => false

s = Set[2, 3, 5]
s.length               # => 3
s.size                 # => 3  synonim metody length.
s.empty?               # => false
Set.new.empty?         # => true

# Dwa proste zbiory.
primes = Set[2, 3, 5, 7]
odds = Set[1, 3, 5, 7, 9]
# Przecicie to zbir wartoci wystpujcych w obu zbiorach.
primes & odds             # => #<Set: {5, 7, 3}>.
primes.intersection(odds) # To jest alias operatora przecicia.
# Suma jest zbiorem wartoci znajdujcych si w kadym ze zbiorw.
primes | odds             # => #<Set: {5, 1, 7, 2, 3, 9}>.
primes.union(odds)        # Alias.
# a-b  elementy zbioru a z wyjtkiem tych, ktre znajduj si w zbiorze b.
primes-odds               # => #<Set: {2}>.
odds-primes               # => #<Set: {1, 9}>.
primes.difference(odds)   # Alias.
# a^b to zbir wartoci, ktre znajduj si w jednym ze zbiorw, ale nie w obu  (a|b)-(a&b).
primes ^ odds             # => #<Set: {1, 2, 9}>.

s = Set[]              # Pocztkowy pusty zbir.
s << 1                 # => #<Set: {1}>
s.add 2                # => #<Set: {1, 2}>  metoda add jest synonimem operatora <<.
s << 3 << 4 << 5       # => #<Set: {5, 1, 2, 3, 4}>  mona tworzy acuchy.
s.add 3                # => #<Set: {5, 1, 2, 3, 4}>  warto nie zostaa zmieniona.
s.add? 6               # => #<Set: {5, 6, 1, 2, 3, 4}>
s.add? 3               # => nil  zbir nie zosta zmodyfikowany.

s = (1..3).to_set   # => #<Set: {1, 2, 3}>
s.merge(2..5)       # => #<Set: {5, 1, 2, 3, 4}>

s = (1..3).to_set   # => #<Set: {1, 2, 3}>
s.delete 1          # => #<Set: {2, 3}>
s.delete 1          # => #<Set: {2, 3}>  bez zmian.
s.delete? 1         # => nil  zwraca warto nil, kiedy nie ma adnych zmian.
s.delete? 2         # => #<Set: {3}>  w przeciwnym przypadku zwraca zbir.

s = (1..3).to_set   # => #<Set: {1, 2, 3}>
s.subtract(2..10)   # => #<Set: {1}>

primes = Set[2, 3, 5, 7]       # Zbir liczb pierwszych.
primes.delete_if {|x| x%2==1}  # => #<Set: {2}>  usuwa liczby nieparzyste.
primes.delete_if {|x| x%2==1}  # => #<Set: {2}>  bez zmian.
primes.reject! {|x| x%2==1}    # => nil  bez zmian.

# Przecicie na miejscu:
s = (1..5).to_set
t = (4..8).to_set
s.reject! {|x| not t.include? x}  # => #<Set: {5, 4}>

s = Set.new(1..3) # Zbir pocztkowy.
s.replace(3..4)   # Zamiana wszystkich elementw. Argumentem moe by kady obiekt umoliwiajcy iteracj.
s.clear           # => #<Set: {}>
s.empty?          # => true

s = Set[1, 2, 3, 4, 5] # => #<Set: {5, 1, 2, 3, 4}>
s.each {|x| print x }  # Drukuje 51234  przed Ruby 1.9 kolejno bya dowolna.
s.map! {|x| x*x }      # => #<Set: {16, 1, 25, 9, 4}>
s.collect! {|x| x/2 }  # => #<Set: {0, 12, 2, 8, 4}>

s = (1..3).to_set
s.to_a          # => [1, 2, 3]
s.to_s          # => "#<Set:0xb7e8f938>"  bezuyteczne.
s.inspect       # => "#<Set: {1, 2, 3}>"  uyteczne.
s == Set[3,2,1] # => true  porwnuje elementy zbioru za pomoc metody eql?.

# Klasyfikowanie elementw zbioru jako parzyste lub nieparzyste.
s = (0..3).to_set     # => #<Set: {0, 1, 2, 3}>
s.classify {|x| x%2}  # => {0=>#<Set: {0, 2}>, 1=>#<Set: {1, 3}>}

s.divide {|x| x%2}  # => #<Set: {#<Set: {0, 2}>, #<Set: {1, 3}>}>

s = %w[ant ape cow hen hog].to_set # Zbir sw.
s.divide {|x,y| x[0] == y[0]}      # Dzielenie na podzbiory wedug pierwszej litery.
# => #<Set:{#<Set:{"hog", "hen"}>, #<Set:{"cow"}>, #<Set:{"ape", "ant"}>}>

s = %w[ant ape cow hen hog].to_set # Zbir sw.
t = s.divide {|x,y| x[0] == y[0]}  # Podzielenie zbioru na podzbiory.
t.flatten!                         # Spaszczenie podzbiorw.
t == s                             # => true

full = '/home/matz/bin/ruby.exe'
file=File.basename(full)     # => ruby.exe  tylko nazwa lokalna.
File.basename(full, '.exe')  # => ruby  usunite rozszerzenie.
dir=File.dirname(full)       # => /home/matz/bin  bez znaku / na kocu.
File.dirname(file)           # => .  aktualny katalog.
File.split(full)             # => ['/home/matz/bin', 'ruby.exe'].
File.extname(full)           # => .exe
File.extname(file)           # => .exe
File.extname(dir)            # => ''
File.join('home','matz')     # => home/matz  wzgldna.
File.join('','home','matz')  # => /home/matz bezwzgldna.

Dir.chdir("/usr/bin")      # Aktualny katalog roboczy to  /usr/bin.
File.expand_path("ruby")       # => /usr/bin/ruby
File.expand_path("~/ruby")     # => /home/david/ruby
File.expand_path("~matz/ruby") # => /home/matz/ruby
File.expand_path("ruby", "/usr/local/bin") # => /usr/local/bin/ruby
File.expand_path("ruby", "../local/bin")   # => /usr/local/bin/ruby
File.expand_path("ruby", "~/bin")          # => /home/david/bin/ruby

File.identical?("ruby", "ruby")          # => true, jeli plik ten istnieje.
File.identical?("ruby", "/usr/bin/ruby") # => true, jeli biecy katalog roboczy to /usr/bin.
File.identical?("ruby", "../bin/ruby")   # => true, jeli biecy katalog roboczy to /usr/bin.
File.identical?("ruby", "ruby1.9")       # => true, jeli istnieje dowizanie.

File.fnmatch("*.rb", "hello.rb")     # => true
File.fnmatch("*.[ch]", "ruby.c")     # => true
File.fnmatch("*.[ch]", "ruby.h")     # => true
File.fnmatch("?.txt", "ab.txt")      # => false
flags = File::FNM_PATHNAME | File::FNM_DOTMATCH
File.fnmatch("lib/*.rb", "lib/a.rb", flags)      # => true
File.fnmatch("lib/*.rb", "lib/a/b.rb", flags)    # => false
File.fnmatch("lib/**/*.rb", "lib/a.rb", flags)   # => true
File.fnmatch("lib/**/*.rb", "lib/a/b.rb", flags) # => true

# tworzy list wszystkich plikw katalogu config/.
filenames = Dir.entries("config")        # Pobranie nazw w tablicy.
Dir.foreach("config") {|filename| ... }  # Iteracja nazw.

Dir['*.data']       # Pliki z rozszerzeniem data.
Dir['ruby.*']       # Kady plik, ktrego nazwa zaczyna si od sowa ruby.
Dir['?']            # Kada nazwa pliku zoona z jednego znaku.
Dir['*.[ch]']       # Kady plik, ktrego nazwa koczy si znakami .c lub .h.
Dir['*.{java,rb}']  # Kady plik, ktrego nazwa koczy si znakami .java lub .rb.
Dir['*/*.rb']       # Kady program Ruby w kadym bezporednim podkatalogu.
Dir['**/*.rb']      # Kady program Ruby w jakimkolwiek podkatalogu.

Dir.glob('*.rb') {|f| ... }      # Iteracja po wszystkich plikach z kodem Ruby.
Dir.glob('*')                    # Nie bierze pod uwag plikw, ktrych nazwy zaczynaj si od  kropki.
Dir.glob('*',File::FNM_DOTMATCH) # Dodaje pliki, ktrych nazwy zaczynaj si od kropki, tak jak metoda Dir.entries.

puts Dir.getwd          # Drukuje aktualny katalog roboczy.
Dir.chdir("..")         # Zmienia katalog roboczy na katalog nadrzdny.
Dir.chdir("../sibling") # Ponownie zmienia na katalog rwnolegy.
Dir.chdir("/home")      # Zmienia na katalog gwny.
Dir.chdir               # Zmienia na katalog gwny uytkownika.
home = Dir.pwd          # Metoda pwd jest aliasem metody getwd.

f = "/usr/bin/ruby"      # Nazwa pliku uywana w poniszych przykadach.
# Itnienie pliku i typy.
File.exist?(f)           # Czy plik o takiej nazwie istnieje? Take File.exists?.
File.file?(f)            # Czy to jest istniejcy plik?
File.directory?(f)       # Czy jest to istniejcy katalog?
File.symlink?(f)         # Czy jest to mimo wszystko dowizanie symboliczne?
# Rozmiar pliku. Do ustawiania rozmiaru pliku suy metoda File.truncate.
File.size(f)             # Rozmiar pliku w bajtach.
File.size?(f)            # Rozmiar w bajtach lub nil, jeli plik jest pusty.
File.zero?(f)            # Prawda, jeli plik jest pusty.
# Zezwolenia dostpu do plikw. Do ustawiania zezwole dostpu suy metoda File.chmod (zalena od systemu).
File.readable?(f)        # Czy mona odczytywa ten plik?
File.writable?(f)        # Czy mona zapisywa w tym pliku?
File.executable?(f)      # Czy mona ten plik wykonywa?
File.world_readable?(f)  # Czy kady moe odczyta ten plik? Ruby 1.9.
File.world_writable?(f)  # Czy kady moe zapisywa w tym pliku? Ruby 1.9.
# Czas. Do ustawiania czasu suy metoda File.utime.
File.mtime(f)            # => Czas ostatniej modyfikacji w postaci obiektu klasy Time.
File.atime(f)            # => Czas ostatniego dostpu do pliku w postaci obiektu klasy Time.

File.ftype("/usr/bin/ruby")    # => link
File.ftype("/usr/bin/ruby1.9") # => file
File.ftype("/usr/lib/ruby")    # => directory
File.ftype("/usr/bin/ruby3.0") # SystemCallError  nie ma takiego pliku lub katalogu.

s = File.stat("/usr/bin/ruby")
s.file?             # => true
s.directory?        # => false
s.ftype             # => "file"
s.readable?         # => true
s.writable?         # => false
s.executable?       # => true
s.size              # => 5492
s.atime             # => Mon Jul 23 13:20:37 -0700 2007

# Sprawdzanie pojedynczych plikw.
test ?e, "/usr/bin/ruby"   # File.exist?("/usr/bin/ruby").
test ?f, "/usr/bin/ruby"   # File.file?("/usr/bin/ruby").
test ?d, "/usr/bin/ruby"   # File.directory?("/usr/bin/ruby").
test ?r, "/usr/bin/ruby"   # File.readable?("/usr/bin/ruby").
test ?w, "/usr/bin/ruby"   # File.writeable?("/usr/bin/ruby").
test ?M, "/usr/bin/ruby"   # File.mtime("/usr/bin/ruby").
test ?s, "/usr/bin/ruby"   # File.size?("/usr/bin/ruby").
# Porwnywanie dwch plikw f i g.
test ?-, f, g              # File.identical(f,g).
test ?<, f, g              # File(f).mtime < File(g).mtime.
test ?>, f, g              # File(f).mtime > File(g).mtime.
test ?=, f, g              # File(f).mtime == File(g).mtime.

# Utworzenie (lub nadpisanie) pliku o nazwie test.
File.open("test", "w") {}
# Utworzenie (ale nienadpisanie) pliku o nazwie test.
File.open("test", "a") {}

File.copy_stream("test", "test.backup")

File.rename("test", "test.old")     # Aktualna nazwa i nowa nazwa.

File.symlink("test.old", "oldtest") # Cel dowizania, nazwa dowizania.

File.link("test.old", "test2")   # Cel dowizania, nazwa dowizania.

File.delete("test2")   # Moe by te wywoywana z wieloma argumentami,
File.unlink("oldtest") # aby usun wiele plikw.

f = "log.messages"          # Nazwa pliku.
atime = mtime = Time.now    # Nowe czasy dostpu i modyfikacji.
File.truncate(f, 0)         # Wyczyszczenie caej zawartoci.
File.utime(atime, mtime, f) # Zmiana czasw.
File.chmod(0600, f)         # Zezwolenia w systemie Unix -rw-------. Zwr uwag na argument semkowy.

Dir.mkdir("temp")                 # Utworzenie katalogu.
File.open("temp/f", "w") {}       # Utworzenie pliku w katalogu.
File.open("temp/g", "w") {}       # Utworzenie jeszcze jednego pliku.
File.delete(*Dir["temp/*"])       # Usunicie wszystkich plikw z katalogu.
Dir.rmdir("temp")                 # Usunicie katalogu.

f = File.open("data.txt", "r")   # Otwarcie pliku data.txt do odczytu.
out = File.open("out.txt", "w")  # Otwarcie pliku out.txt do zapisu.

File.open("log.txt", "a") do |log|      # Otwarcie w trybie dodawania.
  log.puts("INFO: Zapisywanie komunikatu w dzienniku")   # Wysanie danych do pliku.
end

# Ile czasu dziaa serwer?
uptime = open("|uptime") {|f| f.gets }

require "open-uri"                         # Wymagana biblioteka.
f = open("http://www.davidflanagan.com/")  # Strona internetowa jako plik.
webpage = f.read                           # Odczyt jako jednego dugiego acucha.
f.close                                    # Nie zapomnij o zamkniciu pliku!

require "stringio"
input = StringIO.open("now is the time")  # Odczyt z tego acucha.
buffer = ""
output = StringIO.open(buffer, "w")       # Zapis w buforze.

f.set_encoding("iso-8859-1", "utf-8") # Latin-1, transkodowane na UTF-8.
f.set_encoding("iso-8859-1:utf-8")    # To samo co powyej
f.set_encoding(Encoding::UTF-8)       # Tekst UTF-8.

in = File.open("data.txt", "r:utf-8");           # Odczyt tekstu UTF-8.
out = File.open("log", "a:utf-8");               # Zapis tekstu UTF-8.
in = File.open("data.txt", "r:iso8859-1:utf-8"); # Konwersja Latin-1 na UTF-8.

File.open("data", "r:binary")  # Otwarcie pliku do odczytu danych binarnych.

lines = ARGF.readlines         # Wczytanie wszystkich danych wejciowych i zwrcenie tablicy poszczeglnych wierszy.
line = DATA.readline           # Wczytanie jednego wiersza danych ze strumienia.
print l while l = DATA.gets    # Odczytywanie, dopki metoda gets nie zwrci wartoci nil po dotarciu na koniec pliku.
DATA.each {|line| print line } # Iteracja wierszy ze strumienia do napotkania koca pliku.
DATA.each_line                 # Alias metody each.
DATA.lines                     # Enumerator dla metody each_line  Ruby 1.9.

print while DATA.gets

DATA.lineno = 0     # Zaczyna od wiersza 0, mimo e dane znajduj si na kocu pliku.
DATA.readline       # Wczytuje jeden wiersz danych.
DATA.lineno         # => 1
$.                  # => 1:  magiczna zmienna globalna zostaje ustawiona niejawnie.

data = IO.read("data")                    # Wczytanie i zwrcenie caego pliku.
data = IO.read("data", mode:"rb")         # Otwarcie w trybie "rb".
data = IO.read("data", encoding:"binary") # Odczyt niezakodowanych danych.
data = IO.read("data", 4, 2)              # Wczytanie czterech bajtw, zaczynajc od drugiego.
data = IO.read("data", nil, 6)            # Odczyt od szstego bajta do koca pliku.
# Wczytanie wierszy danych do tablicy.
words = IO.readlines("/usr/share/dict/words")
# Odczyt po jednym wierszu i inicjacja tablicy asocjacyjnej.
words = {}
IO.foreach("/usr/share/dict/words") {|w| words[w] = true}

IO.copy_stream("/usr/share/dict/words", STDOUT)          # Wywietlenie sownika.
IO.copy_stream("/usr/share/dict/words", STDOUT, 10, 100) # Wywietlenie bajtw 100-109.

# Alternatywa dla text = File.read("data.txt").
f = File.open("data.txt")  # Otwarcie pliku.
text = f.read              # Wczytanie zawartoci pliku jako tekst.
f.close                    # Zamknicie pliku.

f = File.open("data", "r:binary") # Otwarcie pliku data do odczytu w trybie binarnym.
c = f.getc                        # Wczytanie pierwszego bajta jako liczby cakowitej.
f.ungetc(c)                       # Wepchnicie bajta z powrotem.
c = f.readchar                    # Ponowne wczytanie bajta.

f.each_byte {|b| ... }      # Iteracja po pozostaych bajtach.
f.bytes                     # Enumerator dla metody each_byte  Ruby 1.9.
f.each_char {|c| ... }      # Iteracja po znakach  Ruby 1.9.
f.chars                     # Enumerator dla metody each_char  Ruby 1.9.

f = File.open("data.bin", "rb:binary")  # Bez konwersji znakw nowego wiersza, bez kodowania.
magic = f.readbytes(4)       # Cztery pierwsze bajty identyfikuj typ pliku.
exit unless magic == "INTS"  # Liczba magiczna INTS (ASCII).
bytes = f.read               # Wczytanie reszty pliku.
                             # Kodowanie jest binarne, a wic jest to acuch bajtw.
data = bytes.unpack("i*")    # Konwersja bajtw na tablic liczb cakowitych.

o = STDOUT
# Dane wyjciowe w postaci jednego znaku.
o.putc(65)         # Zapis jednego bajta 65 (wielka litera A).
o.putc("B")        # Zapis jednego bajta 66 (wielka litera B).
o.putc("CD")       # Zapis tylko pierwszego bajta acucha.

o = STDOUT
# Wysyanie acucha na wyjcie.
o << x             # Wysanie x.to_s.
o << x << y        # Mona tworzy acuchy  output x.to_s + y.to_s.
o.print            # Wysanie $_ + $\.
o.print s          # Wysanie s.to_s + $\.
o.print s,t        # Wysanie s.to_s + t.to_s + $\.
o.printf fmt,*args # Wysya fmt%[args].
o.puts             # Wysanie znaku nowego wiersza.
o.puts x           # Wysanie x.to_s.chomp plus znak nowego wiersza.
o.puts x,y         # Wysanie x.to_s.chomp, znak nowego wiersza, y.to_s.chomp, znak nowego wiersza.
o.puts [x,y]       # To samo co powyej.
o.write s          # Wysanie s.to_s, zwrcenie s.to_s.length.
o.syswrite s       # Niskopoziomowa wersja metody write.

f = File.open("test.txt")
f.pos        # => 0  zwrcenie aktualnej pozycji w bajtach.
f.pos = 10   # Przejcie do pozycji 10.
f.tell       # => 10  synonim metody pos.
f.rewind     # Przejcie z powrotem do pozycji 0, reset numeru wiersza do 0.
f.seek(10, IO::SEEK_SET)  # Przejcie do bezwzgldnej pozycji 10.
f.seek(10, IO::SEEK_CUR)  # Przejcie o 10 bajtw dalej od aktualnej pozycji.
f.seek(-10, IO::SEEK_END) # Przejcie do pozycji oddalonej o 10 bajtw od koca.
f.seek(0, IO::SEEK_END)   # Przejcie na sam koniec pliku.
f.eof?                    # => true  jeste na kocu.

pos = f.sysseek(0, IO::SEEK_CUR)  # Sprawdzenie aktualnej pozycji.
f.sysseek(0, IO::SEEK_SET)        # Przewinicie strumienia do tyu.
f.sysseek(pos, IO::SEEK_SET)      # Powrt do pierwotnej pozycji.

File.open("test.txt") do |f|
  # Uycie strumienia f.
  # Warto tego bloku staje si wartoci zwrotn metody open.
end # Strumie f zostaje zamknity automatycznie w tym miejscu.

begin
  f = File.open("test.txt")
  # Uycie strumienia f.
ensure
  f.close if f
end

out.print 'wait>' # Wywietlenie znaku zachty.
out.flush         # Rczne oprnienie bufora wyjciowego do systemu operacyjnego.
sleep(1)          # Znak zachty pojawia si przed zaniciem.
out.sync = true   # Automatyczne oprnianie bufora po kadym zapisie.
out.sync = false  # Wyczenie automatycznego oprniania.
out.sync          # Zwraca biecy tryb synchronizacji.
out.fsync         # Oprnia bufor wyjciowy i prosi system operacyjny o oprnienie buforw.
                  # Zwraca warto nil, jeli nie jest obsugiwana na biecej platformie.

f.eof?       # true, jeli strumie jest na kocu pliku.
f.closed?    # true, jeli strumie zosta zamknity.
f.tty?       # true, jeli strumie jest interaktywny.

require 'socket'

require 'socket'                # Gniazda znajduj si w bibliotece standardowej.
host, port = ARGV               # Host i port z wiersza polece.
s = TCPSocket.open(host, port)  # Otwarcie gniazda do hosta i portu.
while line = s.gets             # Odczytanie danych z gniazda.
  puts line.chop                # Wydruk danych ze znakiem koca wiersza platformy.
end
s.close                         # Zamknicie gniazda po skoczeniu pracy.

require 'socket'
host, port = ARGV
TCPSocket.open(host, port) do |s| # Blokowa wersja metody open.
  while line = s.gets
    puts line.chop
  end
end                               # Gniazdo zostaje zamknite automatycznie.

require 'socket'               # Gniazda z biblioteki standardowej.
server = TCPServer.open(2000)  # Gniazdo nasuchujce na porcie 2000.
loop {                         # Nieskoczona ptla  serwery dziaaj bez przerwy.
  client = server.accept       # Oczekiwanie na poczenie klienta.
  client.puts(Time.now.ctime)  # Wysanie informacji o czasie do klienta.
  client.close                 # Rozczenie z klientem.
}

ruby client.rb localhost 2000

require 'socket'                     # Biblioteka standardowa.
host, port, request = ARGV           # Pobranie argumentw z wiersza polece.
ds = UDPSocket.new                   # Utworzenie gniazda datagramu.
ds.connect(host, port)               # Poczenie z portem hosta.
ds.send(request, 0)                  # Wysanie treci dania.
response,address = ds.recvfrom(1024) # Oczekiwanie na odpowied (maksymalnie 1 kb).
puts response                        # Wydruk odpowiedzi.

require 'socket'                     # Biblioteka standardowa.
port = ARGV[0]                       # Port, na ktrym ma by nasuchiwanie.
ds = UDPSocket.new                   # Utworzenie nowego gniazda.
ds.bind(nil, port)                   # Zmuszenie gniazda do nasuchiwania na okrelonym porcie.
loop do                              # Nieskoczona ptla.
  request,address=ds.recvfrom(1024)  # Oczekiwanie na jakie dane.
  response = request.upcase          # Konwersja tekstu na wielkie litery.
  clientaddr = address[3]            # Adres IP, z ktrego przyszo danie.
  clientname = address[2]            # Nazwa hosta.
  clientport = address[1]            # Numer portu, z ktrego danie zostao wysane.
  ds.send(response, 0,               # Wysanie odpowiedzi tam...
          clientaddr, clientport)    # ... skd przyszo danie.
  # Zapisanie poczenia z klientem w dzienniku.
  puts "Poczenie z: #{clientname} #{clientaddr} #{clientport}"
end

require 'socket'     # Gniazda z biblioteki standardowej.
host, port = ARGV    # Nazwa hosta i numer portu z wiersza polece.
begin                # Dla obsugi wyjtkw.
  # Podczas czenia bdzie wywietlana odpowiednia informacja.
  STDOUT.print "czenie..."        # Co si dzieje.
  STDOUT.flush                      # Pokazanie tego natychmiast.
  s = TCPSocket.open(host, port)    # czenie.
  STDOUT.puts "ukoczono"           # Informacja o zakoczeniu operacji.
  # Wywietlenie informacji o poczeniu.
  local, peer = s.addr, s.peeraddr
  STDOUT.print "Poczono z #{peer[2]}:#{peer[1]}"
  STDOUT.puts " przy uyciu portu lokalnego #{local[1]}"
  # Odczekanie chwil, aby sprawdzi, czy serwer przyle jaki komunikat pocztkowy.
  begin
    sleep(0.5)                      # Odczekanie p sekundy.
    msg = s.read_nonblock(4096)     # Odczytanie tego, co jest gotowe.
    STDOUT.puts msg.chop            # Wywietlenie tego.
  rescue SystemCallError
    # Jeli nic nie byo gotowe do odczytu, wyjtek zostanie zignorowany.
  end
  # Pocztek ptli interakcji klienta z serwerem.
  loop do
    STDOUT.print '> '   # Wywietlenie znaku zachty do podania danych lokalnych.
    STDOUT.flush        # Uwidocznienie znaku zachty.
    local = STDIN.gets  # Odczytanie jednego wiersza tekstu z konsoli.
    break if !local     # Zakoczenie, jeli w konsoli nie ma adnych danych.
    s.puts(local)       # Wysanie wczytanego wiersza do serwera.
    s.flush             # Wymuszenie wyjcia tego wiersza.
    # Odczytanie odpowiedzi serwera i jej wydrukowanie.
    # Serwer moe przysa wicej ni jeden wiersz tekstu, a wic zostaa uyta metoda readpartial
    # odczytujca, co zostanie przysane (jeli dane te przyjd w jednym kawaku).
    response = s.readpartial(4096) # Odczytanie odpowiedzi serwera.
    puts(response.chop)            # Wywietlenie tej odpowiedzi.
  end
rescue           # Jeli co pjdzie nie tak,
  puts $!        # zostanie wywietlony wyjtek.
ensure           # Bez wzgldu na to, co si stanie,
  s.close if s   # nie mona zapomnie zamkn gniazda.
end

# Niniejszy serwer wczytuje wiersz danych od klienta, odwraca go
# i wysya z powrotem. Jeli klient wyle acuch "koniec",
# poczenie zostaje zakoczone. Do obsugi sesji zostaa uyta metoda Kernel.select.
require 'socket'
server = TCPServer.open(2000) # Nasuchiwanie na porcie 2000.
sockets = [server]            # Tablica gniazd, ktre bd monitorowane.
log = STDOUT                  # Wysyanie komunikatw dziennika na wyjcie standardowe.
while true                    # Serwery dziaaj w nieskoczono.
  ready = select(sockets)     # Oczekiwanie, a gniazdo bdzie gotowe.
  readable = ready[0]         # Z tych gniazd mona odczytywa dane.
  readable.each do |socket|          # Iteracja przez gniazda umoliwiajce odczyt.
    if socket == server              # Jeli gniazdo serwera jest gotowe,
      client = server.accept         # akceptuje nowego klienta.
      sockets << client              # Dodanie go do zestawu gniazd.
      # Poinformowanie klienta, z czym i gdzie si poczy.
      client.puts "Usuga odwracania v0.01 dziaa na #{Socket.gethostname}"
      # Zarejestrowanie faktu poczenia z klientem.
      log.puts "Przyjto informacj od #{client.peeraddr[2]}"
    else                             # W przeciwnym przypadku klient jest gotowy.
      input = socket.gets            # Wczytanie danych od klienta.
      # Jeli brak danych, klient rozczy si.
      if !input
        log.puts "Klient #{socket.peeraddr[2]} rozczy si."
        sockets.delete(socket)       # Zaprzestanie monitorowania tego gniazda.
        socket.close                 # Zamknicie go.
        next                         # Przejcie do nastpnego.
      end
      input.chop!                    # Przycicie danych od klienta.
      if (input == "koniec")         # Jeli klient prosi o zakoczenie,
        socket.puts("Do widzenia!"); # mwisz mu do widzenia.
        log.puts "Closing connection to #{socket.peeraddr[2]}"
        sockets.delete(socket)       # Zakoczenie monitorowania gniazda.
        socket.close                 # Zakoczenie sesji.
      else                           # W przeciwnym przypadku klient nie skoczy.
        socket.puts(input.reverse)   # Odwracasz dane i wysyasz je z powrotem.
      end
    end
  end
end

require 'socket'           # Gniazda.

host = 'www.example.com'   # Serwer sieciowy.
port = 80                  # Domylny port HTTP.
path = "/index.html"       # Wymagany plik.
# danie HTTP wysyane, aby zaadowa plik.
request = "GET #{path} HTTP/1.0\r\n\r\n"
socket = TCPSocket.open(host,port)  # Poczenie z serwerem.
socket.print(request)               # Wysanie dania.
response = socket.read              # Odczytanie penej odpowiedzi.
# Podzielenie odpowiedzi wedug pierwszego pustego wiersza na cz nagwkow i ciao.
headers,body = response.split("\r\n\r\n", 2)
print body                          # Wywietlenie ciaa.

require 'net/http'         # Potrzebna biblioteka.
host = 'www.example.com'   # Serwer sieciowy.
path = '/index.html'       # Wymagany plik.
http = Net::HTTP.new(host)      # Utworzenie poczenia.
headers, body = http.get(path)  # danie pliku.
if headers.code == "200"        # Sprawdzenie kodu stanu.
                                # Uwaga: kod nie jest liczb!
  print body                    # Wydrukowanie ciaa, jeli udao si je pobra.
else                            # W przeciwnym przypadku
  puts "#{headers.code} #{headers.message}" # wywietlasz komunikat o bdzie.
end

require 'open-uri'
open("http://www.example.com/index.html") {|f|
  puts f.read
}

# Pierwszy wtek.
Thread.new {
  # Ten kod wykonywany jest przez drugi wtek.
}
# Ten kod wykonywany jest przez pierwszy wtek.

# Czeka, a wszystkie wtki (poza biecym i gwnym) zakocz dziaanie.
# Zakada, e podczas oczekiwania nie zostan uruchomione adne dodatkowe wtki.
def join_all
  main = Thread.main        # Wtek gwny.
  current = Thread.current  # Biecy wtek.
  all = Thread.list         # Wszystkie wtki jeszcze dziaaj.
  # Wywoanie metody join na rzecz kadego wtku.
  all.each {|t| t.join unless t == current or t == main }
end

Thread.abort_on_exception = true

t = Thread.new { ... }
t.abort_on_exception = true

x = 0
t1 = Thread.new do
  # Ten wtek moe sprawdza i ustawia warto zmiennej x.
end
t2 = Thread.new do
  # Ten wtek rwnie moe sprawdza i ustawia warto zmiennej x.
  # Moe te sprawdza i ustawia zmienne t1 i t2.
end

n = 1
while n <= 3
  Thread.new { puts n }
  n += 1
end

n = 1
while n <= 3
  # Zapisanie prywatnej kopii biecej wartoci zmiennej n w zmiennej x.
  Thread.new(n) {|x| puts x }
  n += 1
end

1.upto(3) {|n| Thread.new { puts n }}

Thread.current[:progress] = bytes_received

total = 0
download_threads.each {|t| total += t[:progress] }

total = 0
download_threads.each {|t| total += t[:progress] if t.key?(:progress)}

group = ThreadGroup.new
3.times {|n| group.add(Thread.new { do_task(n) }}

# Rwnolegle wczytuje pliki. Naley uywa z moduem open-uri adujcym adresy URL.
# Przekazuje tablic nazw plikw. Zwraca tablic asocjacyjn rzutujc te nazwy plikw na ich tre.
def conread(filenames)
  h = {}                            # Pusta tablica asocjacyjna wynikw.
  # Utworzenie po jednym wtku dla kadego pliku.
  filenames.each do |filename|      # Dla kadego wyznaczonego pliku.
    h[filename] = Thread.new do     # Utworzenie wtku, rzutowanie na nazw pliku.
      open(filename) {|f| f.read }  # Otwarcie i odczyt pliku.
    end                             # Warto wtku jest treci pliku.
  end
  # Iteracja przez tablic asocjacyjn z odczekaniem, a kady wtek skoczy dziaanie.
  # Zastpienie wtku w tablicy asocjacyjnej jego wartoci (treci pliku).
  h.each_pair do |filename, thread|
    begin
      h[filename] = thread.value    # Rzutowanie nazwy pliku na tre pliku
    rescue
      h[filename] = $!              # lub na zgoszony wyjtek.
    end
  end
end

require 'socket'
# Niniejsza metoda wymaga gniazda poczonego z klientem.
# Wczytuje dane od klienta, odwraca je i wysya z powrotem.
# Metoda ta moe by uruchomiona przez wiele wtkw jednoczenie.
def handle_client(c)
  while true
    input = c.gets.chop     # Odczytanie wiersza danych od klienta.
    break if !input         # Wyjcie, jeli nie ma wicej danych
    break if input=="quit"  # lub jeli klient tego zada.
    c.puts(input.reverse)   # W przeciwnym przypadku wysanie odpowiedzi do klienta.
    c.flush                 # Wymuszenie wyjcia danych.
  end
  c.close                   # Zamknicie gniazda klienta.
end
server = TCPServer.open(2000) # Nasuchiwanie na porcie 2000.
while true                    # Serwery dziaaj w nieskoczono.
  client = server.accept      # Poczekanie, a klient si poczy.
  Thread.start(client) do |c| # Uruchomienie nowego wtku.
    handle_client(c)          # Obsuga klienta w tym wtku.
  end
end

module Enumerable           # Otwarcie moduu Enumerable.
  def conmap(&block)        # Definicja nowej metody wymagajcej bloku.
    threads = []            # Pocztek z pust tablic wtkw.
    self.each do |item|     # Dla kadego elementu umoliwiajcego iteracj.
      # Wywouje blok w nowym wtku i zapamituje ten wtek.
      threads << Thread.new { block.call(item) }
    end
    # Rzutowanie tablicy wtkw na ich wartoci.
    threads.map {|t| t.value } # Zwrcenie tablicy wartoci.
  end
end

module Enumerable
  def concurrently
    map {|item| Thread.new { yield item }}.each {|t| t.join }
  end
end

h.each_pair.concurrently {|*pair| process(pair)}

require 'thread'  # Aby udostpni klas Mutex w Ruby 1.8.
# Konto bankowe ma nazw (name), okrelon ilo rodkw biecych (checking) i okrelon kwot oszczdnoci (savings).
class BankAccount
  def init(name, checking, savings)
    @name,@checking,@savings = name,checking,savings
    @lock = Mutex.new         # Dla bezpieczestwa wtkw.
  end
  # Blokuje konto i przelewa rodki z rachunku oszczdnociowego na biecy.
  def transfer_from_savings(x)
    @lock.synchronize {
      @savings -= x
      @checking += x
    }
  end
  # Blokuje konto i generuje raport o saldach biecych.
  def report
    @lock.synchronize {
      "#@name\nChecking: #@checking\nSavings: #@savings"
    }
  end
end

# Klasyczne zakleszczenie  dwa wtki i dwie blokady.
require 'thread'
m,n = Mutex.new, Mutex.new
t = Thread.new {
  m.lock
  puts "Wtek t zablokowa Mutex m."
  sleep 1
  puts "Wtek t czeka na zablokowanie obiektu Mutex n."
  n.lock
}
s = Thread.new {
  n.lock
  puts "Wtek s zablokowa Mutex n."
  sleep 1
  puts "Wtek s czeka na zablokowanie obiektu Mutex m."
  m.lock
}
t.join
s.join

a = [-2,-1,0,1,2]
mapper = lambda {|x| x*x }             # Obliczanie kwadratw.
injector = lambda {|total,x| total+x } # Obliczanie sumy.
a.conject(0, mapper, injector)         # => 10

module Enumerable
  # Wspbiena metoda inject  przyjmuje warto pocztkow i dwa obiekty klasy Proc.
  def conject(initial, mapper, injector)
    # Uycie kolejki do przekazania wartoci z wtkw rzutujcych do wtku wstawiajcego.
    q = Queue.new
    count = 0                 # Ile elementw?
    each do |item|            # Dla kadego elementu
      Thread.new do           # tworzy nowy wtek.
        q.enq(mapper[item])   # Rzutuje i ustawia w kolejce rzutowan warto.
      end
      count += 1              # Zliczanie elementw.
    end
    t = Thread.new do         # Utworzenie wtku wstawiajcego.
      x = initial             # Start z okrelon wartoci pocztkow.
      while(count > 0)        # Jedno powtrzenie ptli dla kadego elementu.
        x = injector[x,q.deq] # Usunicie wartoci z kolejki i wstawienie jej.
        count -= 1            # Odliczanie w d.
      end
      x                       # Warto wtku to wstawiona warto.
    end
    t.value   # Poczekanie na wtek wstawiajcy i zwrcenie jego wartoci.
  end
end

require 'thread'
class Exchanger
  def initialize
    # Zmienne do przechowywania wartoci do wymiany.
    @first_value = @second_value = nil
    # Obiekt klasy Mutex chronicy dostpu do metody exchange.
    @lock = Mutex.new
    # Obiekt klasy Mutex pozwalajcy sprawdzi, czy metoda exchange
    # jest wywoywana po raz pierwszy, czy drugi.
    @first = Mutex.new
    # Obiekt klasy ConditionVariable pozwalajcy pierwszemu wtkowi poczeka
    # na przybycie drugiego wtku.
    @second = ConditionVariable.new
  end
  # Zamienia t warto na warto przekazan przez drugi wtek.
  def exchange(value)
    @lock.synchronize do      # Tylko jeden wtek moe wywoa t metod w danym momencie.
      if @first.try_lock      # To jest pierwszy wtek.
        @first_value = value  # Zapisanie argumentu pierwszego wtku.
        # Poczekanie na przybycie drugiego wtku.
        # Tymczasowo odblokowuje obiekt klasy Mutex podczas oczekiwania,
        # dziki czemu drugi wtek te moe wywoa t metod.
        @second.wait(@lock)   # Poczekanie na drugi wtek.
        @first.unlock         # Przygotowanie do kolejnej wymiany.
        @second_value         # Zwrcenie wartoci drugiego wtku.
      else                    # W przeciwnym przypadku ten wtek jest drugi.
        @second_value = value # Zapisanie drugiej wartoci.
        @second.signal        # Poinformowanie drugiego wtku, e jeste tutaj.
        @first_value          # Zwrcenie wartoci pierwszego wtku.
      end
    end
  end
end

