x = ARGV[0].to_f  # Konwersja pierwszego argumentu na liczb.
y = ARGV[1].to_f  # Konwersja drugiego argumentu na liczb.
sum = x + y       # Dodanie argumentw.
puts sum          # Wydruk sumy.

if wyraenie
  kod
end

# Jeli x jest mniejsze od 10, zwiksz jego warto.
if x < 10                     # Znak nowego wiersza jako separator.
  x += 1
end
if x < 10 then x += 1 end     # Sowo kluczowe then jako separator.

if x < 10 then
  x += 1
end

if wyraenie
  kod
else
  kod
end

if data         # Jeli tablica ta istnieje,
  data << x     #   dopisz do niej warto.
else            # W przeciwnym przypadku...
  data = [x]    #    utwrz now tablic dla tej wartoci.
end             # Koniec instrukcji warunkowej.

if wyraenie1
  kod1
elsif wyraenie2
  kod2
      .
      .
      .
elsif wyraenieN
  kodN
else
  kod
end

if x == 1
  name = "jeden"
elsif x == 2
  name = "dwa"
elsif x == 3 then name = "trzy"
elsif x == 4; name = "cztery"
else
  name = "duzo"
end

       name = if    x == 1 then "jeden"
              elsif x == 2 then "dwa"
              elsif x == 3 then "trzy"
              elsif x == 4 then "cztery"
              else              "duo"
              end

if wyraenie then kod end

kod if wyraenie

puts message if message    # Wysanie na wyjcie komunikatu, jeli zosta zdefiniowany.

puts message        # Wyraenie bezwarunkowe.
if message          # Niekompletne!

y = x.invert if x.respond_to? :invert
y = (x.invert if x.respond_to? :invert)

if wyraenie     begin                (
  wiersz1           wiersz1              wiersz1
  wiersz2           wiersz2              wiersz2
end              end if wyraenie     ) end if wyraenie

# Wysanie komunikatu na wyjcie, jeli istnieje i jeli metoda wysyajca jest zdefiniowana.
puts message if message if defined? puts

puts message if message and defined? puts

# Jednociekowa instrukcja unless.
unless warunek
  kod
end
# Dwuciekowa instrukcja unless.
unless warunek
  kod
else
  kod
end
# Modyfikator unless.
kod unless warunek

# Wywoanie metody to_s na rzecz obiektu o, chyba e o ma warto nil.
s = unless o.nil?                        # Znak nowego wiersza jako separator.
  o.to_s
end
s = unless o.nil? then o.to_s end        # Sowo kluczowe then jako separator.

s = o.to_s unless o.nil?

unless x == 0
  puts "x nie jest 0"
else
  unless y == 0
    puts "y nie jest 0"
  else
    unless z == 0
      puts "z nie jest 0"
    else
      puts "wszystkie s 0"
    end
  end
end

name = case                           name = if    x == 1 then "jeden"
       when x == 1 then "jeden"              elsif x == 2 then "dwa"
       when x == 2 then "dwa"                elsif x == 3 then "trzy"
       when x == 3 then "trzy"               elsif x == 4 then "cztery"
       when x == 4 then "cztery"             else "duo"
       else "duo"                           end
       end

case
when x == 1
  "jeden"
when x == 2
  "dwa"
when x == 3
  "trzy"
end

case
when x == 1, y == 0 then  "x jest jeden lub y jest zero"  # Niejasna skadnia.
when x == 2 || y == 1 then "x jest dwa lub y jest jeden"  # atwiejsze do zrozumienia.
end

name = case x
       when 1             # Tylko warto do porwnania z x.
         "jeden"
       when 2 then "dwa"  # Sowo kluczowe then zamiast znaku nowego wiersza.
       when 3; "trzy"     # rednik zamiast znaku nowego wiersza.
       else "duo"        # Opcjonalna klauzula else na kocu.
       end

name = case
       when 1 === x then "jeden"
       when 2 === x then "dwa"
       when 3 === x then "trzy"
       else "duo"
       end

# Podejmowanie rnych dziaa w zalenoci od klasy obiektu x.
puts case x
     when String then "acuch"
     when Numeric then "liczba"
     when TrueClass, FalseClass then "warto logiczna"
     else "inna"
     end
# Obliczanie podatku dochodowego przy uyciu instrukcji case i obiektw klasy Range.
tax = case income
      when 0..7550
        income * 0.1
      when 7550..30650
        755 + (income-7550)*0.15
      when 30650..74200
        4220 + (income-30655)*0.25
      when 74200..154800
        15107.5 + (income-74201)*0.28
      when 154800..336550
        37675.5 + (income-154800)*0.33
      else
        97653 + (income-336550)*0.35
      end
