Ruby on Rails rzutem na taśmę wywołało burzę skrajnie różnych emocji. Owszem, jest to nowy, rewolucyjny sposób szybkiego budowania aplikacji internetowych. Lecz także i tej technologii trzeba się nauczyć niejako od nowa. Aby należycie zaprezentować możliwości RoR, postanowiliśmy wpierw przyjrzeć się Ruby, obiektowemu językowi programowania, który pomimo tego, że powstał dobre kilkanaście lat temu, jest do dziś dobrze znany tylko wąskiej grupie programistów.
Autorem Ruby jest Yukihiro Matsumoto, programista i zwolennik wolnego oprogramowania.
Stworzył on Ruby, gdyż jak to określa w referencyjnej książce (oficjalnympodręczniku Ruby) – był zniechęcony sposobem, w jaki wiele innych języków zmusza programistę do wielokrotnego wykonywania tych samych czynności. Ruby jest językiem skryptowym, co oznacza, że do wykonania programu konieczne jest zinterpretowanie jego kodu przez parser.
Ruby jest też językiem zorientowanym obiektowo, którego wyróżnikiem jest brak konieczności deklarowania zmiennych, a co za tym idzie – ich typów. Zmienne zostają automatycznie zadeklarowane w momencie pierwszego przypisania. Mechanizm dynamicznego doboru typu zmiennej pozwala nie tylko wyręczyć programistę, lecz także zapobiec błędom przy kompilacji.
Choć ten mechanizm ma wielu zwolenników wśród programistów C++ czy Javy, to zachowanie języka niekoniecznie musi działać na jego niekorzyść.
Językiem o podobnych cechach jest np. PHP, który dzięki łatwości implementacji zdobył przewagę
w obsłudze aplikacji internetowych. Jednak PHP ma wiele wad i nie narzuca programiście żadnego stylu programowania, czego efektem jest chaotyczny
kod pisany przez amatorów programowania.
Ruby zostało wypuszczone na rynek w 1995 roku, ale przez wiele lat nie było zauważone. Dopiero za sprawą Ruby on Rails, oczy wielu programistów skierowały się na ten interesujący niewątpliwie język. Ruby on Rails jest frameworkiem
napisanym w języku Ruby. Celem RoR (skrót od Ruby on Rails) jest stworzenie przyjaznego środowiska dla programistów aplikacji internetowych.
Wykorzystanie do tego celu Ruby okazało się bardzo trafne, o czym świadczy bardzo duże zainteresowanie developerów tą nową technologią. Mimo że RoR powstało w 2003 roku, prawdziwego rozpędu nabrało dopiero niespełna dwa lata temu.
Ruby on Rails oparto o architekturę MVC (Model, Widok, Kontroler), która wydaje się naturalnym paradygmatem realizacji aplikacji internetowych.
Słusznie zauważono, że w aplikacjach sieciowych rozdzielenie widoku i kontrolera byłoby okupione większym skomplikowaniem aplikacji i tworzeniem dodatkowego, niepotrzebnego kodu (a przecież Ruby chce tego uniknąć). Rails podoba się, bo napisanie prostych aplikacji jest proste. Doskonałym kontrprzykładem jest tu język Java, który jest co prawda doskonały w rozbudowanych aplikacjach, lecz kompletnie nie nadaje się choćby do prostych implementacji, takich jak wyświetlenie na ekranie tekstu „Witaj świecie” – do osiągnięcia tego celu potrzebuje bowiem kilkunastu linii kodu.
Z Ruby on Rails jest jednak jeden problem. Aby mógł on działać na serwerze WWW, tak jak PHP czy Perl (CGI), konieczne jest zainstalowanie odpowiedniego oprogramowania. Jeżeli spojrzeć na niewielką liczbę firm hostingowych obsługujących
tę platformę, okazuje się, że nie jest to wcale takie łatwe. Co więcej, żadna licząca się na rynku firma hostingowa nie zdecydowała się na taki krok. Dlatego póki rosnąca popularność frameworka nie sprawi, że instalacja RoR na serwerach zacznie opłacać się z ekonomicznego punktu widzenia, raczej nie zaleje nas fala serwisów napisanych w RoR. Można więc powiedzieć, że koło się zamyka, bo racjonalnie myślący programiści nie używają technologii, której nie mogą wdrożyć i testować na żywym organizmie, jakim jest internet.
A jednak popularność RoR na świecie wydaje się być zaskakująco duża. Lecz i o hosting z obsługą
RoR jest za oceanem znacznie łatwiej.
Najważniejsze cechy Ruby jako języka to:
- Ruby łączy cechy języka czysto obiektowego (jak Smalltalk) z przystępnością języków skryptowych (Perl). Programy napisane w Ruby są kompaktowe, łatwe w interpretacji. Wiele kwestii można rozwiązać, wykorzystując zaledwie kilka linii kodu, bez zbytniego komplikowania składni.
- Składnia i semantyka języka jest prosta i intuicyjna,
a kod wynikowy wolny od niepotrzebnych znaków. - Programista koncentruje się wyłącznie na pisaniu rozwiązań, bez zbędnego zagłębiania się w potrzeby kompilatora.
- Ruby posiada otwarte źródło i nie stawia ograniczeń co do platformy, na której może być wykonywane.
W tym artykule przyjrzymy się językowi Ruby, jego składni oraz możliwościom. W następnym, mając już opanowane podstawy Ruby, zgłębimy tajniki Ruby on Rails.
Instalacja Ruby
W przeciwieństwie do platformy Rails, interpreter
języka Ruby można znaleźć na wielu komercyjnych
serwerach liczących się firm hostingowych (za pośrednictwem powłoki lub jako skrypt CGI). Ruby jest językiem skryptowym, który może być wykorzystywany do rozmaitych celów. Dzięki Ruby można np. stworzyć interfejs graficzny(Tcl).
Nie istnieją jakiekolwiek ograniczenia co do platformy, na której uruchamiamy skrypty Ruby. Te same skrypty będą działać zarówno pod kontrolą systemów linuksowych, jak i Windowsów (z wyłączeniem kilku funkcjonalności specyficznych dla danej platformy).
Witryna napisana w Ruby nie będzie tym samym, co witryna stworzona w oparciu o Ruby on Rails. Nie jest problemem wykorzystanie Ruby np. do obsługi formularzy czy obsługi parametrów przekazywanych poprzez adres URL. Mechanizm taki może być oparty o interfejs CGI (ang. Common Gateway Interface).
Niestety, napisana w ten sposób aplikacja nie będzie żadną rewolucją i nie przysporzy Ruby wielu fanów. Stworzona przy użyciu CGI aplikacja internetowa będzie przypominać w zasadzie to, co znają webmasterzy posługujący się Perl/CGI czy też osoby pracujące pod kontrolą Pythona. Oczywiście różnicą będzie tutaj język implementacji.
Interactive Ruby
Standardowa kompilacja Ruby zawiera terminal o nazwie IRB. Pozwala on na testowanie kodu w uproszczonej formie. Interactive Ruby to nic innego jak wiersz poleceń, do którego możemy wprowadzać wszystkie elementy języka Ruby.
IRB dostępny jest po wprowadzeniu w wierszu poleceń:
irb -simple-prompt
Dodatkowy parametr wyświetla krótszy ciąg znaków poprzedzający znak zachęty.
Ruby jako skrypt
Domyślnym rozszerzeniem skryptów ruby jest .rb.
By uruchomić skrypt ruby w systemie Windows, wystarczy dwukrotnie kliknąć na dowolny plik o rozszerzeniu .rb. Instalator Ruby domyślnie wywołuje
skrypt przepuszczając go przez interpreter Ruby. Niepożądanym efektem z pewnością będzie szybkie uruchomienie i zamknięcie się okna.
Problem ten można rozwiązać, umieszczając na końcu skryptu prośbę o wprowadzenie przez użytkownika danych:
dowolnazmienna = gets
Podobnego tricku używa się podczas programowania
w C, czy C++.
Z poziomu powłoki systemu wprowadzamy polecenie ruby, a następnie podajemy nazwę skryptu:
ruby mojskrypt.rb
Jeżeli Ruby ma służyć do realizacji usług internetowych – np. wyświetlać stronę WWW, konieczne jest umieszczenie skryptu w katalogu cgi-bin, obsługiwanego przez serwer WWW (najczęściej Apache). Żeby skrypt działał i nie zwracał „wewnętrznego błędu serwera”, konieczne jest dodanie na początku skryptu kodu inwokacji, wskazującego na lokalizację interpretera Ruby:
#!/usr/bin/ruby
Oczywiście lokalizacja może się różnić w zależności od systemu. Metoda uruchomienia tego skryptu polega na wykorzystaniu mechanizmu CGI (ang. Common Gateway Inteface). Ruby posiada bibliotekę do obsługi CGI, domyślnie zainstalowaną
w standardowej kompilacji.
Jeżeli umieszczony na serwerze skrypt nie działa, warto sprawdzić, czy zgadzają się prawa dostępu chmod. Do testów można przyznać skryptowi
maksymalne prawa:
chmod 777 nazwaskryptu.rb
Dokumentacja
Ruby zawiera aplikację pełniącą funkcję instrukcji obsługi. W celu uzyskania informacji na temat wybranej klasy, należy uruchomić program ri, wykonując polecenie:
ri Klasa
By wyświetlić wszystkie opcje RI, wprowadź:
ri -h
Dokumentację znajdziesz też na stronie internetowej pod adresem: http://www.ruby-doc.org/.
Podstawy składni
Na początku należy jeszcze raz podkreślić, że w Ruby wszystko jest obiektem. Dotyczy to nawet ciągu znaków (ang. string).
Wszystkie testowane w tym artykule przykłady będą wykonywane w IRB. Praca w terminalu ma tę zaletę, że nie tylko natychmiastowo zwraca wynik, lecz domyślnie zwraca wszystkie dane, które zostały zmienione w wyniku operacji.
Rozpocznijmy od tradycyjnego wyświetlenia na ekranie napisu Witaj świecie. Symbolem strzałki oznaczono wynik działania polecenia:
print \"Witaj Swiecie\"
-> Witaj Swiecie => Nil
W wyniku działania powyższego kodu na ekranie pojawia się napis „Witaj świecie”. Ponieważ
funkcja print zwraca domyślnie wartość null (w Ruby null to nil), IRB wyświetla ją na ekranie. Gdybyśmy ten sam kod uruchomili jako skrypt z rozszerzeniem .rb, program zwróciłby wyłącznie napis. IRB jest środowiskiem do testowania kodu, stąd wyświetla dodatkowe informacje.
Operacje arytmetyczne w Ruby są bardzo zbliżone do innych języków. Ponieważ Ruby jest językiem o dynamicznie przydzielanych typach, konieczne jest przedstawienie anomalii z tym związanych:
a = 5
-> 5
b = 2*a
-> 10
b/2
-> 5
Operacje mnożenia i dzielenia liczb całkowitych o wyniku całkowitym są oczywiste. Warto zwrócić uwagę, że w Ruby nie stosuje się znaku końca wiersza – np. średnika z C/C++/PHP.
b % 2
-> 0
a = a ** 2
-> 25
a **= 2
-> 625
Znak procentów to modulo 2 z liczby przypisanej do zmiennej b. Znak podwójnej gwiazdki to potęgowanie. Możemy stosować operatory **=, +=, które przypisują do zmiennej stojącej po lewej stronie wynik operacji. W te sposób 25 do potęgi drugiej daje 625. W Ruby nie ma inkrementacji
typu zmienna++.
Aby inkrementować zmienną, stosujemy konstrukcje:
a = 1
-> 1
a += 1 // a++ - taka konstrukcja nie istnieje
-> 2
Duże liczby możemy zapisać w tradycyjny sposób (ciągiem liczb) lub rozdzielając je znakiem podkreślenia (dla człowieka jest to zdecydowanie bardziej przystępna forma zapisu):
c = 25_200_100
-> 25200100
Wykonanie operacji dzielenia liczb całkowitych zawsze daje liczbę całkowitą:
1/2
-> 0
Podobnie jak w C, by uzyskać liczbę zmiennoprzecinkową, musimy użyć liczby zmiennoprzecinkowej podczas wykonywania operacji arytmetycznej:
1.0/2
-> 0.5
Trudno określić, czy jest to wada, czy zaleta języka.
Ciągi znaków
Ciągiem znaków (ang. string) jest domyślnie każda zmienna, której wartość umieszczono w znakach cudzysłowu:
a = \"he \"
-> \"he \"
a*3
-> \"he he he \"
Jak widać, stringi można mnożyć, czego efektem jest zwielokrotnienie ich zawartości. Spróbujmy
dodać ciąg znaków do liczby:
b = 2
a+b / błąd
Niezgodność typów nie pozwala na taką operację.
W Ruby znak sumy arytmetycznej i konkatencji jest jeden – „+”. By zsumować ciąg znaków, należy użyć metody .to_s. Powiedzieliśmy już, że w Ruby wszystko jest obiektem – nawet ciąg znaków. Dlatego dowolna zmienna posiada zestaw metod, które można na niej wykorzystać:
a+b.to_s
-> \"he 2\"
(a+b.to_s).length
-> 4
(a+b.to_s).upcase
-> \"HE 2\"
Metoda length zwraca liczbę znaków w ciągu znaków, natomiast upcase zamienia ciąg znaków na duże litery. Ruby ma setki wbudowanych metod (uwaga – nie można ich nazwać funkcjami, gdyż pracujemy na obiekcie!).
Za obsługę ciągów znaków odpowiada klasa string. Jej szczegółowy opis można znaleźć pod adresem: http://www.ruby-doc.org/core/classes/String.html.
Tablice
W ruby tablica to zbiór odwołań do obiektów. Każdy element tablicy może być dowolnego typu:
tablica = [1, 3.14, \"Hello World\"]
-> [1, 3.14, \"Hello World\"]
Odwoływanie się do konkretnych elementów tablicy wygląda standardowo – wystarczy do nawiasu kwadratowego podać żądany indeks:
print tablica[1]
-> 3.14
Aby otrzymać ostatni element tablicy, jako indeks podajemy -1:
print tablica[-1]
-> \"Hello World\"
Tablicę można również stworzyć poprzez utworzenie
nowej instancji klasy Array:
tablica = Array.new
tablica[0] = 1
tablica[1] = 3.14
tablica[2] = \"Hello World\"
Tablicę można dowolnie „kroić”. Utwórzmy więc przykładową tablicę:
a = [0,4,3,1,2,5]
Wykonanie operacji nazwa_tablicy[zakres_start..zakres_stop] powoduje przycięcie jej do określonych rozmiarów:
a[0..3]
-> [0, 4, 3, 1]
Instrukcje warunkowe
W Ruby znajdziemy trzy podstawowe instrukcje warunkowe: if, unless oraz switch. Najprostszy if (jeżeli) dla zadanego warunku wykonuje określony blok kodu:
a = 5
-> 5
if a > 0
a = 10
end
-> 10
Blok warunkowy lub pętla musi zostać zakończona słowem kluczowym end. Wykonanie złożonej z dwóch porównań instrukcji warunkowej prezentuje się następująco:
if a != 0 && b == 0
a = 10
elsif a == 0
a = 5
else
a = 7
end
Operatory logiczne używane przez Ruby są zgodne ze znanymi z innych języków programowania.
Jeżeli warunek stojący przy IF jest nieprawdziwy, wykonywane są instrukcje elsif wyrażenia. Jeżeli żadny warunek nie zostanie spełniony, wówczas wykonywany jest fragment kodu else.
Ciekawą konstrukcją warunkową jest unless (ang. dopóki). Zatem dopóki wyrażenie -> to:
unless cena > 100
przesylka = 20
end
W Ruby nie zabrakło operatora trójargumentowego,
uwielbianego przez programistów:
cena > 100 ? przesylka = 0 : przesylka = 20
Jego konstrukcja jest identyczna jak w C/C++/PHP: warunek ? co_gdy_prawda : co_gdy_fałsz.
Ruby nie narzuca sposobu praktycznego użycia funkcji warunkowych. Oto nieco szokujący
przykład:
print \"tak\" if a > 0
Funkcji warunkowych możemy więc używać także wewnątrz funkcji, z odwróconą kolejnością – najpierw instrukcja, a dopiero potem warunek.
Switch czy też zwrotnica to konstrukcja przeznaczona
do obsługi wielu możliwych przypadków:
cenaPrzesylki = case Total
when 0..200: 20
when 201..300: 16
when 301..500: 6
else 0
end
W przykładzie zmienna cenaPrzesylki przyjmuje wartość zależną od zmiennej Total. Wyobraźmy sobie zatem sklep internetowy. Cena przesyłki zależy od wartości zamówienia. I tak zamówienia np. od 0-200 zł wiążą się z kosztem przesyłki 20 zł, itd.
Pętle
Wyróżniamy trzy dostępne w ruby pętle: while, do i for, choć sposobów wykonania iteracji jest więcej.
Pętla while wykonuje obrót zawsze, gdy spełniony
jest warunek:
while warunek
print zmienna
end
Pętli while używamy, gdy nie znamy rozmiaru wczytywanego pliku. Przykład odczytu zawartości linia po linii opiera się o klasę File (do zarządzania plikami) oraz metody open (otwórz plik), gets (pobierz linię):
file=File.open(\"plik\")
while line = file.gets
print line
end
Konstrukcja \”do\” jest bardzo ciekawym wynalazkiem takie spostrzeżenia mają programiści innych języków:
3.times do print \"he \" end
-> he he he
W ruby wszystko zdaje się proste. Zamiast zastanawiać się, ile razy pętla obróci, piszemy, by obróciła się 3.razy (3.times) i to tyle. Wyświetlenie napisu „he” nastąpi trzykrotnie.
Bardziej rozbudowana instrukcja „do” może iterować od pewnej wartości w górę (upto) lub w dół (down to). Aby pętla obróciła od 10 do 0 co jeden, korzystamy z konstrukcji:
10.downto(0) do |x| print x, \" \" end
-> 10 9 8 7 6 5 4 3 2 1 0
Często zachodzi potrzeba interacji po tablicy. Stwórzmy jedną i skorzystajmy z metody each wykonanej na obiekcie tablica:
tablica = [0,4,3,1,2,5]
tablica.each { |x| print x, \" \" }
-> 0 4 3 1 2 5
Dziwna konstrukcja |x|, która się powtarza od ostatnich dwóch przykładów, to zmienna, której wartość ustalana jest dynamicznie w danym bloku przez interpreter. W powyższym przykładzie x jest wartością dla kolejnych indeksów tablicy. Użycie konstrukcji zaopatrzonej w klamry jest konieczne, gdyż wszystkie bezpośrednie operacje iteracyjne na metodach w Ruby formułowane są właśnie w taki sposób.
Typowa pętla „for” opiera się o konstrukcję for zmienna in obiekt:
for x in tablica
print x*x, \" \"
end
-> 0 16 9 1 4 25
Korzystając z tablicy z poprzedniego przykładu, interujemy po wszystkich jej wartościach, wyświetlając ich potęgę (moglibyśmy użyć też x**2, ale x*x jest szybsze).
Jeżeli potrzebujemy iterować od 1 do 10, wystarczy wprowadzić zakres:
for x in 1..10
print x, \" \"
end
-> 1 2 3 4 5 6 7 8 9 10
Po literach też można iterować, a czemu by nie:
for x in \"a\"..\"d\"
print x, \" \"
end
-> a b c d
We wszystkich pętlach możemy używać rozmaitych struktur kontrolnych. W Ruby wyróżniamy: next (przejdź do kolejnego obrotu pętli), redo (wykonaj interację jeszcze raz przy tym samym warunku, bez jego przeliczania), break (przerwij pętlę), retry (przewija pętle do samego początku, wracając do wartości początkowych iteracji).
Poniższy przykład jest całkowicie pozbawiony sensu, ma jedynie za zadanie przedstawić sposób implementacji struktur kontrolnych:
for x in 1..100
next if a > 0
redo if c == 0
break if koniec
retry if error > 0
end
Powróćmy jeszcze raz do tworzenia tablic. Możemy bardzo szybko stworzyć nową, posiłkując się metodą to_a (to też swojego rodzaju pętla):
(1..10).to_a
-> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
(\"a\"..\"f\").to_a
-> [\"a\", \"b\", \"c\", \"d\", \"e\", \"f\"]
Bardziej złożone wartości dla dynamicznie generowanej tablicy można otrzymać, wykorzystując
klasę Array:
a = Array.new(10) { |x| x*x*x }
-> [0, 1, 8, 27, 64, 125, 216, 343, 512, 729]
W ten sposób udało się utworzyć tablicę, której każdy następny element jest kolejną liczbą całkowitą podniesioną do trzeciej potęgi.
Jeżeli mielibyśmy za zadanie usunąć wszystkie elementy tablicy, które są większe od 100, moglibyśmy użyć następującej konstrukcji:
a.delete_if { |x| x>= 100 }
-> [0, 1, 8, 27, 64]
Dobrnęliśmy do zagadnień związanych z obiektowością
w Ruby. Z pewnością pod tym względem jest to język warty uwagi, gdyż oferuje niespotykane
nigdzie indziej właściwości (np. miksiny).
Najprostsza definicja funkcji w Ruby prezentuje się tak:
def polekwadratu(a)
a*a
end
Ruby automatycznie zwraca ostatnio obliczone wyrażenie, stąd nie jest wymagane używanie słowa kluczowego return do zwrócenia wyniku. Do utworzonej w ten sposób funkcji odwołujemy się tak:
print polekwadratu(2)
Funkcja zwróci liczbę 4. Użycie dwóch zmiennych
jest analogiczne. Argumenty przekazujemy, korzystając z separatora – przecinka, niekoniecznie zamykając argumenty definicji funkcji w klamry:
def p a,b
a*b
end
print p(2,3)
Stwórzmy teraz klasę zawierającą funkcję kwadrat, liczącą pole:
class Pole
def kwadrat(a)
a*a
end
end
Nazwy klas w Ruby muszą zaczynać się od dużej litery, podczas gdy nazwy funkcji – zawsze od małej. Do funkcji kwadrat odwołujemy się następująco (tworząc obiekt klasy):
a = Kwadrat.new
print a.kwadrat(2)
-> 4
Dotychczas posługiwaliśmy się wyłącznie zmiennymi lokalnymi. Nazwy takich zmiennych mogą zaczynać się wyłącznie od małej litery (zmienna1, zMienna2).
Dla stałych zarezerwowane są wszystkie nazwy, które rozpoczynają się od dużej litery:
Zmienna = 1
-> 1
Zmienna = 2 // błąd - nie można zmienić wartości stałej
Wszystkie zmienne globalne rozpoczynają się znakiem $, np. $zmienna. Zmienna globalna to taka, która widoczna jest zarówno w głównym fragmencie programu, jak i np. wewnątrz metody.
Zmienne wewnątrz instancji poprzedzamy znakiem @, np. @zmienna, natomiast zmienne klasy dodając jeszcze jeden znak mały – @@, np. @@zmienna. Podsumowanie standardów nazewnictwa zawarto w tabeli 1.
Tabela 1.
Zmienne lokalne | zmienna | zMienna |
Zmienne globalne | $Zmienna | $zmienna |
Zmienne w obrębie instancji | @zmienna | @mojaZmienna |
Zmienne klasy | @@zmienna | @mojaZmienna |
Stałe | STALA | Stala |
Nazwy klas | Klasa | MojaKlasa |
Nazwy metod | metoda | mojaMetoda |
Ruby obsługuje konstruktory klasy. Konstruktorem
nazywamy metodę klasy, która w momencie
tworzenia nowego obiektu jest domyślnie wykonywana:
class Pole
def initialize (wysokosc,szerokosc)
@a = wysokosc
@b = szerokosc
end
def prostokat()
@a*@b
end
end
By utworzyć obiekt klasy Pole, konieczne jest przekazanie do konstruktora zmiennych szerokosc i wysokość:
pole = Pole.new(4,7)
print pole.prostokat()
-> 28
Ponieważ Ruby wymusza, aby klasy rozpoczynały
się od dużej litery, a zmienne od małej, nie tworzy się bałagan. Do metody prostokąt możemy się odwołać bez używania nawiasów klamrowych (metoda w końcu nie przyjmuje argumentów):
print pole.prostokat
-> 28
Przypomnieliśmy sobie właśnie, że nie mamy metody do liczenia pola kwadratu. Żaden problem.
Do naszego tymczasowego kodu dodajemy nową metodę:
class Pole
def kwadrat()
if @a == @b
@a*@a
else
\"To nie jest kwadrat\"
end
end
end
Ponieważ kwadrat musi mieć boki równej długości, konieczne jest stworzenie warunku i ewentualne wyświetlenie błędu. Wykonajmy teraz obie metody:
print pole.prostokat
-> 28
print pole.kwadrat
-> \"To nie jest kwadrat\"
Najszybszą metodą obliczenia pola prostokąta jest wykonanie poniższego kodu:
print Pole.new(3,5).prostokat
-> 15
Ruby pozwala zatem na tworzenie bardzo treściwego kodu. W dodatku żadna klasa w Ruby nie jest zamknięta. W każdym momencie możemy dodać do niej nowe metody, nawet po utworzeniu instancji danej klasy. Warto zauważyć, że możemy dodawać nowe metody także do klas wbudowanych:
class String
def u
upcase
End
end
W ten sposób stworzyliśmy skrót do metody upcase, która konwertuje wszystkie litery alfabetu na duże:
\"To nie jest kwadrat\".u
-> \"TO NIE JEST KWADRAT\"
Ruby nie obsługuje wielokrotnego dziedziczenia.
Dziedziczyć można wyłącznie po jednej klasie:
class Obwod < Kwadrat
def initialize(a)
@a = a
end
def obwod
@a*4
end
end
Każda klasa może posiadać dowolną ilość właściwości, które definiujemy podwójnym znakiem małpy - @@:
class Kursy
@@euro = 4.1
def przelicz(kwota)
@kwota*@@euro
end
end
Moduły i miksiny
Zadaniem modułów jest grupowanie klas, metod i stałych, czyli tworzenie swojego rodzaju paczek kodu do wielokrotnego wykorzystania. Choć moduły to nazwa dobra, do wielu może lepiej przemówić określenie biblioteka, gdyż moduły pełnią właśnie taką funkcję. Moduły dostarczają osobnej przestrzeni nazw, dzięki czemu programista nie musi zwracać uwagi na konflikty nazewnictwa.
Moduły w praktyce umieszcza się w osobnych plikach. Taki plik z modułem zakończony jest tradycyjnym rozszerzeniem .rb. By dołączyć moduł do aktualnego skryptu, używamy funkcji:
require \'nazwaplikumodułu\' // nazwa bez rozszerzenia .rb
W tym momencie kompilator wie, gdzie znajduje się dany moduł i nic poza tym. Aby modułu można było używać, trzeba go dołączyć do każdej klasy z osobna. Służy do tego konstrukcja include:
include nazwamodulu
Zobaczmy przykład (moduł może znajdować się w tym samym pliku, co cały skrypt - nic nie stoi na przeszkodzie):
module Pole
def kwadrat(a)
a*a
end
end
Pole.kwadrat(2) // błąd
include Pole
kwadrat(2)
-> 4
Pole.kwadrat(2)
-> 4
W momencie wykonania polecenia include Pole funkcje umieszczone w module przechodzą do ogólnej przestrzeni nazw.
Z uwagi na brak wielokrotnego dziedziczenia, w Ruby wprowadzono tzw. miksiny (ang. mixins). Miksiny umożliwiają zrealizowanie mechanizmu wielokrotnego dziedziczenia, pozwalając na włączenie do (wmiksowanie) istniejącej klasy dodatkowych
metod. Zobaczmy to na przykładzie:
module Modul
def funkcja
print \"to ja\"
end
end
class Klasa
def funkcja2
print \"a to ja\"
end
end
klasa = Klasa.new
klasa.funkcja2
-> \"a to ja\"
klasa.funkcja
-> \"to ja\"
Podsumowanie
W artykule udało się przedstawić najbardziej podstawowe zagadnienia języka Ruby. Programistom
zainteresowanym rozwijaniem swoich umiejętności w tym zakresie można polecić referencyjną pozycję książkową pt. „Programming Ruby: The Pragmatic Programmers. Second Edition”.
Ten ponad tysiącstronicowy podręcznik szczegółowo omawia zarówno sam język, jak i standardowe biblioteki dołączane do Ruby. Łącznie przekłada się to na opis prawie 1000 podstawowych metod. Książka została w Polsce wydana nakładem wydawnictwa Helion, pt. „Programowanie w języku Ruby”.
Przydatne linki
1. Ruby on Rails
Oficjalna strona
http://www.rubyonrails.org/
2. Ruby on Rails
Polskie tłumaczenie oficjalnej strony
http://www.rubyonrails.org/pl/
3. Źródło wiedzy o Ruby
4. Pomoc i dokumentacja
do języka Rubyh ttp://www.ruby-doc.org/
5. Oficjalny podręcznik
Pierwsze wydanie podręcznika Ruby http://www.rubycentral.com/book/