# To jest komentarz=begin
To jest wielolinijkowy komentarz
Nikt ich nie używa
Ty też nie powinieneś
=end# Przede wszystkim: Wszystko jest obiektem.# Liczby są obiektami3.class#=> Fixnum3.to_s#=> "3"# Trochę podstawowej arytmetyki1+1#=> 28-1#=> 710*2#=> 2035/5#=> 72**5#=> 325%3#=> 25^6#=> 3# Arytmetyka jest zastąpeniem składni# metod wywoływanych na obiektach1.+(3)#=> 410.*5#=> 50# Wartości specjalne są obiektaminil# To na prawdę jest niczymtrue# prawdafalse# fałsznil.class#=> NilClasstrue.class#=> TrueClassfalse.class#=> FalseClass# Równość1==1#=> true2==1#=> false# Nierówność1!=1#=> false2!=1#=> true# jedyną 'fałszywą' wartością poza false, jest nil !nil#=> true!false#=> true!0#=> false# Więcej porównań1<10#=> true1>10#=> false2<=2#=> true2>=2#=> true# Operatory logicznetrue&&false#=> falsetrue||false#=> true!true#=> false# Istnieją alternatywne wersje operatorów logicznych ze znacznie mniejszym# pierwszeństwem. Używane są by kontrolować wyrażenia w łańcuchach wyrażeń# aż jedno z nich wróci true lub false.# `zrob_cos_innego` wywołaj tylko wtedy gdy `zrob_cos` zakończy się sukcesem.zrob_cos_innego()andzrob_cos()# `log_error` wywołaj tylko wtedy gdy `zrob_cos` nie zakończy się sukcesem.zrob_cos()orlog_error()# Stringi są obiektami'Jestem stringiem.'.class#=> String"Ja również jestem stringiem.".class#=> Stringwypelnienie='użyć interpolacji stringa'"Potrafię #{wypelnienie} używając podwójnych cudzysłowów."#=> "Potrafię użyć interpolacji stringa używając podwójnych cudzysłowów."# Staraj się zapisywać stringi za pomocą apostrof, zamiast cudzysłowów tam, gdzie to możliwe# Cudzysłowy wykonują dodatkowe wewnętrzne operacje# Łączenie stringów, ale nie liczb'hej '+'świecie'#=> "hej świecie"'hej '+3#=> TypeError: can't convert Fixnum into String'hej '+3.to_s#=> "hej 3"# Łączenie stringów i operatorów'hej '*3#=> "hej hej hej "# Dodawanie do stringa'hej'<<' świecie'#=> "hej świecie"# wydrukowanie wartości wraz z nową linią na końcuputs"Drukuję!"#=> Drukuję!#=> nil# wydrukowanie wartości bez nowej linii na końcu print"Drukuję!"#=> Drukuję! => nill# Zmiennex=25#=> 25x#=> 25# Zauważ, że przypisanie zwraca przypisywaną wartość# To znaczy, że możesz wykonać wielokrotne przypisanie:x=y=10#=> 10x#=> 10y#=> 10# Zwyczajowo, używaj notacji nazwa_zmiennej dla nazw zmiennychnazwa_zmiennej=true# Używaj opisowych nazw zmiennychsciezka_do_projektu='/dobra/nazwa/'sciezka='/zla/nazwa/'# Symbole (są obiektami)# Symbole są niezmiennymi, wielokrotnie używanymi stałymi reprezentowanymi wewnętrznie jako # liczby całkowite. Często używane są zamiast stringów w celu wydajniejszego przekazywania danych:oczekujacy.class#=> Symbolstatus=:oczekujacystatus==:oczekujacy#=> truestatus=='oczekujacy'#=> falsestatus==:zatwierdzony#=> false# Tablice# To jest tablicaarray=[1,2,3,4,5]#=> [1, 2, 3, 4, 5]# Tablice mogą zwierać różne typy danych[1,'hej',false]#=> [1, "hej", false]# Tablice mogę być indeksowane# Od początkutablica[0]#=> 1tablica.first#=> 1tablica[12]#=> nil# Podobnie jak przy arytmetyce, dostęp poprzez [zmienna]# jest tylko czytelniejszą składnią# dla wywoływania metody [] na obiekcietablica.[]0#=> 1tablica.[]12#=> nil# Od końcatablica[-1]#=> 5tablica.last#=> 5# Z początkowym indeksem i długościątablica[2,3]#=> [3, 4, 5]# Odwrotność tablicya=[1,2,3]a.reverse!#=> [3,2,1]# Lub zakresarray[1..3]#=> [2, 3, 4]# Dodawanie do tablicy w taki sposóbtablica<<6#=> [1, 2, 3, 4, 5, 6]# Lub takitablica.push(6)#=> [1, 2, 3, 4, 5, 6]# Sprawdzanie, czy tablica zawiera elementtablica.include?(1)#=> true# Hasze są Ruby'owymi podstawowymi słownikami z parami klucz/wartość.# Hasze są zapisywane za pomocą nawiasów klamrowychhasz={'kolor'=>'zielony','numer'=>5}hasz.keys#=> ['kolor', 'numer']# Można szybko sprawdzić zawartość hasza za pomocą kluczy:hasz['kolor']#=> 'zielony'hasz['numer']#=> 5# Sprawdzenie wartośći dla nieistniejącego klucza zwraca nil:hasz['nic tutaj nie ma']#=> nil# Od wersji 1.9, Ruby posiada specjalną składnię, gdy używamy symboli jako kluczy:nowy_hasz={stan:3,akcja:true}nowy_hasz.keys#=> [:stan, :akcja]# Sprawdzenie istnienia kluczy i wartości w haszunew_hash.has_key?(:defcon)#=> truenew_hash.has_value?(3)#=> true# Wskazówka: Zarówno tablice, jak i hasze, są policzalne# Współdzielą wiele metod takich jak each, map, count, i inne# Instrukcje warunkoweiftrue'wyrażenie if'elsiffalse'wyrażenie if, opcjonalne'else'wyrażenie else, również opcjonalne'endforlicznikin1..5puts"powtórzenie #{licznik}"end#=> powtórzenie 1#=> powtórzenie 2#=> powtórzenie 3#=> powtórzenie 4#=> powtórzenie 5# JEDNAKŻE, Nikt nie używa pętli for.# Zamiast tego, powinno się używać metody "each" i podawać jej blok.# Blok jest kawałkiem kodu, który możesz podać metodzie podobnej do "each".# Jest analogiczny do wyrażeń lambda, funkcji anonimowych lub zamknięć w innych# językach programowania.## Metoda "each" danego zakresu, wykonuje blok dla każdego elementu w zakresie.# Do bloku zostaje przekazany licznik jako parametr.# Wykonanie metody "each" z przekazaniem bloku wygląda następująco:(1..5).eachdo|licznik|puts"powtórzenie #{licznik}"end#=> powtórzenie 1#=> powtórzenie 2#=> powtórzenie 3#=> powtórzenie 4#=> powtórzenie 5# Możesz również otoczyć blok nawiasami klamrowymi:(1..5).each{|licznik|puts"powtórzenie #{licznik}"}# Zawartość struktur danych również może być powtarzana używając each.tablica.eachdo|element|puts"#{element} jest częścią tablicy"endhasz.eachdo|klucz,wartosc|puts"#{klucz} jest #{wartosc}"end# Jeśli nadal potrzebujesz indeksum, możesz użyć "each_with_index" i zdefiniować # zmienną odpowiadającą indeksowitablica.each_with_indexdo|element,indeks|puts"#{element} jest numerem #{indeks} w tablicy"endlicznik=1whilelicznik<=5doputs"powtórzenie #{licznik}"licznik+=1end#=> powtórzenie 1#=> powtórzenie 2#=> powtórzenie 3#=> powtórzenie 4#=> powtórzenie 5# W Ruby istnieje dużo pomocnych funkcji wykonujących pętle,# na przykład "map", "reduce", "inject" i wiele innych. Map,# w każdym wywołaniu, pobiera tablicę, na której wykonuję pętlę,# wykonuje kod zapisany za pomocą bloku i zwraca całkowicie nową tablicę.tablica=[1,2,3,4,5]podwojone=tablica.mapdo|element|element*2endputspodwojona#=> [2,4,6,8,10]putstablica#=> [1,2,3,4,5]ocena=2caseocenawhen1puts'Dobra robota, masz wolne'when2puts'Następnym razem będziesz miał więcej szczęścia'when3puts'Możesz to zrobić lepiej'when4puts'Przebrnąłeś'when5puts'Oblałeś!'elseputs'Inny system oceniania?'end#=> "Następnym razem będziesz miał więcej szczęścia"# case może również użwać zakresówocena=82caseocenawhen90..100puts'Hurra!'when80...90puts'Dobra robota'elseputs'Oblałeś!'end#=> "Dobra robota"# obsługa błędów:begin# kod, który może wywołać wyjątekraiseNoMemoryError,'Zabrakło pamięci.'rescueNoMemoryError=>zmienna_wyjatkuputs'Został wywołany NoMemoryError',zmienna_wyjatkurescueRuntimeError=>inna_zmienna_wyjatkuputs'Teraz został wywołany RuntimeError'elseputs'To zostanie uruchomione, jeśli nie wystąpi żaden wyjątek'ensureputs'Ten kod wykona się zawsze'end# Funkcjedefpodwojenie(x)x*2end# Funkcje (i wszystkie bloki) zawsze zwracają wartość ostatniego wyrażeniapodwojenie(2)#=> 4# Okrągłe nawiady są opcjonalne, gdy wynik jest jednoznacznypodwojenie3#=> 6podwojeniepodwojenie3#=> 12defsuma(x,y)x+yend# Argumenty metod są oddzielone przecinkamisuma3,4#=> 7sumasuma(3,4),5#=> 12# yield# Wszystkie metody mają ukryty, opcjonalny parametr bloku,# który może być wykonany używając słowa kluczowego 'yield'defotoczenieputs'{'yieldputs'}'endotoczenie{puts'hej świecie'}# {# hej świecie# }# Możesz przekazać blok do funkcji# "&" oznacza referencję to przekazanego blokudefgoscie(&blok)blok.call'jakis_argument'end# Możesz przekazać listę argumentów, które będę przekonwertowane na tablicę# Do tego służy operator ("*")defgoscie(*tablica)tablica.each{|gosc|putsgosc}end# Definiowanie klas używając słowa kluczowego classclassCzlowiek# Zmienna klasowa. Jest współdzielona przez wszystkie instancje tej klasy.@@gatunek='H. sapiens'# Podstawowe inicjalizowaniedefinitialize(imie,wiek=0)# Przypisanie argumentu do zmiennej danej instancji o nazwie "imie"@imie=imie# Jeśli nie podano wieku, zostanie użyta domyślna wartość z listy argumentów.@wiek=wiekend# Podstawowa metoda przypisująca wartośćdefimie=(imie)@imie=imieend# Podstawowa metoda pobierająca wartośćdefimie@imieend# Powyższa funkcjonalność może być zastąpiona używając metody attr_accessor w taki sposóbattr_accessor:imie# Metody przypisujące/pobierające mogą być stworzone indywidualnieattr_reader:imieattr_writer:imie# Metody klasowe używają self aby odróżnić się od metody instancji.# To może być wywołane na klasie, nie na instancji.defself.powiedz(wiadomosc)putswiadomoscenddefgatunek@@gatunekendend# Tworzenie instancji klasyjim=Czlowiek.new('Jim Halpert')dwight=Czlowiek.new('Dwight K. Schrute')# Wywołajmy parę metodjim.gatunek#=> "H. sapiens"jim.imie#=> "Jim Halpert"jim.imie="Jim Halpert II"#=> "Jim Halpert II"jim.imie#=> "Jim Halpert II"dwight.gatunek#=> "H. sapiens"dwight.imie#=> "Dwight K. Schrute"# Wywołanie metody klasowejCzlowiek.powiedz('Cześć')#=> "Cześć"# Zasięg zmiennej jest definiowany poprzez jej nazwę.# Zmienne, które zaczynają się na $ mają zasięg globalny$zmienna="Jestem zmienną globalną"defined?$zmienna#=> "global-variable"# Zmienne zczynające się na @ mają zasięg danej instancji@zmienna="Jestem zmienną instancji"defined?@zmienna#=> "instance-variable"# Zmienne, które zaczynają się na @@ mają zasięg danej klasy@@zmienna="Jestem zmienną klasową"defined?@@zmienna#=> "class variable"# Zmienne, które zaczynają się na dużą literę, są stałymiZmienna="Jestem stałą"defined?Zmienna#=> "constant"# Klasa jest również obiektem w ruby. Może więc mieć zmienne instancji.# Zmienna klasowa może być współdzielona między klasą i jej potomstwem.# podstawowa klasaclassCzlowiek@@cokolwiek=0defself.cokolwiek@@cokolwiekenddefself.cokolwiek=(wartosc)@@cokolwiek=wartoscendend# klasa pochodnaclassPracownik<CzlowiekendCzlowiek.cokolwiek# 0Pracownik.cokolwiek# 0Czlowiek.cokolwiek=2# 2Pracownik.cokolwiek# 2# Zmienna instancji danej klasy nie jest współdzielona przez jej potomstwo.classCzlowiek@cos=0defself.cos@cosenddefself.cos=(wartosc)@cos=wartoscendendclassDoktor<CzlowiekendCzlowiek.cos# 0Doktor.cos# nilmodulePrzykladowyModuldefcokolwiek'cokolwiek'endend# Włączanie modułów łączy ich metody z metodami instancji klasy# Rozszerzanie modułów łączy ich metody z metodami klasyclassOsobaincludePrzykladowyModulendclassKsiazkaextendPrzykladowyModulendOsoba.cokolwiek# => NoMethodError: undefined method `cokolwiek' for Osoba:ClassOsoba.new.cokolwiek# => 'cokolwiek'Ksiazka.cokolwiek# => 'cokolwiek'Ksiazka.new.cokolwiek# => NoMethodError: undefined method `cokolwiek'# Gdy włączamy lub rozszerzamy muduły, wykonywane są tzw. wywołania zwrotnemodulePrzykladowyModuldefself.included(baza)baza.extend(MotodyKlasowe)baza.send(:include,MetodyInstancji)endmoduleMotodyKlasowedefcos'cos'endendmoduleMetodyInstancjidefxyz'xyz'endendendclassCokolwiekincludePrzykladowyModulendCokolwiek.cos# => 'cos'Cokolwiek.xyz# => NoMethodError: undefined method `xyz'Cokolwiek.new.cos# => NoMethodError: undefined method `cos'Cokolwiek.new.xyz# => 'qux'