# Pobranie danych od uytkownika i przetworzenie ich. Komentarze s ignorowane, a wyjcie
# nastpuje po wpisaniu przez uytkownika sowa koniec.
while line=gets.chomp do  # Zapytanie o dane przy kadej iteracji ptli.
  case line
  when /^\s*#/            # Jeli wprowadzone dane wygldaj jak komentarz...
      next                #   przejcie do nowego wiersza.
  when /^koniec$/i        # Jeli wpisano "koniec" (bez wzgldu na wielko znakw)...
    break                 #   nastpuje wyjcie z ptli.
  else                    # W przeciwnym przypadku...
    puts line.reverse     #   dane uytkownika zostaj odwrcone i wydrukowane.
  end
end

def hasValue?(x)         # Definicja metody o nazwie hasValue?.
  case x                 # Wielociekowa instrukcja warunkowa oparta na wartoci x.
  when nil, [], "", 0    # Jeli nil===x || []===x || ""===x || 0===x, to
    false                #    wartoci zwrotn metody jest false.
  else                   # W przeciwnym przypadku
    true                 #    wartoci zwrotn metody jest true.
  end
end

def how_many_messages(n) # Obsuga liczby pojedynczej i mnogiej.
  "Masz " + n.to_s + (n==1 ? " wiadomo." : " wiadomoci.")
end

x = 10               # Inicjacja licznika ptli.
while x >= 0 do      # Powtarzanie, dopki x jest wiksze lub rwne 0.
  puts x             #   Wydruk wartoci x.
  x = x - 1          #   Odjcie 1 od x.
end                  # Koniec ptli.
# Odliczanie do 10 za pomoc ptli until.
x = 0                # Rozpoczcie od wartoci 0 (zamiast -1).
until x > 10 do      # Powtarzanie, a x bdzie wiksze ni 10.
  puts x
  x = x + 1
end                  # Koniec ptli.

x = 0                          # Inicjacja zmiennej ptlowej.
puts x = x + 1 while x < 10    # Wysanie na wyjcie i inkrementacja w jednym wyraeniu.

x = 0
while x < 10 do puts x = x + 1 end

a = [1,2,3]                 # Inicjacja tablicy.
puts a.pop until a.empty?   # Usuwanie elementw z tablicy, a bdzie pusta.

x = 10              # Inicjacja zmiennej ptlowej.
begin               # Pocztek wyraenia zoonego: wykonywane co najmniej jeden raz.
  puts x            #   Drukuje x.
  x = x - 1         #  Zmniejsza x.
end until x == 0    # Koniec wyraenia zoonego i jego modyfikacja za pomoc ptli.

x = 0               # Inicjacja zmiennej ptlowej.
(                   # Pocztek wyraenia zoonego  moe by wykonane zero razy.
  puts x            #   Drukuje x.
  x = x - 1         #   Zmniejsza x.
) until x == 0      # Koniec wyraenia zoonego i jego modyfikacja za pomoc ptli.

for zmienna in kolekcja do
  ciao
end

# Drukuje elementy tablicy.
array = [1,2,3,4,5]
for element in array
  puts element
end
# Drukuje klucze i wartoci tablicy asocjacyjnej.
hash = {:a=>1, :b=>2, :c=>3}
for key,value in hash
  puts "#{key} => #{value}"
end

hash = {:a=>1, :b=>2, :c=>3}
hash.each do |key,value|
  puts "#{key} => #{value}"
end

3.times { puts "dzikuj!" }   # Podzikowanie trzy razy.
data.each {|x| puts x }        # Wydruk kadego elementu x zmiennej data.
[1,2,3].map {|x| x*x }         # Obliczenie kwadratw elementw tablicy.
factorial = 1                  # Obliczenie silni n.
2.upto(n) {|x| factorial *= x }

chars = "hello world".tap {|x| puts "original object: #{x.inspect}"}
  .each_char         .tap {|x| puts "each_char returns: #{x.inspect}"}
  .to_a              .tap {|x| puts "to_a returns: #{x.inspect}"}
  .map {|c| c.succ } .tap {|x| puts "map returns: #{x.inspect}" }
  .sort              .tap {|x| puts "sort returns: #{x.inspect}"}


4.upto(6) {|x| print x}   # => Drukuje "456".

3.times {|x| print x }    # => Drukuje "012".

0.step(Math::PI, 0.1) {|x| puts Math.sin(x) }

[1,2,3].each {|x| print x }   # => Drukuje "123".
(1..3).each  {|x| print x }   # => Drukuje "123"  to samo, co 1.upto(3).

File.open(filename) do |f|       # Otwarcie podanego pliku, przekazanie jako f.
  f.each {|line| print line }    # Wydruk kadego wiersza z f.
end                              # Koniec bloku i zamknicie pliku.

File.open(filename) do |f|
  f.each_with_index do |line,number|
    print "#{number}: #{line}"
  end
end

squares = [1,2,3].collect {|x| x*x}   # => [1,4,9]

evens = (1..10).select {|x| x%2 == 0} # => [2,4,6,8,10]

odds = (1..10).reject {|x| x%2 == 0}  # => [1,3,5,7,9]

data = [2, 5, 3, 4]
sum = data.inject {|sum, x| sum + x }       # => 14       (2+5+3+4)
floatprod = data.inject(1.0) {|p, x| p*x }  # => 120.0  (1.0*2*5*3*4)
max = data.inject {|m, x| m>x ? m : x }     # => 5         (najwikszy element)

def twice
  yield
  yield
end

# Niniejsza metoda pobiera blok. Generuje n wartoci w formie
# m*i + c, dla i nalecego do zbioru 0..n-1 oraz przekazuje je pojedynczo do
# zwizanego z ni bloku.
def sequence(n, m, c)
  i = 0
  while(i < n)      # Powtrzenie n razy.
    yield m*i + c   # Wywoanie bloku i przekazanie do niego wartoci.
    i += 1          # Zwikszenie i za kadym razem.
  end
end
# Wywoanie zdefiniowanej metody z blokiem.
# Drukuje wartoci 1, 6 i 11.
sequence(3, 5, 1) {|y| puts y }

# Generowanie n punktw rwnomiernie rozmieszczonych na obwodzie
# koa o promieniu r i rodku w punkcie (0,0). Wsprzdne x i y kadego punktu
# s przekazywane do odpowiedniego bloku kodu.
def circle(r,n)
  n.times do |i|    # Niniejsza metoda zostaa zaimplementowana przy uyciu bloku.
    angle = Math::PI * 2 * i / n
    yield r*Math.cos(angle), r*Math.sin(angle)
  end
end
# Niniejsze wywoanie powyszego iteratora drukuje:
# (1.00, 0.00) (0.00, 1.00) (-1.00, 0.00) (-0.00, -1.00).
circle(1,4) {|x,y| printf "(%.2f, %.2f) ", x, y }

# Zwraca tablic n elementw w formie m*i+c.
# Jeli blok zosta podany, kady z tych elementw jest do niego przekazywany.
def sequence(n, m, c)
  i, s = 0, []                  # Inicjacja zmiennych.
  while(i < n)                  # Powtarzanie n razy.
    y = m*i + c                 # Obliczenie wartoci.
    yield y if block_given?     # Przekazanie sterowania i wartoci, jeli jest blok.
    s << y                      # Zapisanie wartoci.
    i += 1
  end
  s                             # Zwrot tablicy wartoci.
end

# Wywoanie metody z enumeratorem zamiast tablicy, ktr mona byoby modyfikowa.
# Jest to przydatna strategia obronna pozwalajca unikn bdw.
process(data.to_enum)  # Zamiast process(data).

s = "hello"
s.enum_for(:each_char).map {|c| c.succ }  # => ["i", "f", "m", "m", "p"].

process(data.each_char)  # Zamiast process(data).

"hello".chars.map {|c| c.succ }  # => ["i", "f", "m", "m", "p"].

enumerator = 3.times             # Obiekt enumeracyjny.
enumerator.each {|x| print x }   # Drukuje "012".
# Metoda downto zwraca enumerator z metod select.
10.downto(1).select {|x| x%2==0}  # => [10,8,6,4,2]
# Metoda iteracyjna each_byte zwraca enumerator z metod to_a.
"hello".each_byte.to_a            # => [104, 101, 108, 108, 111]

def twice
  if block_given?
    yield
    yield
  else
    self.to_enum(:twice)
  end
end

enumerator = s.each_char.with_index

for line, number in text.each_line.with_index
  print "#{number+1}: #{line}"
end

iterator = 9.downto(1)             # Enumerator w roli zewntrznego iteratora.
begin                              # Aby mona byo uy poniej metody rescue.
  print iterator.next while true   # Wielokrotne wywoanie metody next.
rescue StopIteration               # Kiedy nie ma wicej wartoci,
  puts "...start!"                 # nastpuje spodziewana, nie wyjtkowa sytuacja.
end

iterator = 9.downto(1)
loop do                 # Powtarzanie a do wystpienia wyjtku StopIteration.
  print iterator.next   # Wydruk kolejnego elementu.
end
puts "...start!"

module Iterable
  include Enumerable          # Definicja iteratorw na bazie metody each.
  def each                    # Definicja metody each na bazie metody next.
    loop { yield self.next }
  end
end

def iterate(iterator)
  loop { yield iterator.next }
end
iterate(9.downto(1)) {|x| print x }

# Wywoanie metody each po kolei w kadej z kolekcji.
# Nie jest to iteracja rwnolega, a wic nie jest wymagany enumerator.
def sequence(*enumerables, &block)
  enumerables.each do |enumerable|
    enumerable.each(&block)
  end
end
# Iteracja przez podane kolekcje z przeplataniem ich elementw.
# Nie mona tego zrobi szybko bez uycia iteratorw zewntrznych.
# Warto zauway rzadki przypadek uycia klauzuli else w bloku begin-rescue.
def interleave(*enumerables)
  # Konwersja przeliczalnych kolekcji na tablic enumeratorw.
  enumerators = enumerables.map {|e| e.to_enum }
  # Ptla dziaa tak dugo, a wyczerpi si enumeratory.
  until enumerators.empty?
    begin
      e = enumerators.shift   # Pobranie pierwszego enumeratora.
      yield e.next            # Pobranie kolejnego elementu i przekazanie go do bloku.
    rescue StopIteration      # Jeli nie ma wicej elementw, nic si nie dzieje.
    else                      # Jeli nie wystpi aden wyjtek,
      enumerators << e        # enumerator zostaje zwrcony z powrotem.
    end
  end
end
# Iteracja przez okrelone kolekcje ze zwrotem krotek wartoci,
# po jednej wartoci z kadej kolekcji. Zobacz te Enumerable.zip.
def bundle(*enumerables)
  enumerators = enumerables.map {|e| e.to_enum }
  loop { yield enumerators.map {|e| e.next} }
end
# Przykady dziaania powyszych metod iteracyjnych.
a,b,c = [1,2,3], 4..6, 'a'..'e'
sequence(a,b,c) {|x| print x}   # Drukuje "123456abcde".
interleave(a,b,c) {|x| print x} # Drukuje "14a25b36cde".
bundle(a,b,c) {|x| print x}     # '[1, 4, "a"][2, 5, "b"][3, 6, "c"]'.

a = [1,2,3,4,5]
a.each {|x| puts "#{x},#{a.shift}" }  # Drukuje "1,1\n3,2\n5,3".

module Enumerable
  def each_in_snapshot &block
    snapshot = self.dup    # Utworzenie prywatnej kopii obiektu Enumerable.
    snapshot.each &block   # Iteracja po tej kopii.
  end
end

# Drukuje liczby od 1 do 10.
1.upto(10) {|x| puts x }   # Wywoanie i blok w jednym wierszu z klamrami.
1.upto(10) do |x|          # Blok ograniczony sowami kluczowymi do i end.
  puts x
end
1.upto(10)                 # aden blok nie zosta podany.
 {|x| puts x }             # Bd skadni: blok nie znajduje si za wywoaniem.

1.upto(3) {|x| puts x }    # Nawiasy i klamry dziaaj dobrze.
1.upto 3 do |x| puts x end # Brak nawiasw, blok otoczony sowami kluczowymi do i end.
1.upto 3 {|x| puts x }     # Bd skadni: prba przekazania bloku do liczby 3!

# Iterator Hash.each przekazuje dwa argumenty do swojego bloku.
hash.each do |key, value|   # Dla kadej pary (key,value) w tablicy asocjacyjnej.
  puts "#{key}: #{value}"   # Drukuje klucz i jego warto.
end                         # Koniec bloku.

# Blok pobiera dwa sowa i zwraca je w porzdku wg dugoci.
words.sort! {|x,y| y.length <=> x.length }

array.collect do |x|
  next 0 if x == nil  # Przedwczesny zwrot wartoci, jeli x ma warto nil.
  next x, x*x         # Zwrot dwch wartoci.
end

array.collect do |x|
  if x == nil
    0
  else
    [x, x*x]
  end
end

total = 0
data.each {|x| total += x }  # Sumowanie elementw tablicy data.
puts total                   # Wydruk tej sumy.

1.upto(10) do |i|            # 10 wierszy,
  1.upto(10) do |i|          # kady zawiera 10 kolumn.
    print "#{i} "            # Drukowanie numeru kolumny.
  end
  print " ==> Wiersz #{i}\n" # Prba wydrukowania numeru wiersza, ale pobranie numeru kolumny.
end

x = y = 0            # Zmienne lokalne.
1.upto(4) do |x;y|   # Zmienne x i y maj zasig blokowy.
                     # Zmienne x i y zasaniaj zewntrzne zmienne.
  y = x + 1          # Zmienna y uyta jako zmienna pocztkowa.
  puts y*y           # Drukuje 4, 9, 16, 25.
end
[x,y]                # => [0,0]: blok nie zmienia tych wartoci.

hash.each {|key,value; i,j,k| ... }

key,value = k,v

{:one=>1}.each_pair {|key,value| ... } # key=:one, value=1

{:one=>1}.each_pair {|$key, @value| ... } # Nie dziaa w Ruby 1.9.

hash.each {|k,v| ... }  # Klucz i warto przypisane do parametrw k i v.

k,v = [key, value]

def two; yield 1,2; end  # Iterator zwracajcy dwie wartoci.
two {|x| p x }     # Ruby 1.8: ostrzega i drukuje [1,2],
two {|x| p x }     # Ruby 1.9: drukuje 1, nie ostrzega.
two {|*x| p x }    # Obie wersje: drukuje [1,2]; bez ostrzeenia.
two {|x,| p x }    # Obie wersje: drukuje 1; bez ostrzeenia.

def five; yield 1,2,3,4,5; end     # Zwrot piciu wartoci.
five do |head, *body, tail|        # Nadwykowe wartoci przechodz do tablicy body.
  print head, body, tail           # Drukuje "1[2,3,4]5".
end

def hashiter; yield :a=>1, :b=>2; end  # Brak nawiasw klamrowych.
hashiter {|hash| puts hash[:a] }       # Drukuje 1.

# Niniejszy obiekt klasy Proc spodziewa si bloku.
printer = lambda {|&b| puts b.call } # Wydruk wartoci zwrconej przez b.
printer.call { "hi" }                # Przekazanie bloku do bloku!

[1,2,3].each {|x,y=10| print x*y }     # Bd skadni!


[1,2,3].each &->(x,y=10) { print x*y }  # Drukuje "102030".

# Zwrot dwch kopii x, jeli x nie ma wartoci nil.
def double(x)
  return nil if x == nil   # Przedwczesny zwrot wartoci.
  return x, x.dup          # Zwrot kilku wartoci.
end


# Zwrot indeksu pierwszego wystpienia celu w tablicy lub wartoci nil.
# Zauwa, e niniejszy kod powiela tylko metod Array.index.
def find(array, target)
  array.each_with_index do |element,index|
    return index if (element == target)  # Zwrot wartoci przez metod find.
  end
  nil  # Jeli element nie zostanie znaleziony, zwracana jest warto nil.
end

while(line = gets.chop)     # Pocztek ptli.
  break if line == "quit"   # Jeli ta instrukcja break zostanie wykonana...
  puts eval(line)
end
puts "Do widzenia"          # ... sterowanie zostanie przekazane do tego miejsca.


while(line = gets.chop)     # Pocztek ptli.
  next if line[0,1] == "#"  # Jeli ten wiersz jest komentarzem, przejd do kolejnego.
  puts eval(line)
  # Sterowanie przechodzi do tego miejsca po wykonaniu instrukcji next.
end

f.each do |line|              # Iteracja przez wiersze pliku f.
  next if line[0,1] == "#"    # Jeli ten wiersz jest komentarzem, przejd do kolejnego.
  puts eval(line)
  # Sterowanie przechodzi do tego miejsca po wykonaniu instrukcji next.
end


squareroots = data.collect do |x|
  next 0 if x < 0  # Zwraca 0 dla ujemnych wartoci.
  Math.sqrt(x)
end

squareroots = data.collect do |x|
  if (x < 0) then 0 else Math.sqrt(x) end
end

i = 0
while(i < 3)   # Drukuje "0123" zamiast "012".
  # Po wykonaniu instrukcji redo sterowanie wraca do tego miejsca.
  print i
  i += 1
  redo if i == 3
end

puts "Podaj pierwsze sowo, ktre przychodzi ci do gowy"
words = %w(jabko banan winia)   # Skrcony zapis ["jabko", "banan", "winia"].
response = words.collect do |word|
  # Po wykonaniu instrukcji redo sterowanie wraca do tego miejsca.
  print word + "> "               # Zapytanie uytkownika.
  response = gets.chop            # Pobranie odpowiedzi.
  if response.size == 0           # Jeli uytkownik nic nie wpisa,
    word.upcase!                  # po nacisk na prob, drukujc j wielkimi literami.
    redo                          # Przejcie na pocztek bloku.
  end
  response                        # Zwrcenie odpowiedzi.
end

n = 10
n.times do |x|   # Iteracja n razy od 0 do n1.
  print x        # Drukowanie numeru iteracji.
  if x == 9      # Jeli doszede do numeru 9,
    n -= 1       # zmniejsz n (nastpnym razem nie dojdziesz do 9!)
    retry        # Restart iteracji.
  end
end

# Niniejsza metoda dziaa jak ptla while: jeli x nie ma wartoci nil ani false,
# nastpuje wywoanie bloku i ponowna prba zrestartowania ptli oraz sprawdzenie
# warunku. Metoda ta nieco rni si od prawdziwej ptli while:
# ciao ptli mona umieci, podobnie jak w jzyku C, w nawiasach klamrowych.
# Dodatkowo zmienne uywane tylko w obrbie ciaa ptli pozostaj lokalne w tym bloku.
def repeat_while(x)
  if x     # Jeli warunek nie zwrci wartoci nil ani false,
    yield  # nastpuje uruchomienie ciaa ptli.
    retry  # Ponowne wyprbowanie i obliczenie warunku ptli.
  end
end

for matrix in data do             # Przetwarzanie gboko zagniedonej struktury danych.
  catch :missing_data do          # Nadanie instrukcji etykiety, aby mona byo z niej wyj.
    for row in matrix do
      for value in row do
        throw :missing_data unless value # Wyjcie z dwch ptli naraz.
        # W przeciwnym przypadku przetwarzane s dane.
      end
    end
  end
  # Koniec nastpuje w tym miejscu, po zakoczeniu przetwarzania kadej macierzy przez ptle.
  # Docierasz tutaj take wtedy, gdy zostanie spowodowany wyjtek :missing_data.
end

Object
 +--Exception
     +--NoMemoryError
     +--ScriptError
     |   +--LoadError
     |   +--NotImplementedError
     |   +--SyntaxError
     +--SecurityError         # StandardError w 1.8.
     +--SignalException
     |   +--Interrupt
     +--SystemExit
     +--SystemStackError      # StandardError w 1.8.
     +--StandardError
         +--ArgumentError
         +--FiberError        # Nowo w 1.9.
         +--IOError
         |   +--EOFError
         +--IndexError
         |   +--KeyError      # Nowo w 1.9.
         |   +--StopIteration # Nowo w 1.9.
         +--LocalJumpError
         +--NameError
         |   +--NoMethodError
         +--RangeError
         |   +--FloatDomainError
         +--RegexpError
         +--RuntimeError
         +--SystemCallError
         +--ThreadError
         +--TypeError
         +--ZeroDivisionError

def factorial(n)                 # Definicja metody factorial z argumentem n.
  raise "zy argument" if n < 1  # Zgoszenie wyjtku dla zej wartoci n.
  return 1 if n == 1             # factorial(1) wynosi 1.
  n * factorial(n-1)             # Rekursywne obliczenie innych silni (factorial).
end

raise RuntimeError, "zy argument" if n < 1
raise RuntimeError.new("zy argument") if n < 1
raise RuntimeError.exception("zy argument") if n < 1

raise ArgumentError if n < 1

raise ArgumentError, "Spodziewany argument >= 1. Otrzymano #{n}" if n < 1

if n < 1
  raise ArgumentError, "Spodziewany argument >= 1. Otrzymano #{n}", caller
end

raise TypeError, "Oczekiwana liczba cakowita" if not n.is_a? Integer

begin
  # W tym miejscu moe znajdowa si dowolna liczba instrukcji.
  # Zazwyczaj s one wykonywane bez adnych problemw i
  # wykonywanie jest kontynuowane od miejsca za instrukcj end.
rescue
  # To jest klauzula rescue, w ktrej znajduje si kod obsugi wyjtkw.
  # Jeli powyszy kod zgosi wyjtek lub zostanie on przesany z
  # jednej z metod wywoanych wyej, wykonywany jest ten kod.
end

require 'English'

rescue => ex

begin                                # Blok obsugujcy wyjtki.
  x = factorial(-1)                  # Nieprawidowy argument.
rescue => ex                         # Zapisanie wyjtku w zmiennej ex.
  puts "#{ex.class}: #{ex.message}"  # Obsuga wyjtku polegajca na wydrukowaniu komunikatu.
end                                  # Koniec bloku begin-rescue.

rescue Exception

rescue ArgumentError => e

rescue ArgumentError, TypeError => error

begin
  x = factorial(1)
rescue ArgumentError => ex
  puts "Sprbuj ponownie z wartoci >= 1"
rescue TypeError => ex
  puts "Sprbuj ponownie z liczb cakowit"
end

def explode        # Niniejsza metoda zgasza wyjtek klasy RuntimeError w 10% przypadkw.
  raise "bam!" if rand(10) == 0
end
def risky
  begin            # Ten blok
    10.times do    # zawiera inny blok,
      explode      # ktry moe zgosi wyjtek.
    end            # Nie ma tu klauzuli rescue, a wic wychodzisz na zewntrz.
  rescue TypeError # Niniejsza klauzula rescue nie moe obsuy wyjtku RuntimeError,
    puts $!        # a wic zostaje pominita i wyjtek jest propagowany dalej.
  end
  "hello"          # Normalna warto zwrotna, jeli nie wystpi aden wyjtek.
end                # Tutaj nie ma klauzuli rescue, a wic wyjtek przesyany jest do wywoujcego.
def defuse
  begin                     # Niniejszy kod moe spowodowa wyjtek.
    puts risky              # Prba wywoania oraz wydrukowania wartoci zwrotnej.
  rescue RuntimeError => e  # Jeli zosta zgoszony wyjtek,
    puts e.message          # w zamian drukujesz komunikat o bdzie.
  end
end
defuse


require 'open-uri'
tries = 0       # Ile razy prbowano odczyta podany adres URL.
begin           # Pocztek instrukcji retry.
  tries += 1    # Prba wydrukowania zawartoci adresu URL.
  open('http://www.example.com/') {|f| puts f.readlines }
rescue OpenURI::HTTPError => e  # Jeli wystpi bd HTTP,
  puts e.message                # drukuje komunikat o bdzie.
  if (tries < 4)                # Jeli nie byo jeszcze czterech prb...
    sleep(2**tries)             # czeka 2, 4 i 8 sekund.
    retry                       # A nastpnie prbuje ponownie!
  end
end

begin
  return 1     # Przechodzi do klauzuli ensure przed zwrotem wartoci do wywoujcego.
ensure
  return 2     # Warto zwrotna zostanie zastpiona t now wartoci.
end

def test
  begin return 1 ensure 2 end
end

def method_name(x)
  # Tutaj znajduje si ciao metody.
  # Zazwyczaj kod ten jest wykonywany do samego koca, bez adnych wyjtkw
  # i normalnie zwraca warto do swojego wywoujcego.
rescue
  # W tym miejscu znajduje si kod obsugi bdw.
  # Jeli w ciele metody zostanie zgoszony wyjtek lub jeli
  # jedna z wywoanych w tym ciele metod zgosi wyjtek, sterowanie
  # zostaje przekazane do tego bloku.
else
  # Jeli w ciele metody nie wystpi adne wyjtki,
  # zostanie wykonany kod tej klauzuli.
ensure
  # Niniejszy kod zostanie wykonany bez wzgldu na to, co si stanie w
  # ciele metody. Jest on wykonywany, gdy metoda zostanie w caoci wykonana, jeli
  # wyrzuci wyjtek lub wykona instrukcj return.
end

# Oblicza silni x lub uywa wartoci 0, jeli metoda zgosi wyjtek.
y = factorial(x) rescue 0

y = begin
      factorial(x)
    rescue
      0
    end

BEGIN {
  # Gobalny kod inicjujcy.
}
END {
  # Globalny kod koczcy.
}

if (false)
  BEGIN {
    puts "ptla";                # To zostanie wydrukowane.
    a = 4;                       # Ta zmienna jest zdefiniowana tylko tutaj.
  }
else
  BEGIN { puts "if" }            # To take bdzie wydrukowane.
end
10.times {BEGIN { puts "else" }} # To zostanie wydrukowane tylko jeden raz.

a = 4;
if (true)
  END {                        # Ta instrukcja END jest wykonywana.
    puts "petla";              # Ten kod zostaje zarejestrowany.
    puts a                     # Ta zmienna jest widoczna; drukuje 4.
  }
else
  END { puts "if" }            # Ten kod nie jest wykonywany.
end
10.times {END { puts "else" }} # To jest wykonywane tylko jeden raz.

# Niniejsza metoda pobiera tablic nazw plikw.
# Zwraca tablic acuchw reprezentujcych tre podanych plikw.
# Metoda ta tworzy po jednym wtku dla kadego przekazanego do niej pliku.
def readfiles(filenames)
  # Utworzenie tablicy wtkw z tablicy nazw plikw.
  # Kady wtek zaczyna odczytywa plik.
  threads = filenames.map do |f|
    Thread.new { File.read(f) }
  end
  # Teraz zostanie utworzona tablica dla zawartoci plikw poprzez wywoanie metody
  # value kadego z wtkw. Metoda ta zostaje w razie potrzeby zablokowana,
  # a wtek zakoczy dziaanie i zwrci warto.
  threads.map {|t| t.value }
end

f = Fiber.new {                       # Wiersz 1: utworzenie nowego wkna.
  puts "Wkno wita si"              # Wiersz 2:
  Fiber.yield                         # Wiersz 3: przejcie do wiersza 9.
  puts "Wkno egna si"             # Wiersz 4:
}                                     # Wiersz 5: przejcie do wiersza 11.
                                      # Wiersz 6:
puts "Algorytm wywoujcy wita si"   # Wiersz 7:
f.resume                              # Wiersz 8: przejcie do wiersza 2.
puts "Algorytm wywoujcy egna si"  # Wiersz 9:
f.resume                              # Wiersz 10: przejcie do wiersza 4.
                                      # Wiersz 11:

Algorytm wywoujcy wita si
Wkno wita si
Algorytm wywoujcy egna si
Wkno egna si

f = Fiber.new do |message|
  puts "Algorytm wywoujcy mwi: #{message}"
  message2 = Fiber.yield("Witaj")    # acuch "Witaj" zwrcony przez pierwsze wywoanie metody resume.
  puts "Algorytm wywoujcy mwi: #{message2}"
  "W porzdku"                       # acuch "W porzdku" zwrcony przez drugie wywoanie metody resume.
end
response = f.resume("Witaj")         # acuch "Witaj" przekazany do bloku.
puts "Wkno mwi: #{response}"
response2 = f.resume("Jak leci?")    # acuch "Jak leci?" zwrcony przez wywoanie metody Fiber.yield.
puts "Wkno mwi: #{response2}"

Algorytm wywoujcy mwi: Witaj
Wkno mwi: Witaj
Algorytm wywoujcy mwi: Jak leci?
Wkno mwi: W porzdku

# Zwraca obiekt klasy Fiber obliczajcy liczby Fibonacciego.
def fibonacci_generator(x0,y0)   # Oparcie cigu na x0,y0.
  Fiber.new do
    x, y = x0, y0                # Inicjacja x i y.
    loop do                      # To wkno dziaa wiecznie.
      Fiber.yield y              # Zwrot kolejnej liczby cigu.
      x,y = y,x+y                # Aktualizacja x i y.
    end
  end
end
g = fibonacci_generator(0,1)     # Utworzenie generatora.
10.times { print g.resume, " " } # Uycie generatora.

1 1 2 3 5 8 13 21 34 55

class FibonacciGenerator
  def initialize
    @x,@y = 0,1
    @fiber = Fiber.new do
      loop do
        @x,@y = @y, @x+@y
        Fiber.yield @x
      end
    end
  end
  def next           # Zwrot kolejnej liczby Fibonacciego.
    @fiber.resume
  end
  def rewind         # Ponowne uruchomienie cigu.
    @x,@y = 0,1
  end
end
g = FibonacciGenerator.new      # Utworzenie generatora.
10.times { print g.next, " " }  # Wydruk pierwszych dziesiciu liczb.
g.rewind; puts                  # Rozpoczcie od nowa w nowym wierszu.
10.times { print g.next, " " }  # Ponowny wydruk dziesiciu pierwszych liczb.

def each
   loop { yield self.next }
end

class Generator
  def initialize(enumerable)
    @enumerable = enumerable  # Zapamitanie obiektu przeliczalnego.
    create_fiber              # Utworzenie wkna sucego do jego przeliczania.
  end
  def next                    # Zwrot kolejnego elementu
    @fiber.resume             # poprzez uruchomienie wkna.
  end
  def rewind                  # Ponowne uruchomienie enumeracji
    create_fiber              # poprzez utworzenie nowego wkna.
  end
  private
  def create_fiber            # Utworzenie wkna odpowiedzialnego za enumeracj.
    @fiber = Fiber.new do     # Utworzenie nowego wkna.
      @enumerable.each do |x| # Uycie metody each.
        Fiber.yield(x)        # Wstrzymanie enumeracji w celu zwrotu wartoci.
      end
      raise StopIteration     # Zgoszenie wyjtku, kiedy nie ma ju wartoci.
    end
  end
end
g = Generator.new(1..10)  # Utworzenie generatora.
loop { print g.next }     # Uycie go jak enumeratora.
g.rewind                  # Rozpoczcie od pocztku.
g = (1..10).to_enum       # Metoda to_enum robi to samo.
loop { print g.next }

require 'fiber'

require 'fiber'
f = g = nil
f = Fiber.new {|x|        # 1:
  puts "f1: #{x}"         # 2: drukuje "f1: 1".
  x = g.transfer(x+1)     # 3: przekazuje 2 do wiersza 8.
  puts "f2: #{x}"         # 4: drukuje "f2: 3".
  x = g.transfer(x+1)     # 5: zwraca 4 do wiersza 10.
  puts "f3: #{x}"         # 6: drukuje "f3: 5".
  x + 1                   # 7: zwraca 6 do wiersza 13.
}
g = Fiber.new {|x|        # 8:
  puts "g1: #{x}"         # 9: drukuje "g1: 2".
  x = f.transfer(x+1)     #10: zwraca 3 do wiersza 3.
  puts "g2: #{x}"         #11: drukuje "g2: 4".
  x = f.transfer(x+1)     #12: zwraca 5 do wiersza 5.
}
puts f.transfer(1)        #13: przekazuje 1 do wiersza 1.

f1: 1
g1: 2
f2: 3
g2: 4
f3: 5
6

require 'continuation'

# Globalna tablica asocjacyjna wica numery wierszy (lub symbole) z kontynuacjami.
$lines = {}
# Utworzenie kontynuacji i powizanie jej z okrelonym numerem wiersza.
def line(symbol)
  callcc {|c| $lines[symbol] = c }
end
# Odszukanie kontynuacji zwizanej z tym numerem i przeskoczenie do niej.
def goto(symbol)
  $lines[symbol].call
end
# Teraz moesz udawa, e programujesz w jzyku BASIC.
i = 0
line 10              # Deklaracja tego miejsca jako wiersza numer 10.
puts i += 1
goto 10 if i < 5     # Przeskok z powrotem do wiersza numer 10, jeli warunek zosta speniony.
line 20              # Deklaracja miejsca jako wiersz numer 20.
puts i -= 1
goto 20 if i > 0

