background image

Wydawnictwo Helion
ul. Koœciuszki 1c
44-100 Gliwice
tel. 032 230 98 63

e-mail: helion@helion.pl

Ruby. Wprowadzenie 
 
 
 
 

Autor: Michael Fitzgerald
T³umaczenie: Adam Jarczyk
ISBN: 978-83-246-1229-1
Tytu³ orygina³u: 

Learning Ruby

Format: B5, stron: 240

Poznaj praktyczne zastosowania jêzyka Ruby 

• 

Podstawowe konstrukcje jêzyka i zasady programowania obiektowego 

• 

Operacje na tekstach, liczbach i plikach 

• 

Framework Ruby on Rails 

Ruby – obiektowy jêzyk programowania, wzglêdnie nowy, bo opracowany na pocz¹tku 
lat 90. ubieg³ego wieku, zdobywa coraz wiêksz¹ popularnoœæ. W zakresie tworzenia 
aplikacji internetowych staje siê powa¿n¹ konkurencj¹ dla Perla, PHP i Javy. 
Jest niezwykle elastyczny, posiada prost¹ sk³adniê i spore mo¿liwoœci, a tworzony 
w nim kod jest bardzo zwarty. Za pomoc¹ Ruby mo¿na pisaæ zarówno proste skrypty 
administracyjne, jak i rozbudowane aplikacje internetowe. W budowaniu tych ostatnich 
niezwykle pomocny jest framework Ruby on Rails, dziêki któremu proces tworzenia 
aplikacji przebiega b³yskawicznie. 

Ksi¹¿ka 

„

Ruby. Wprowadzenie

”

 to podrêcznik dla tych, którzy chc¹ poznaæ mo¿liwoœci 

jêzyka bez koniecznoœci studiowania zawi³ych opisów teoretycznych. Przedstawia Ruby 
na praktycznych przyk³adach, pokazuj¹c jego zastosowania w typowych zadaniach, 
z jakimi spotyka siê na co dzieñ programista aplikacji sieciowych. Czytaj¹c tê ksi¹¿kê, 
poznasz elementy jêzyka Ruby i nauczysz siê programowaæ obiektowo. Dowiesz siê, 
w jaki sposób przetwarzaæ dane liczbowe, teksty i tablice, pliki i katalogi 
oraz dokumenty XML. Przeczytasz tak¿e o œrodowisku Ruby on Rails. 

• 

Instalacja jêzyka Ruby w ró¿nych systemach operacyjnych 

• 

Instrukcje i operatory 

• 

Przetwarzanie tekstów i operacje matematyczne 

• 

Operacje na systemie plików 

• 

Korzystanie z plików XML 

• 

Programowanie obiektowe 

• 

Wprowadzenie do Ruby on Raili 

WejdŸ do œwiata Ruby, a pokochasz jego mo¿liwoœci!  

background image

Spis tre

ļci

_

5

Spis tre

ļci

Przedmowa  ................................................................................................................................9

1.  Podstawy j

ýzyka Ruby .................................................................................................. 13

Witaj, Matz! 

14

Interactive Ruby 

22

Zasoby 

24

Instalowanie jözyka Ruby 

25

Permission Denied 

30

Kojarzenie typów plików w systemie Windows 

30

Pytania sprawdzajñce 

32

2.  Krótka wycieczka po j

ýzyku Ruby  ...............................................................................33

Ruby jest jözykiem obiektowym 

33

Säowa zastrzeĔone jözyka Ruby 

35

Komentarze 

37

Zmienne 

37

ãaþcuchy 

40

Liczby i operatory 

42

Instrukcje warunkowe 

43

Tablice i tablice asocjacyjne 

43

Metody 

44

Bloki 

48

Symbole 

52

Obsäuga wyjñtków 

52

Dokumentacja jözyka Ruby 

53

Pytania sprawdzajñce 

53

3.  Instrukcje warunkowe ..................................................................................................55

Instrukcja if 

55

Instrukcja case 

58

background image

6

_

Spis tre

ļci

Pötla while 

59

Metoda loop 

62

Pötla for 

63

Wykonanie przed lub po programie 

65

Pytania sprawdzajñce 

66

4. 

Ĥaħcuchy ........................................................................................................................67

Tworzenie äaþcuchów 

67

Konkatenacja äaþcuchów 

70

Dostöp do äaþcuchów 

70

Porównywanie äaþcuchów 

72

Manipulowanie äaþcuchami 

73

Konwersja wielkoĈci liter 

76

Odstöpy itp. 

78

Inkrementowanie äaþcuchów 

79

Konwersja äaþcuchów 

80

WyraĔenia regularne 

81

Ruby 1.9 i nastöpne 

84

Pytania sprawdzajñce 

84

5.  Matematyka  ..................................................................................................................85

Hierarchia klas i moduäy wbudowane 

86

Konwersja liczb 

86

Podstawowe operacje matematyczne 

87

Zakresy 

90

Zapytania o liczby 

91

Inne metody matematyczne 

93

Funkcje matematyczne 

93

Liczby wymierne 

94

Liczby pierwsze 

96

Pytania sprawdzajñce 

97

6.  Tablice ............................................................................................................................99

Tworzenie tablic 

100

Dostöp do elementów 

102

Konkatenacja 

104

Operacje na zbiorach 

104

Elementy unikatowe 

105

Na stos 

105

Porównywanie tablic 

105

Modyfikacja elementów 

106

Usuwanie elementów 

107

background image

Spis tre

ļci

_

7

Tablice i bloki 

108

Sortowanie i w tyä zwrot 

108

Tablice wielowymiarowe 

109

Ruby 1.9 i nastöpne 

109

Inne metody klasy Array 

109

Pytania sprawdzajñce 

110

7.  Tablice asocjacyjne  ...................................................................................................... 111

Tworzenie tablicy asocjacyjnej 

111

Dostöp do tablicy asocjacyjnej 

112

Iteracja na tablicy asocjacyjnej 

113

Modyfikacje tablicy asocjacyjnej 

114

Konwersja tablicy asocjacyjnej na innñ klasö 

116

Ruby 1.9 i nastöpne 

117

Inne metody klasy Hash 

117

Pytania sprawdzajñce 

117

8.  Praca z plikami  .............................................................................................................119

Katalogi 

119

Tworzenie nowego pliku 

121

Otwieranie istniejñcego pliku 

121

Usuwanie i zmiana nazw plików 

124

Zapytania o pliki 

124

Zmiana trybu i wäaĈciciela pliku 

125

Klasa IO 

126

Pytania sprawdzajñce 

127

9.  Klasy ............................................................................................................................. 129

Definiowanie klasy 

130

Zmienne instancji 

131

Akcesory 

132

Zmienne klasy 

134

Metody klasy 

134

Dziedziczenie 

136

Moduäy 

137

Metody public, private i protected 

139

Pytania sprawdzajñce 

140

10.  Dalsza zabawa z j

ýzykiem Ruby ................................................................................ 141

Formatowanie wyjĈcia za pomocñ metody sprintf 

141

Przetwarzanie dokumentów XML 

144

Data i czas 

148

background image

8

_

Spis tre

ļci

Refleksja 

152

Tk 

155

Metaprogramowanie 

157

RubyGems 

158

Obsäuga wyjñtków 

162

Tworzenie dokumentacji za pomocñ RDoc 

163

Embedded Ruby 

170

Pytania sprawdzajñce 

172

11.  Krótki przewodnik po Ruby on Rails  ......................................................................... 173

Skñd pochodzi Rails? 

173

Dlaczego Rails? 

174

Co inni zdziaäali z pomocñ Rails? 

178

Hosting dla Rails 

179

Instalowanie Rails 

179

Nauka Rails 

183

Krótki samouczek 

184

Pytania sprawdzajñce 

188

A  Leksykon j

ýzyka Ruby ..................................................................................................191

B  Odpowiedzi na pytania sprawdzaj

éce ......................................................................209

S

ĥowniczek  ............................................................................................................................. 215

Skorowidz  ..............................................................................................................................223

background image

33

ROZDZIA

Ĥ 2.

Krótka wycieczka po j

ýzyku Ruby

Niniejszy rozdziaä przedstawia, bez zbytniego zagäöbiania siö w szczegóäy, podstawy jözyka
Ruby: klasy i moduäy, w tym klasö 

Object

 i moduä 

Kernel

, säowa zastrzeĔone (inaczej säowa

kluczowe), komentarze, zmienne, metody i tak dalej. WiökszoĈè z tych zagadnieþ bödzie omó-
wiona bardziej szczegóäowo w innych rozdziaäach. Niektóre tematy zasäugujñ na caäe rozdziaäy,
inne tylko na podrozdziaäy (zawarte w rozdziale 10.). Za kaĔdym razem powiem, gdzie znajdujñ
siö dodatkowe informacje na dany temat. W niniejszym rozdziale zostaäy zawarte najbardziej
szczegóäowe opisy metod i bloków.

Ruby jest j

ýzykiem obiektowym

Matz, twórca jözyka Ruby, juĔ w szkole Ĉredniej marzyä o stworzeniu wäasnego jözyka progra-
mowania. Chciaä utworzyè jözyk skryptowy, który zarazem byäby zorientowany obiektowo.

Ruby wykracza poza proste pisanie skryptów, mimo Ĕe programy w nim mogñ sprawiaè wra-

Ĕenie zwykäych skryptów powäoki. Nie jest to zaledwie jözyk proceduralny, choè moĔe byè
jako taki wykorzystany.

Jözyk  Ruby  zawiera  klasy.  Klasy  zawierajñ  dane  —  w  postaci  staäych  i  zmiennych  —  oraz
metody, które sñ krótkimi fragmentami kodu, pomagajñcymi wykonywaè operacje na danych.
Klasy mogñ dziedziczyè po sobie informacje, lecz tylko z jednej klasy na raz. Pozwala to ponow-
nie wykorzystywaè kod — co oznacza mniej czasu zmarnowanego na naprawianie kodu i usu-
wanie z niego bäödów — oraz mieszaè ze sobñ kod poprzez dziedziczenie.

Klasa jest czymĈ w rodzaju „schematu”; za pomocñ metody 

new

 schemat ten moĔna przypisaè

do  zmiennej  lub  wykonaè  jego  kopiö,  która  przez  to  staje  siö  obiektem.  W  jözyku  Ruby
obiektem jest prawie wszystko; w istocie to, co Ruby moĔe skojarzyè z nazwñ zmiennej, jest
zawsze obiektem.

O klasach moĔna powiedzieè o wiele wiöcej; Czytelnik znajdzie mnóstwo dodatkowych infor-
macji na ich temat w rozdziale 9. Na razie wystarczñ nam podstawy. Listing 2.1 przedstawia
program  w  Ruby  (friendly.rb)  zawierajñcy  dwie  klasy: 

Hello

  i 

Goodbye

.  Program  ten  jest

zawarty w archiwum kodu Ruby towarzyszñcym niniejszej ksiñĔce (dostöpnym pod adresem
ftp://ftp.helion.pl/przyklady/rubwpr.zip). Proponujö uruchomiè program w powäoce lub wierszu
poleceþ w katalogu, do którego zostaäo rozpakowane archiwum. W przypadkach gdy przykäad
kodu nie znajduje siö w pliku, moĔna wpisaè go w irb. Zachöcam Czytelnika do wypróbowy-
wania kodu tak czösto, jak to moĔliwe.

background image

34

_

Rozdzia

ĥ 2. Krótka wycieczka po jýzyku Ruby

Listing 2.1. friendly.rb

class Hello
  def howdy
    greeting = "Witaj, Matz!"
    puts greeting
  end
end

class Goodbye < Hello
  def solong
    farewell = "Do widzenia, Matz."
    puts farewell
  end
end

friendly = Goodbye.new
friendly.howdy
friendly.solong

Po uruchomieniu tego programu zostanñ wyĈwietlone komunikaty:

friendly.rb
Witaj, Matz!
Do widzenia, Matz.

DoĈwiadczeni programiĈci zapewne bez podpowiedzi zorientujñ siö, jak dziaäa kod z listingu
2.1. Czytelnicy tacy mogñ przejĈè do nastöpnego punktu (lub prosto do rozdziaäu 9., aby poznaè
caäñ kwestiö klas w jözyku Ruby).

Klasa 

Hello

  definiuje  metodö 

howdy

.  Metoda  ta  wyĈwietla  zawartoĈè  äaþcucha  zawartego

w zmiennej 

greeting

 (

Witaj, Matz!

). Klasa 

Goodbye

 podobnie zawiera definicjö metody 

solong

,

która wyĈwietla äaþcuch przypisany do zmiennej 

farewell

 (

Do widzenia, Matz.

). Klasa 

Good-

bye

 dziedziczy teĔ zawartoĈè klasy 

Hello

; do tego säuĔy tutaj operator 

<

. Oznacza to, Ĕe w klasie

Goodbye

 nie trzeba ponownie definiowaè metody 

howdy

. Zostaäa po prostu odziedziczona.

friendly

 jest obiektem, egzemplarzem klasy 

Goodbye

. Metoda 

new

 wywoäywana z 

Goodbye

pochodzi z klasy 

Object

 i tworzy nowy egzemplarz 

friendly

 (wiöcej na temat klasy 

Object

w nastöpnym punkcie). MogliĈmy uĔyè obiektu 

friendly

 do wywoäania zarówno metody 

howdy

,

jak i 

solong

, poniewaĔ obie sñ dostöpne w tym obiekcie. Metoda 

solong

 zostaäa zdefiniowana

w klasie 

Goodbye

, a metoda 

howdy

 odziedziczona z 

Hello

.

To wszystko, co na razie chciaäem powiedzieè na ten temat. Informacje o klasach znajdñ siö
w róĔnych miejscach nastöpnych rozdziaäów. W rozdziale 9. omówiö klasy bardziej dokäadnie.

Klasa Object i modu

ĥ Kernel

Object

 jest podstawowñ klasñ jözyka Ruby, nadrzödnñ wzglödem wszystkich pozostaäych klas

tego jözyka, i zawsze w sposób magiczny pojawia siö, gdy uruchamiamy program w Ruby. Nie
musimy niczego robiè, by w innych klasach uzyskaè dostöp do jej funkcjonalnoĈci. Jest zawsze
dla nas dostöpna.

Klasa 

Object

 zawiera bogatñ funkcjonalnoĈè w postaci metod i staäych, którñ wszystkie pro-

gramy w Ruby dziedziczñ automatycznie. W niniejszym punkcie przedstawiö czöĈè tej funk-
cjonalnoĈci.

background image

S

ĥowa zastrzeŜone jýzyka Ruby

_

35

Klasa — analogia do wiadra

Czytelnicy, którzy nie wiedzñ, na czym polega obiektowoĈè jözyka programowania, mogñ
posäuĔyè siö  prostñ  analogiñ.  WyobraĒmy  sobie  klasö  —  podstawowy  skäadnik  jözyka  obiekto-
wego — jako wiadro. W wiadrze znajduje siö woda i jeden lub wiöcej czerpaków. Woda to od-
powiednik wäaĈciwoĈci (danych lub informacji) mieszczñcych siö w klasie, a czerpaki sñ narzö-
dziami (metodami) do manipulowania wodñ (danymi). Podstawowym narzödziem uĔywanym
z klasami jest metoda — porcja kodu, której moĔemy nadaè nazwö i wielokrotnie jñ wy-
korzystywaè. Metoda przypomina czerpak, który zanurzamy w wiadrze i wybieramy wodö
lub  nalewamy  jñ.  MoĔemy  wiadro  wykorzystaè  ponownie,  wylaè  starñ  wodö,  nalaè  ĈwieĔej,
a nawet wäoĔyè jedno wiadro do drugiego. Tak, bez zagäöbiania siö w Ĕargon techniczny, wy-
glñdajñ  podstawy  programowania  obiektowego.  Sporñ  porcjñ  Ĕargonu  poczöstuje  Czytelnika
rozdziaä 9.

Object

 udostöpnia metody takie, jak 

==

 i 

eql?

class

inspect

object_id

 oraz 

to_s

. Zostanñ

one dokäadniej opisane w nastöpnych rozdziaäach. Wiöcej informacji o wszystkich metodach
klasy 

Object

 moĔna znaleĒè pod adresem http://www.ruby-doc.org/core/classes/Object.html.

Kernel

 jest moduäem jözyka Ruby. Moduä przypomina klasö, lecz nie moĔna utworzyè jego

egzemplarza, tak jak w przypadku klasy. JeĈli jednak doäñczymy moduä do klasy lub wmie-
szamy go w niñ, w obröbie tej klasy uzyskamy dostöp do wszystkich jego metod. MoĔemy uĔy-
waè metod z doäñczonego moduäu bez potrzeby ich implementowania.

Klasa 

Object

  zawiera  moduä 

Kernel

.  PoniewaĔ  zawsze  mamy  w  programach  Ruby  dostöp

do klasy 

Object

, oznacza to, Ĕe zawsze uzyskujemy dostöp równieĔ do wszystkich metod

moduäu 

Kernel

. Kilka z tych metod widzieliĈmy juĔ w dziaäaniu, na przykäad 

print

 i 

puts

.

Do  najczöĈciej  uĔywanych  metod  moduäu 

Kernel

  naleĔñ 

eval

exit

gets

loop

require

,

sleep

 i 

sprintf

. W dalszych rozdziaäach skorzystamy z wiökszoĈci tych metod.

Nazwy metody moduäu 

Kernel

 nie trzeba poprzedzaè nazwñ obiektu lub odbiornika. Wystarczy

wywoäaè metodö w dowolnym miejscu programu. Wiöcej informacji o module 

Kernel

 moĔna

znaleĒè pod adresem http://www.ruby-doc.org/core/classes/Kernel.html.

S

ĥowa zastrzeŜone jýzyka Ruby

KaĔdy jözyk programowania ma wäasnñ listö säów zastrzeĔonych (inaczej säów kluczowych),
które zarezerwowane sñ na potrzeby dziaäania jözyka. Säowami takimi sñ instrukcje w progra-
mach, a jak bez instrukcji mielibyĈmy poinformowaè komputer, co ma robiè?

Tabela 2.1 przedstawia listö säów zastrzeĔonych jözyka Ruby wraz z krótkim opisem przezna-
czenia kaĔdego z nich.

background image

36

_

Rozdzia

ĥ 2. Krótka wycieczka po jýzyku Ruby

Tabela 2.1. S

äowa zastrzeĔone jözyka Ruby

S

ĥowo zastrzeŜone

Opis

BEGIN

Kod zamkni

ýty w nawiasy klamrowe 

{}

 wykonywany przed samym programem.

END

Kod zamkni

ýty w nawiasy klamrowe 

{}

 wykonywany po zako

ħczeniu dziaĥania programu.

alias

Tworzy alias dla istniej

écej metody, operatora lub zmiennej globalnej.

and

Operator logiczny; taki sam jak 

&&

, lecz o ni

Ŝszym priorytecie (analogicznie jak 

or

).

begin

Zaczyna blok kodu (grup

ý instrukcji) zakoħczony sĥowem kluczowym 

end

.

break

Wychodzi z p

ýtli 

while

 lub 

until

 albo z metody wewn

étrz bloku.

case

Porównuje wyra

Ŝenie z warunkiem 

when

; instrukcja zako

ħczona przez 

end

 (zobacz 

when

).

class

Definiuje klas

ý; definicja jest koħczona przez 

end

.

def

Definiuje metod

ý; definicja jest koħczona przez 

end

.

defined?

Operator specjalny sprawdzaj

écy, czy zmienna, metoda, metoda klasy bazowej lub blok istnieje.

do

Zaczyna blok i wykonuje jego zawarto

ļë, koħczy siý na 

end

.

else

Wykonuje nast

ýpujécy po nim kod, jeļli poprzedni warunek (

if

elsif

unless

 albo 

when

)

nie jest prawdziwy.

elsif

Wykonuje nast

ýpujécy po nim kod, jeļli poprzedni warunek (

if

 albo 

elsif

) nie jest prawdziwy.

end

Ko

ħczy blok kodu rozpoczýty przez 

begin

def

do

if

 itp.

ensure

Zawsze wykonuje kod po zako

ħczeniu bloku; naleŜy uŜyë po ostatnim 

rescue

.

false

Warto

ļë logiczna (boolowska) „faĥsz”; egzemplarz klasy 

FalseClass

 (zobacz 

true

).

for

Rozpoczyna p

ýtlý 

for

; u

Ŝywane ze sĥowem kluczowym 

in

.

if

Wykonuje blok kodu, je

ļli warunek jest prawdziwy. Blok jest zakoħczony przez 

end

 (porównaj

unless

until

).

in

U

Ŝywane w pýtli 

for

 (zobacz 

for

).

module

Definiuje modu

ĥ; definicja jest koħczona przez 

end

.

next

Wykonuje skok przed instrukcj

é warunkowé pýtli (porównaj z 

redo

).

nil

Warto

ļë pusta, niezainicjowana zmienna, niepoprawna, lecz nie to samo co zero. Obiekt z klasy 

NilClass

.

not

Operator logiczny, taki sam jak 

!

.

or

Operator logiczny; taki sam jak 

||

, lecz o ni

Ŝszym priorytecie (analogicznie jak 

and

).

redo

Skok po instrukcji warunkowej p

ýtli (porównaj z 

next

).

rescue

Ewaluuje wyra

Ŝenie po pojawieniu siý wyjétku; uŜywane przed 

ensure

.

retry

Na zewn

étrz 

rescue

 powtarza wywo

ĥanie metody; wewnétrz 

rescue

 wykonuje skok na pocz

étek

bloku (

begin

).

return

Zwraca warto

ļë z metody lub bloku. MoŜna pominéë.

self

Obiekt bie

Ŝécy (wywoĥane przez metodý).

super

Wywo

ĥuje metodý o tej samej nazwie w superklasie (klasie nadrzýdnej wzglýdem bieŜécej).

then

Kontynuacja instrukcji 

if

unless

 lub 

when

. Mo

Ŝna pominéë.

true

Warto

ļë logiczna (boolowska) „prawda”; egzemplarz klasy 

TrueClass

 (zobacz 

false

).

undef

Usuwa definicj

ý metody w bieŜécej klasie.

unless

Wykonuje blok kodu, je

ļli instrukcja warunkowa zwróci 

false

 (porównaj z 

if

until

).

until

Wykonuje blok kodu, gdy instrukcja warunkowa zwróci 

false

 (porównaj z 

if

unless

).

when

Rozpoczyna klauzul

ý (jedné lub wiýcej) po 

case

.

background image

Zmienne

_

37

Tabela 2.1. S

äowa zastrzeĔone jözyka Ruby — ciñg dalszy

S

ĥowo zastrzeŜone

Opis

while

Wykonuje blok kodu, je

ļli instrukcja warunkowa zwróci 

true

.

yield

Wykonuje blok przekazany do metody.

__FILE__

Nazwa bie

Ŝécego pliku Śródĥowego.

__LINE__

Numer bie

Ŝécego wiersza w bieŜécym pliku Śródĥowym.

Komentarze

Komentarz ukrywa wiersze skryptu przed interpreterem jözyka Ruby, tak Ĕe zostajñ odrzucone
(zignorowane). UmoĔliwia to programistom (czyli nam) wstawianie do programów wszelkiego
rodzaju informacji, które pozwolñ innym uĔytkownikom zorientowaè siö, o co chodzi. W Ruby
stosowane sñ dwa podstawowe style komentarzy. Symbol 

#

 (hash) moĔe znajdowaè siö na

poczñtku wiersza:

# Jestem tylko komentarzem. Nie zwracaj na mnie uwagi.

albo po instrukcji lub wyraĔeniu, w tym samym wierszu:

name = "Floydee Wallup" # te

Ī mi nazwisko…

Komentarz moĔe zajmowaè kilka wierszy pod rzñd:

# To jest komentarz.
# To te

Ī jest komentarz.

# I to te

Ī jest komentarz.

# Nie b

ĊdĊ siĊ powtarzaü.

Oto inna forma: blokowy komentarz, który ukrywa przed interpreterem kilka wierszy pomiödzy
säowami kluczowymi 

=begin

 i 

=end

:

=begin
To jest komentarz.
To te

Ī jest komentarz.

I to te

Ī jest komentarz.

Nie b

ĊdĊ siĊ powtarzaü.

=end

W ten sposób moĔna zakomentowaè jeden wiersz lub dowolnñ ich liczbö.

Zmienne

Zmienna jest identyfikatorem (nazwñ), któremu moĔna przypisaè wartoĈè. Podczas dziaäania
programu wartoĈè ma lub bödzie mieè okreĈlony typ. W poniĔszym przykäadzie zmiennej

x

 zostaje za pomocñ znaku równoĈci przypisana wartoĈè 100:

x = 100

Teraz zmienna lokalna 

x

 zawiera wartoĈè 100. Ale jakiego typu? Dla mnie wyglñda na liczbö

caäkowitñ, a dla Czytelnika? A jak zinterpretuje jñ Ruby?

Wiele  wspóäczesnych  jözyków  programowania,  na  przykäad  C++  i  Java,  stosuje  statycznñ
kontrolö typu. Oznacza to, Ĕe zmiennej w chwili jej deklarowania przypisuje siö okreĈlony typ,
a poniewaĔ w jözykach tych kontrola typów jest Ĉcisäa, zmienna zachowuje typ, dopóki nie
zostanie jej przypisany inny (o ile jest to w ogóle moĔliwe).

background image

38

_

Rozdzia

ĥ 2. Krótka wycieczka po jýzyku Ruby

Na przykäad, w jözyku Java zmienne deklaruje siö z podaniem typu (

int

) po lewej stronie:

int months = 12;
int year = 2007;

W jözyku Ruby nie ma deklaracji typów. WartoĈci sñ po prostu przypisywane do zmiennych:

months = 12
year = 2007

JeĈli ktoĈ sobie tego Ĕyczy, moĔe zakoþczyè wiersz Ĉrednikiem, lecz znak koþca wiersza w zupeä-
noĈci wystarczy.

WartoĈci w zmiennych 

x

months

 i 

year

 sñ ewidentnie liczbami caäkowitymi (integer), lecz nie

musimy wskazywaè typu, poniewaĔ Ruby robi to za nas automatycznie. Nosi to nazwö dyna-
micznej kontroli typów
 lub potocznie duck typing.

Mechanizm dziaäa tak: jeĈli zauwaĔymy ptaka wodnego, który chodzi jak kaczka (ang. duck),
kwacze jak kaczka, fruwa jak kaczka i päywa jak kaczka, to, na honor, zapewne mamy do czy-
nienia z kaczkñ. Ruby podobnie sprawdza wartoĈè przypisanñ do zmiennej — jeĈli ta wartoĈè
chodzi, kwacze, fruwa i päywa jak liczba caäkowita, Ruby przyjmuje, Ĕe moĔe graè rolö liczby
caäkowitej.

Zobaczmy, czy Ruby moĔe uznaè wartoĈè 

x

 za liczbö caäkowitñ, za pomocñ metody 

kind_of?

(jest to metoda z klasy 

Object

).

x.kind_of? Integer # => true

AleĔ oczywiĈcie, wartoĈè zmiennej 

x

 zachowuje siö jak liczba caäkowita! W istocie jest egzem-

plarzem klasy 

Fixnum

, która dziedziczy klasö 

Integer

.

x.class # => Fixnum

Zmieþmy teraz wartoĈè 

x

 z caäkowitej na zmiennoprzecinkowñ za pomocñ metody 

to_f

 z klasy

Fixnum

 (jest teĔ dziedziczona przez inne klasy):

x.to_f # => 100.0

Jak wspomniaäem w rozdziale 1., zapis 

=>

 w przykäadach kodu pojawia siö tu zawsze

po znaku komentarza (

#

). Tekst nastöpujñcy po 

=>

 jest wynikiem, którego moĔemy siö

spodziewaè z wiersza lub bloku kodu albo caäego programu.

Zmienne lokalne

Nazwaäem wczeĈniej 

x

 zmiennñ lokalnñ. Co to znaczy? Oznacza to, Ĕe zmienna ma zasiög

(kontekst) lokalny. Na przykäad, gdy zmienna lokalna zostaje zdefiniowana wewnñtrz metody
lub pötli, ma zasiög w obröbie tej metody lub pötli. Na zewnñtrz nie jest do niczego przydatna.

Nazwy zmiennych lokalnych muszñ zaczynaè siö od maäej litery lub znaku podkreĈlenia (

_

), na

przykäad 

alpha

 lub 

_beta

. Zmienne lokalne w jözyku Ruby moĔemy teĔ poznaè po tym, Ĕe ich

nazwy nie sñ poprzedzane znakami specjalnymi, z wyjñtkiem podkreĈlenia. Istniejñ teĔ inne typy
zmiennych, z äatwoĈciñ identyfikowane przez pierwszy znak nazwy. NaleĔñ do nich zmienne
globalne, zmienne instancji i zmienne klasy.

background image

Zmienne

_

39

Zmienne instancji

Zmienna instancji jest zmiennñ, do której odwoäujemy siö przez wystñpienie (egzemplarz) kla-
sy, wiöc naleĔy do okreĈlonego obiektu. Nazwy takich zmiennych poprzedza znak 

@

:

@hello = hello

Dostöp do zmiennej instancji spoza jej wäasnej klasy jest moĔliwy tylko przez metody akcesora.
Wiöcej informacji o tych metodach zawiera rozdziaä 9.

Zmienne klasy

Zmienna klasy jest wspóäuĔytkowana przez wszystkie wystñpienia klasy. Dla danej klasy
istnieje tylko jedna kopia zmiennej klasy. W jözyku Ruby nazwy zmiennych tego typu poprze-
dzajñ dwa znaki 

@

 (

@@

). Przed uĔyciem zmiennej klasy naleĔy jñ zainicjalizowaè (przypisaè

wartoĈè):

@@times = 0

Zmienne klasy zobaczymy w akcji w rozdziale 9.

Zmienne globalne

Zmienne globalne sñ dostöpne globalnie w caäym programie, w kaĔdej jego strukturze. Ich
zasiögiem jest caäy program. Nazwö zmiennej globalnej poprzedza symbol dolara (

$

):

$amount = "0.00"

Trudno jest Ĉledziè wykorzystanie zmiennych globalnych. Lepiej wyjdziemy na projektowaniu
kodu tak, by wykorzystywaä zmienne klasy i staäe. Matz twierdzi, cytujö, Ĕe zmienne globalne
„sñ paskudne, wiöc nie korzystaj z nich”. Sñdzö, Ĕe to dobra rada (lepiej uĔywaè metod singleton;
zobacz rozdziaä 9.).

Sta

ĥe

Staäa  mieĈci  niezmiennñ  wartoĈè  przez  caäy  czas  dziaäania  programu  w  Ruby.  Staäe  sñ  zmien-
nymi, których nazwy zaczynajñ siö od duĔej litery lub sñ zapisane samymi duĔymi literami.
Oto definicja staäej o nazwie 

Matz

:

Matz = "Yukishiro Matsumoto"
puts Matz # => Yukishiro Matsumoto

JeĈli staäa zostaäa zdefiniowana wewnñtrz klasy lub moduäu, bödzie dostöpna w tej klasie lub
module; jeĈli zdefiniujemy jñ na zewnñtrz klas i moduäów, bödzie dostöpna globalnie. W prze-
ciwieþstwie do innych jözyków w Ruby staäe sñ zmienialne (mutable) — inaczej mówiñc, moĔna
modyfikowaè ich wartoĈci.

Przypisanie równoleg

ĥe

Podoba mi siö w jözyku Ruby moĔliwoĈè przypisywania równolegäego (jak w jözykach Perl,
Python i JavaScript 1.7). Co to takiego? Jest to sposób przypisywania w jednej instrukcji kilku
zmiennych, w jednym wierszu. Czösto przypisujemy po jednej zmiennej na wiersz:

background image

40

_

Rozdzia

ĥ 2. Krótka wycieczka po jýzyku Ruby

x = 100
y = 200
z = 500

W przypisaniu równolegäym moĔemy uzyskaè ten sam efekt, oddzielajñc od siebie nazwy zmien-
nych, a nastöpnie wartoĈci przecinkami:

x, y, z = 100, 200, 500

MoĔliwe jest nawet przypisanie wartoĈci róĔnych typów, na przykäad äaþcucha, wartoĈci zmien-
noprzecinkowej i caäkowitej:

a, b, c = "cash", 1.99, 100

Przypisanie równolegäe jest wygodne. To bardzo typowe dla jözyka Ruby.

Ĥaħcuchy

ãaþcuch jest ciñgiem liter, cyfr i innych znaków. W jözyku Ruby istnieje kilka metod tworzenia

äaþcuchów, lecz najprostszñ chyba jest zapisanie tekstu w cudzysäowach (mogñ byè pojedyncze
lub podwójne). WeĒmy cytat z ksiñĔki Walden Henry Davida Thoreau:

thoreau = "Dobro

ð jest jedynî inwestycjî, która nigdy nie zawodzi."

1

Metody klasy 

String

 pozwalajñ uzyskaè dostöp do äaþcucha 

thoreau

 i manipulowaè nim.

MoĔemy, na przykäad, pobraè fragment äaþcucha za pomocñ metody 

[]

, uĔywajñc zakresu.

WeĒmy znaki z pozycji od 33. do 37.:

thoreau[33..37] # => "nigdy"

Albo, zaczynajñc od koþca äaþcucha i uĔywajñc liczb ujemnych, weĒmy znaki od przedostatniego
do ósmego od koþca:

thoreau[-8..-2] # => "zawodzi"

MoĔemy przejĈè iteracyjnie przez wszystkie znaki äaþcucha, uĔywajñc bloku kodu, który pobierze
kolejno kaĔdy bajt (8 kolejnych bitów) äaþcucha i wygeneruje z niego znak za pomocñ metody

chr

, oddzielajñc od siebie kolejne znaki ukoĈnikami:

thoreau.each_byte do |c|
  print.chr, "/"
end
# => D/o/b/r/o/

ü/ /j/e/s/t/ /j/e/d/y/n/ą/ /i/n/w/e/s/t/y/c/j/ą/,/ /k/t/ó/r/a/ /n/i/g/d/y/ /n/i/e/ /z/a/w/o/d/z/i/./

Niniejsza wskazówka przeznaczona jest dla czytelników, którzy chcñ w programach
uĔywaè nie tylko znaków ASCII; w przeciwnym razie moĔe byè nadmiarem informacji.
Muszö przyznaè, Ĕe zaäoĔenie, iĔ znak jest równowaĔny bajtowi, jest doĈè staroĈwieckie.
W szerszym kontekĈcie (w Unicode) znak moĔe byè reprezentowany przez wiöcej niĔ
jeden bajt. Na przykäad, w kodowaniu UTF-8 kaĔdy znak jest reprezentowany przez
od jednego do czterech bajtów. Ruby domyĈlnie stosuje kodowanie znaków ASCII,
lecz  moĔemy  to  zmieniè,  ustawiajñc  (w  okolicach  poczñtku  programu)  w  zmiennej

$KCODE

 wartoĈè 

u

 (dla UTF-8), 

e

 (dla EUC), 

s

 (dla SJIS), 

a

 (ASCII) lub 

n

 (

NONE

).

                                                       

1

Täumaczenie wäasne — przyp. täum.

background image

Ĥaħcuchy

_

41

Tak przy okazji, metoda 

chr

 konwertuje kod znaku (wygenerowany przez 

each_byte

)  na

faktyczny  znak.  Powinienem  teĔ  wspomnieè  o  metodzie  odwrotnej  —  operatorze 

?

,  który

zwraca kod podanego znaku. Zademonstrujö to w irb:

irb(main):001.0> ?I
=> 73
irb(main):002.0> ?f
=> 102
irb(main):003.0> ?\  # nie wida

ü znaku, ale tu jest spacja

=> 32
irb(main):004.0> ?m
=> 109
irb(main):005.0> ?a
=> 97
irb(main):006.0> ?n
=> 110

Nie bödö siö tu zbytnio zagäöbiaè w szczegóäy; wiöcej informacji o äaþcuchach zawiera rozdziaä 4.

Wyra

Ŝenia regularne

WyraĔenie  regularne  jest  specjalnym  ciñgiem  znaków,  który  dopasowuje  äaþcuch  lub  zbiór

äaþcuchów. WyraĔenia regularne (potocznie „regexp” od regular expression) czösto sñ wykorzy-
stywane do znajdowania pasujñcych äaþcuchów, aby póĒniej zrobiè coĈ z nimi lub wykonaè innñ
operacjö. SäuĔñ teĔ do pobierania äaþcuchów lub podäaþcuchów do wykorzystania gdzieĈ indziej.

WyraĔenia regularne skäadajñ siö z elementów (jednego lub wiöcej znaków), które instruujñ
silnik wyraĔeþ regularnych, jakie äaþcuchy ma wyszukiwaè. Na wzorzec wyraĔenia regular-
nego skäada siö kombinacja znaków specjalnych zawarta w ukoĈnikach (

//

). Oto kilka przy-

käadów:

^

Dopasowuje poczñtek wiersza.

$

Dopasowuje koniec wiersza.

\w

Dopasowuje säowo (dowolnñ kombinacjö liter i cyfr).

[...]

Dopasowuje dowolny znak w nawiasach prostokñtnych.

[^...]

Dopasowuje dowolny znak, który nie znajduje siö w nawiasach prostokñtnych.

*

Dopasowuje zero lub wiöcej wystñpieþ poprzedniego wyraĔenia regularnego.

+

Dopasowuje jedno lub wiöcej wystñpieþ poprzedniego wyraĔenia regularnego.

?

Dopasowuje zero lub jedno wystñpienie poprzedniego wyraĔenia regularnego.

background image

42

_

Rozdzia

ĥ 2. Krótka wycieczka po jýzyku Ruby

Oto przykäad wyraĔenia regularnego dopasowujñcego äaþcuchy za pomocñ metody 

scan

 z klasy

String

:

hamlet = "Znosi

ð pociski zawistnego losu"

hamlet.scan(/\w+/) # => ["Znosi

ü", "pociski", "zawistnego", "losu"]

Dopasowuje ono jedno lub wiöcej (

+

) säów (

\w

) i umieszcza znalezione wyniki w tablicy.

W szczegóäy wyraĔeþ regularnych zagäöbiö siö w rozdziale 4. Znajduje siö w nim tabela wszyst-
kich wzorców wyraĔeþ regularnych rozpoznawanych przez jözyk Ruby. Czytelników powaĔ-
nie zainteresowanych tym tematem odsyäam do ksiñĔki Jeffreya E. F. Friedla WyraĔenia regularne
(Helion, Gliwice 2001).

Liczby i operatory

W wiökszoĈci  obiektowych  jözyków programowania liczby sñ  uznawane  za  podstawowe  ele-
menty skäadowe nazywane prymitywami lub elementami pierwotnymi. Nie sñ wprost powiñ-
zane z Ĕadnñ klasñ; po prostu . W jözyku Ruby jest inaczej: nawet liczby sñ egzemplarzami klas.

Dodatnia liczba caäkowita 1001, na przykäad, jest egzemplarzem klasy 

Fixnum

, która jest klasñ

potomnñ klasy 

Integer

, a ta z kolei potomnñ klasy 

Numeric

. Zmiennoprzecinkowa liczba 1001.0

jest egzemplarzem klasy 

Float

, która równieĔ jest klasñ potomnñ 

Numeric

 (rysunek 5.1 przed-

stawia relacje pomiödzy tymi klasami).

Wraz z liczbami pojawiajñ siö operacje, które na tych liczbach moĔna wykonywaè. MoĔemy je,
na przykäad, dodawaè, dzieliè, mnoĔyè, podnosiè do potögi czy teĔ zwracaè resztö z dzielenia
(modulo).

Doskonaäym narzödziem do zaznajomienia siö z dziaäaniami matematycznymi w Ruby jest irb.
Wypróbujmy kilka z nich:

irb(main):001.0> 3 + 4 # dodawanie
=> 7
irb(main):002.0> 7 - 3 # odejmowanie
=> 4
irb(main):003.0> 3 * 4 # mno

Īenie

=> 12
irb(main):004.0> 12 / 4 # dzielenie
=> 3
irb(main):005.0> 12**2 # podniesienie do pot

Ċgi

=> 144
irb(main):006.0> 12 % 7 # modulo (reszta)
=> 5

Oto kilka operatorów przypisania jözyka Ruby w akcji:

irb(main):007.0> x = 12 # przypisanie
=> 12
irb(main):008.0> x += 1 # skrócony zapis przypisania z dodaniem
=> 13
irb(main):009.0> x -= 1 # skrócony zapis przypisania z odejmowaniem
=> 12
irb(main):010.0> x *= 2 # skrócony zapis przypisania z mno

Īeniem

=> 3
irb(main):011.0> x /= 2 # skrócony zapis przypisania z dzieleniem
=> 144

background image

Tablice i tablice asocjacyjne

_

43

Ruby zawiera równieĔ moduä 

Math

, udostöpniajñcy wszelkiego rodzaju funkcje matematyczne

(w postaci metod klas), takie jak pierwiastek kwadratowy, cosinus, tangens i tak dalej. Oto przy-
käad wywoäania metody klasy 

sqrt

 (pierwiastek kwadratowy) z moduäu 

Math

:

irb(main):012.0> Math.sqrt(16)
=> 4.0

Poza tym Ruby udostöpnia kilka specjalnych klas matematycznych, na przykäad 

Rational

 do

operacji na uäamkach. Wiöcej o liczbach i operatorach powiem w rozdziale 5. Tabela 5.1 przed-
stawia wszystkie operatory matematyczne w jözyku Ruby, äñcznie z pierwszeþstwem.

Instrukcje warunkowe

Podobnie jak kaĔdy inny jözyk programowania, Ruby zawiera instrukcje warunkowe, które
sprawdzajñ, czy okreĈlone stwierdzenie jest prawdziwe, czy faäszywe. Na podstawie odpowiedzi
jest nastöpnie wykonywany blok kodu. Oto prosty przykäad instrukcji 

if

, w której sprawdzamy,

czy zmienna ma wartoĈè zero:

value = 0

if value.zero? then
  puts "Zmienna value ma warto

Łð 0. DomyŁliĪeŁ siĂ tego?"

end

Metoda 

zero?

 zwraca 

true

, jeĈli wartoĈè zmiennej 

value

 wynosi zero. Tak teĔ jest w naszym

przypadku, wiöc nastöpna instrukcja zostaje wykonana (wraz z wszelkimi innymi instrukcjami
w bloku kodu pomiödzy 

if

 a 

end

). Zgodnie z konwencjñ jözyka Ruby kaĔda metoda, której

nazwa zakoþczona jest znakiem zapytania, zwraca wartoĈè boolowskñ — 

true

 albo 

false

.

Konwencja ta nie jest jednak wymuszana.

Do innych instrukcji warunkowych naleĔñ na przykäad znane nam 

case

 i 

while

 oraz mniej

znane, jak na przykäad 

until

 i 

unless

. Rozdziaä 3. opisuje wszystkie instrukcje warunkowe

dostöpne w jözyku Ruby.

Tablice i tablice asocjacyjne

Tablica jest uporzñdkowanñ sekwencjñ indeksowanych wartoĈci, w której indeks zaczyna siö od
zera. Stanowi jednñ z najczöĈciej spotykanych w informatyce struktur danych. W jözyku Ruby
tablica moĔe wyglñdaè tak:

pacific = ["Waszyngton", "Oregon", "Kalifornia"]

Nasza tablica ma nazwö 

pacific

. Zawiera trzy äaþcuchy — nazwy trzech stanów skäadajñcych

siö na zachodnie wybrzeĔe USA. ãaþcuchy te sñ elementami tablicy. Elementami tablicy mogñ
byè, oczywiĈcie, dane dowolnego typu z jözyka Ruby, nie jedynie äaþcuchy. PowyĔszy przy-
käad jest tylko jednym ze sposobów definiowania tablicy. Istnieje wiele innych, które poznamy
w rozdziale 6.

Aby uzyskaè dostöp do wybranego elementu, moĔna podaè w metodzie jego indeks. Na przy-
käad, by pobraè pierwszy element, którego indeks ma wartoĈè zero, moĔemy uĔyè metody 

[]

:

pacific[0] # => "Waszyngton"

background image

44

_

Rozdzia

ĥ 2. Krótka wycieczka po jýzyku Ruby

Wywoäanie  tej  metody  zwraca  wartoĈè  elementu  zerowego  —  äaþcuch 

Waszyngton

.  Wiöcej

informacji o tablicach w jözyku Ruby zawiera rozdziaä 6.

Tablica asocjacyjna (ang. hash), która przypisuje klucze do wartoĈci, równieĔ jest powszechnie
spotykanñ  strukturñ  danych.  W  przeciwieþstwie  do  zwykäej  tablicy,  w  której  indeksami  sñ
dodatnie liczby caäkowite, w tablicy asocjacyjnej moĔemy dowolnie wybraè klucze säuĔñce do
indeksowania. Wyglñda to tak:

pacific = { "WA" => "Waszyngton", "OR" => "Oregon", "CA" => "Kalifornia" }

Definicja tablicy asocjacyjnej jest zamkniöta w nawiasy klamrowe, natomiast zwykäej w nawiasy
prostokñtne. Poza tym kaĔda wartoĈè jest kojarzona z kluczem za pomocñ operatora 

=>

. Jednñ

z metod dostöpu do wartoĈci w tablicy asocjacyjnej jest podanie klucza. Aby pobraè z naszej
tablicy asocjacyjnej wartoĈè Oregon, moĔemy uĔyè metody 

[]

 z klasy 

Hash

:

pacific["OR"] # => "Oregon"

Podajñc klucz 

OR

, otrzymaliĈmy wartoĈè 

Oregon

. Klucze i wartoĈci mogñ byè dowolnego typu,

nie tylko äaþcuchami. Wiöcej informacji o tablicach asocjacyjnych zawiera rozdziaä 7.

Metody

Metody pozwalajñ zgrupowaè kod (instrukcje i wyraĔenia) w jednym miejscu, tak Ĕe moĔna go
póĒniej wygodnie wykorzystaè — jeĈli bödzie trzeba, wielokrotnie. MoĔemy definiowaè metody
wykonujñce najróĔniejsze czynnoĈci. W istocie wiökszoĈè operatorów matematycznych w jözyku
Ruby to metody.

PoniĔszy  opis  metod  jest  najbardziej  zwiözäy  ze  wszystkich  zawartych  w  niniejszej
ksiñĔce, wiöc Czytelnik byè moĔe zechce powracaè do niego w trakcie dalszej lektury.

Oto prosta definicja metody o nazwie 

hello

, stworzona z uĔyciem säów kluczowych 

def

 i 

end

:

def hello
   puts "Witaj, Matz!"
end

Ta metoda po prostu wyĈwietla tekst za pomocñ instrukcji 

puts

. Z drugiej strony, moĔemy usu-

nñè definicjö metody instrukcjñ 

undef

:

undef hello # usuwamy definicj

Ċ metody o nazwie hello

hello # spróbujemy teraz wywo

áaü metodĊ

NameError: undefined local variable or method 'hello' for main:Object
        from (irb):11
        from :0

MoĔemy teĔ definiowaè metody majñce argumenty, jak w poniĔszym przykäadzie:

def repeat ( word, times )
   puts word * times
end
repeat("Witaj! ", 3) # => Witaj! Witaj! Witaj!
repeat("

Şegnaj! ", 4) # => ĩegnaj! ĩegnaj! ĩegnaj! ĩegnaj!

background image

Metody

_

45

Nasza metoda 

repeat

 przyjmuje dwa argumenty: 

word

 i 

times

. Metodö majñcñ zdefiniowane

argumenty moĔemy wywoäywaè z nawiasami lub bez przed i po argumentach. MoĔna nawet
definiowaè argumenty metody bez nawiasów, lecz zwykle tak nie robiö.

Dziöki temu, Ĕe nawiasy nie sñ wymagane, moĔemy zapisywaè normalnie wyglñdajñce równania
matematyczne, korzystajñc z metod operatorów, na przykäad 

+

. KaĔdy z trzech poniĔszych wier-

szy jest w rzeczywistoĈci poprawnym wywoäaniem metody 

+

 klasy 

Fixnum

:

10 + 2 # => 12
10. + 2 # => 12
(10). + (2) # => 12

Warto

ļci zwracane

Metody zwrajñ wartoĈci. W innych jözykach programowania moĔemy jawnie otrzymaè zwracanñ
wartoĈè za pomocñ instrukcji 

return

. W jözyku Ruby zwracana jest ostatnia wartoĈè z metody,

z uĔyciem instrukcji 

return

 lub bez. Taki jest styl Ruby. Oto, jak moĔemy to sprawdziè w irb:

 

1. 

Na poczñtek zdefiniujemy metodö 

matz

 zawierajñcñ jedynie äaþcuch:

irb(main):001:0> def matz
irb(main):002:1> "Witaj, Matz!"
irb(main):003:1> end
=> nil

 

2. 

Po wywoäaniu metody 

matz

 zobaczymy jej wyjĈcie. Jest to dostöpne w irb, lecz nie bödzie

widoczne w przypadku uruchomienia normalnego programu z wiersza zachöty powäoki.
Aby wyĈwietliè wyjĈcie, w programie uĔylibyĈmy instrukcji 

puts

:

irb(main):004:0> matz
=> "Witaj, Matz!"
irb(main):005:0> puts matz
"Witaj, Matz!"
=> nil

 

3. 

Przypiszemy teraz metodö 

matz

 do zmiennej 

output

 i wyĈwietlimy tö zmiennñ:

irb(main):006:0> output = matz
=> "Witaj, Matz!"
irb(main):007:0> puts output
"Witaj, Matz!"
=> nil

 

4. 

JeĈli ktoĈ sobie tego zaĔyczy, moĔe uĔyè jawnie instrukcji 

return

. Zdefiniujemy ponownie

metodö 

matz

, tym razem dodajñc instrukcjö 

return

, i otrzymamy ten sam wynik:

irb(main):008:0> def matz
irb(main):009:1> return "Witaj, Matz!"
irb(main):010:1> end
=> nil
irb(main):011:0> matz
"Witaj, Matz!"
irb(main):012:0> puts matz
"Witaj, Matz!"
=> nil
irb(main):013:0> output = matz
=> "Witaj, Matz!"
irb(main):014:0> puts output
"Witaj, Matz!"
=> nil

background image

46

_

Rozdzia

ĥ 2. Krótka wycieczka po jýzyku Ruby

Konwencje nazewnicze metod

W jözyku Ruby stosowane sñ konwencje dotyczñce ostatniego znaku nazwy metody — konwen-
cje powszechnie stosowane, lecz nie wymuszane przez jözyk.

Gdy nazwa metody koþczy siö znakiem zapytania, na przykäad 

eql?

, metoda zwraca wartoĈè

boolowskñ — 

true

 albo 

false

. Na przykäad:

x = 1.0
y = 1.0
x.eql? y # => true

Gdy nazwa metody koþczy siö wykrzyknikiem, na przykäad 

delete!

, wskazuje to, Ĕe metoda

jest „niszczycielska” — inaczej mówiñc, wprowadza zmiany w samym obiekcie, a nie w jego
kopii. Modyfikuje sam obiekt. Proszö zwróciè uwagö na róĔnice wyników dziaäania metod

delete

 i 

delete!

 klasy 

String

:

der_mensch = "Matz!" # => "Matz!"
der_mensch.delete( "!" ) = "Matz!" # => "Matz"
puts der_mensch # => "Matz!"
der_mensch.delete!( "!" ) = "Matz!" # => "Matz"
puts der_mensch # => "Matz"

Gdy nazwa metody koþczy siö znakiem równoĈci, na przykäad 

family_name=

, oznacza to,

Ĕe metoda jest tzw. „setterem” — przeprowadza przypisanie lub ustawia zmiennñ, na przykäad
zmiennñ instancji w klasie:

class Name
   def family_name=( family )
      @family_name = family
   end
   def given_name=( given )
      @given_name = given
   end
end

n = Name.new
n.family_name= "Matsumoto" # => "Matsumoto"
n.given_name= "Yukihiro" # => "Yukihiro"
p n # => <Name:0x1d441c @family_name="Matsumoto", @given_name="Yukihiro">

W jözyku Ruby dostöpna jest bardziej praktyczna technika tworzenia metod getter/setter i akce-
sorów. Zostaäa ona opisana w rozdziale 9.

Argumenty domy

ļlne

Metoda 

repeat

, przedstawiona wczeĈniej, ma dwa argumenty. MoĔemy im przypisaè wartoĈci

domyĈlne, uĔywajñc znaku równoĈci, a po nim wartoĈci. JeĈli wywoäamy metodö bez argumen-
tów, automatycznie zostanñ uĔyte wartoĈci domyĈlne.

Zdefiniujmy 

repeat

 ponownie, uĔywajñc wartoĈci domyĈlnych: 

Witaj!

 dla 

word

 i 3 dla 

times

.

Wywoäamy teraz metodö najpierw bez argumentów, a nastöpnie z nimi.

def repeat ( word="Witaj! ", times=3 )
   puts word * times
end
repeat # => Witaj! Witaj! Witaj!
repeat("

Şegnaj! ", 5 ) # => ĩegnaj! ĩegnaj! ĩegnaj! ĩegnaj! ĩegnaj!

background image

Metody

_

47

Gdy metodö wywoäaliĈmy bez argumentów, zostaäy uĔyte wartoĈci domyĈlne; lecz gdy podali-

Ĉmy argumenty, wartoĈci domyĈlne zostaäy odrzucone i zastñpione wartoĈciami argumentów.

Zmienna liczba argumentów

Czasem nie wiemy, ile argumentów bödzie miaäa metoda. MoĔemy pozwoliè sobie na elastycz-
noĈè, poniewaĔ Ruby umoĔliwia przekazanie do metody zmiennej liczby argumentów, poprze-
dzajñc po prostu argument symbolem 

*

. Listing 2.2 przedstawia prosty program, który wyko-

rzystuje tö metodö.

Listing 2.2. num_args.rb

def num_args( *args )
  length = args.size
  label = length == 1 ? " argument" : " arguments"
  num = length.to_s + label + " ( " + args.inspect + " )"
  num
end

puts num_args

puts num_args(1)

puts num_args( 100, 2.5, "three" )

W tym programie operator trójkowy (

?:

) posäuĔyä do ustalenia, czy rzeczownik 

argument

powinien byè w liczbie pojedynczej, czy mnogiej (wiöcej o operatorach trójkowych w nastöpnym
rozdziale).

Gdy uĔyjemy tej skäadni dla róĔnej liczby argumentów, bödñ one zapisane w tablicy, co pozwoli
zilustrowaè metoda 

inspect

. Trzy wywoäania 

num_args

 sñ poprzedzone instrukcjñ 

puts

, aby

wysäaè wartoĈè zwracanñ metody na wyjĈcie standardowe:

0 arguments ( [] )
1 argument ( [1] )
3 arguments ( [100, 2.5, "three"] )

JednoczeĈnie z argumentami zmiennymi moĔemy uĔywaè zwykäych. Caäa sztuka polega na
tym, Ĕe zmienna lista argumentów (zaczynajñca siö od 

*

) zawsze powinna znajdowaè siö na koþ-

cu listy. Listing 2.3 ilustruje metodö, która ma dwa zwykäe argumenty i miejsce na dodatkowe.

Listing 2.3. two_plus.rb

def two_plus( one, two, *args )
  length = args.size
  label = length == 1 ? " variable argument" : " variable arguments"
  num = length.to_s + label + " (" + args.inspect + ")"
  num
end

puts two_plus( 1, 2 )

puts two_plus( 1000, 3.5, 14.3 )

puts two_plus( 100, 2.5, "three", 70, 14.3 )

Oto wyjĈcie programu (ilustruje tylko liczbö argumentów zmiennych, ignorujñc zwykäe):

background image

48

_

Rozdzia

ĥ 2. Krótka wycieczka po jýzyku Ruby

0 variable arguments ( [] )
1 variable argument ( [14.3] )
3 variable arguments ( [100, 2.5, "three"] )

Proszö spróbowaè wywoäaè 

two_plus

 bez Ĕadnych argumentów i sprawdziè, jaka bödzie odpo-

wiedĒ interpretera.

Aliasy metod

Jözyk Ruby zawiera säowo kluczowe 

alias

, które tworzy aliasy metod. Oznacza to, Ĕe tworzy-

my kopiö metody pod nowñ nazwñ, aczkolwiek wywoäanie obu metod bödzie kierowane do
tego  samego  obiektu.  Za  pomocñ 

alias

  (lub  metody 

alias_method

  klasy 

Module

)  moĔemy

uzyskaè dostöp do metod, które zostaäy nadpisane.

PoniĔszy przykäad z irb ilustruje, jak utworzyè alias metody 

greet

:

irb(main):001:0> def greet
irb(main):002:1>   puts "Cze

Ŀî, dziecinko!"

irb(main):003:1> end
=> nil
irb(main):004:0> alias baby greet # tworzymy alias greet pod nazw

ą baby

=> nil
irb(main):005:0> greet # wywo

áujemy metodĊ

Cze

Łð, dziecinko!

=> nil
irb(main):006:0> baby # wywo

áujemy alias

Cze

Łð, dziecinko!

=> nil
irb(main):007:0> greet.object_id # jaki jest identyfikator obiektu?
Cze

Łð, dziecinko!

=> 4
irb(main):008:0> baby.object_id # wskazuje ten sam obiekt
Cze

Łð, dziecinko!

=> 4

Bloki

Blok w jözyku Ruby jest czymĈ wiöcej niĔ fragmentem kodu (grupñ instrukcji). W okreĈlonym
kontekĈcie blok ma specjalne znaczenie. Jak zobaczymy, tego typu blok jest zawsze wywoäy-
wany w poäñczeniu z metodñ. W istocie okreĈlany jest terminem funkcja nienazwana.

W Ruby blok jest czösto (lecz nie zawsze) sposobem na pobranie wszystkich wartoĈci ze struk-
tury danych przez iteracjö na tej strukturze. Oznacza mniej wiöcej „daj mi wszystko, co tu masz,
po jednym na raz”. PokaĔö tu typowe zastosowanie bloku.

Przypomnijmy sobie tablicö 

pacific

:

pacific = ["Waszyngton", "Oregon", "Kalifornia"]

MoĔemy wywoäaè blok na tej tablicy, aby pobraè po jednym wszystkie elementy, posäugujñc siö
metodñ 

each

. Oto jeden z moĔliwych sposobów:

pacific.each do |element|
  puts element
end

background image

Bloki

_

49

Nazwa pomiödzy znakami 

|

 (

|element|

) moĔe byè dowolna. Blok wykorzystuje jñ jako zmiennñ

globalnñ do Ĉledzenia elementów tablicy, a póĒniej do zrobienia czegoĈ z kaĔdym elementem
po kolei. W naszym przykäadzie w bloku instrukcja 

puts

 wyĈwietla kolejno wszystkie elementy

tablicy:

Waszyngton
Oregon
Kalifornia

Instrukcje 

do..end

 moĔna zastñpiè parñ nawiasów klamrowych, co teĔ powszechnie jest stoso-

wane, by otrzymaè bardziej zwiözäy kod (tak przy okazji, nawiasy klamrowe majñ wyĔszy prio-
rytet niĔ 

do..end

):

pacific.each { |e| puts e }

Metoda 

each

 jest dostöpna w dziesiñtkach klas, miödzy innymi w 

Array

Hash

 i 

String

. Ale

proszö nie sugerowaè siö tym zanadto. Iteracja przez struktury danych nie jest jedynñ metodñ
wykorzystania bloków. Pozwolö sobie przytoczyè prosty przykäad wykorzystujñcy säowo klu-
czowe Ruby 

yield

.

Instrukcja yield

Na poczñtek zdefiniujmy króciutkñ metodö 

gimme

 zawierajñcñ jedynie instrukcjö 

yield

:

def gimme
   yield
end

Aby sprawdziè, co robi ta metoda, wywoäamy jñ bez niczego i zobaczymy efekt:

gimme
LocalJumpError: no block given
        from (irb):11:in `gimme'
        from (irb):13
        from :0

OtrzymaliĈmy  komunikat  o  bäödzie,  poniewaĔ  zadaniem  instrukcji 

yield

  jest  wykonanie

bloku kodu skojarzonego z metodñ. Tego nam brakowaäo w wywoäaniu 

gimme

. MoĔemy unik-

nñè takiego bäödu, posäugujñc siö metodñ 

block_given?

 z moduäu 

Kernel

. Zdefiniujmy 

gimme

,

dodajñc instrukcjö 

if

:

def gimme
   if block_given?
      yield
   else
      puts "Nie mam bloku!"
   end
end

if

  jest  instrukcjñ  warunkowñ.  JeĈli  z  wywoäaniem  metody  zostaä  podany  blok,  metoda

block_given?

 zwróci 

true

 i 

yield

 wykona blok; w przeciwnym razie zostanie wykonany kod

po 

else

.

Wypróbujmy metodö jeszcze raz, z blokiem i bez.

gimme { print "Dzie

Ĭ dobry wszystkim."} # => Dzie

Ĕ dobry wszystkim.

gimme # => Nie mam bloku!

background image

50

_

Rozdzia

ĥ 2. Krótka wycieczka po jýzyku Ruby

Gdy podajemy 

gimme

 blok, metoda wykonuje zawarty w nim kod, wyĈwietlajñc tekst Dzieþ

dobry wszystkim; jeĈli nie podamy bloku, 

gimme

 zwróci äaþcuch 

Nie mam bloku!

. Z ciekawoĈci

moĔemy zmieniè definicjö 

gimme

 tak, Ĕe bödzie zawieraè dwie instrukcje 

yield

, a nastöpnie

wywoäaè z blokiem. Wykona blok dwa razy.

def gimme
   if block_given?
      yield
      yield
   else
      puts "Nie mam bloku!"
   end
end

gimme { print "Dzie

Ĭ dobry."} # => Dzie

Ĕ dobry. DzieĔ dobry.

NaleĔy pamiötaè, Ĕe po wykonaniu instrukcji 

yield

 program wraca do nastöpnej instrukcji

bezpoĈrednio po 

yield

. Aby to zilustrowaè, zdefiniujmy 

gimme

 jeszcze raz.

def gimme
   if block_given?
      yield
   else
      puts "Oh-oh. Brak bloku."
   end
   puts "Ca

Ĩa przyjemnoĿî po mojej stronie."

end

gimme { print "Dzi

ĂkujĂ."} # => Dzi

ĊkujĊ. Caáa przyjemnoĞü po mojej stronie.

Jestem pewien, Ĕe te drobne przykäady kodu zademonstrowaäy, jak wszechstronnym narzödziem
sñ bloki. Mogö sobie wyobraziè eksplozjö kreatywnoĈci w gäowie Czytelnika.

Aby w peäni poznaè moĔliwoĈci bloków, musimy powiedzieè coĈ o procedurach.

Bloki s

é domkniýciami

Kto z czytelników wie, czym jest domkniöcie? JeĈli ktoĈ wie, jestem peäen podziwu — zapewne
ta wiedza Ĉwiadczy o zdobytym dyplomie magistra informatyki. Tym, którzy nie wiedzñ, a sñ
ciekawi, juĔ wyjaĈniam. Domkniöcie jest nienazwanñ funkcjñ lub metodñ. Przypomina metodö
wewnñtrz metody, odwoäujñcñ siö do zmiennych z metodñ zewnötrznñ lub je wspóäuĔytkujñcñ.
W jözyku Ruby domkniöcie lub blok sñ zamkniöte w nawiasy klamrowe (

{}

) lub säowa klu-

czowe 

do..end

 i ich dziaäanie jest uzaleĔnione od odpowiedniej metody (na przykäad 

each

).

Obiekty Proc

Ruby pozwala przechowywaè procedury (potocznie proc) jako obiekty, razem z ich kontekstem.
Dostöpnych jest kilka sposobów. Jeden z nich polega na wywoäaniu metody 

new

 z klasy 

Proc

,

innym jest wywoäanie metody lambda albo proc z moduäu 

Kernel

. Tak przy okazji, wywoäanie

metody lambda lub proc jest preferowane w stosunku do 

Proc.new

, poniewaĔ 

lambda

 i 

proc

przeprowadzajñ kontrolö parametrów.

Listing 2.4 ilustruje, jak utworzyè obiekt 

Proc

 na oba sposoby.

background image

Bloki

_

51

Listing 2.4. proc.rb

#!/usr/bin/env/ruby

count = Proc.new { [1,2,3,4,5].each do |i| print i end; puts }
your_proc = lambda { puts "Lurch: 'Pani wzywa

Īa?'" }

my_proc = proc { puts "Morticia: 'Kto to by

Ī, Lurch?'" }

# Jakiego typu obiekty utworzyli

Ğmy?

puts count.class, your_proc.class, my_proc.class

# Wywo

áanie wszystkich procedur

count.call
your_proc.call
my_proc.call

Po poinformowaniu, Ĕe wszystkie utworzone obiekty sñ obiektami 

Proc

, program wyĈwietla

poniĔszy tekst, wywoäujñc po kolei kaĔdñ procedurö za pomocñ metody 

call

:

12345
Lurch: 'Pani wzywa

Īa?'

Morticia: 'Kto to by

Ī, Lurch?'

Metoda moĔe zostaè wywoäana z blokiem; zwróci wtedy wynik wykonania bloku, nawet jeĈli
sama metoda nie przyjmuje Ĕadnych argumentów. Przypominam, Ĕe blok musi zawsze byè
skojarzony z wywoäaniem metody.

MoĔemy teĔ „przekonaè” metodö do skonwertowania w locie skojarzonego z niñ bloku na obiekt
Proc. W tym celu musimy utworzyè argument metody poprzedzony znakiem 

&

. Ilustruje to

listing 2.5.

Listing 2.5. return_block_proc.rb

#!/usr/local/bin/ruby

def return_block
  yield
end

def return_proc( &proc )
  yield
end

return_block { puts "Mam blok!" }
return_proc { puts "Mam blok, konwertuj

Ă na Proc!" }

WyjĈcie bödzie wyglñdaè tak:

Mam blok!
Mam blok, konwertuj

Ă na Proc!

Metoda 

return_block

 nie ma argumentów i zawiera jedynie instrukcjö 

yield

. Zadaniem 

yield

jest ponownie wykonanie bloku, gdy ten zostanie przekazany do metody. Ogromnie zwiöksza
to uniwersalnoĈè starej dobrej metody.

Nastöpna metoda, 

return_proc

, przyjmuje jeden argument — 

&proc

. Gdy nazwa argumentu

metody jest poprzedzona 

&

, metoda przyjmie blok (jeĈli zostaä przekazany) i skonwertuje na

obiekt Proc. Metoda zawiera w treĈci instrukcjö 

yield

, wiöc wykonuje blok bödñcy zarazem

procedurñ, bez potrzeby uĔycia metody 

call

 obiektu 

Proc

.

background image

Czytaj dalej...

52

_

Rozdzia

ĥ 2. Krótka wycieczka po jýzyku Ruby

Symbole

Jözyk Ruby zawiera specjalny obiekt nazwany symbolem. Na razie wystarczy nam wiedzieè
o symbolach tyle, Ĕe sñ jakby pojemnikami na identyfikatory i äaþcuchy. Symbol moĔna rozpo-
znaè po tym, Ĕe zawsze jest poprzedzany dwukropkiem (

:

).

Symbolu nie tworzy siö bezpoĈrednio przez przypisanie do niego wartoĈci. Aby utworzyè sym-
bol, naleĔy wywoäaè metodö 

_sym

 lub 

intern

 z äaþcuchem lub przypisaè symbol do symbolu.

W celu zilustrowania tego przeksztaäèmy äaþcuch na symbol i z powrotem na äaþcuch.

name = "Matz"
name.to_sym # => ":Matz"
:Matz.id2name # => "Matz"
name == :Matz.id2name # => true

Zaczyna byè niepokojñco zagmatwane? Wiem, Ĕe symbole mogñ wyglñdaè trochö niejasno.
Sñ doĈè abstrakcyjne, poniewaĔ nie wiemy tak naprawdö, co dzieje siö „pod maskñ” interpretera
Ruby. Patrzñc z wierzchu widzimy, Ĕe zawartoĈè äaþcucha 

name

 zostaäa magicznie przeksztaä-

cona na etykietö symbolu. No i co?

No i to, Ĕe od chwili utworzenia symbolu tylko jedna kopia symbolu jest przechowywana pod
pojedynczym adresem pamiöci, dopóki program pozostaje uruchomiony. Z tego powodu Ruby
nie tworzy jednej kopii za drugñ, lecz zawsze odwoäuje siö do tego jednego adresu w pamiöci.
Zwiöksza to wydajnoĈè programów w Ruby, poniewaĔ zajmujñ mniej pamiöci.

Ruby  on  Rails  uĔywa  mnóstwa  symboli,  a  w  miarö  poznawania  jözyka  Czytelnik  zapewne
równieĔ zacznie korzystaè z wielu z nich. W istocie Ruby wewnötrznie wykorzystuje ogromnñ
liczbö symboli. Aby siö o tym przekonaè, wystarczy wykonaè nastöpujñcñ instrukcjö Ruby:

Symbol.all_symbols

Dostaniemy listö ponad 1000 symboli!

Programistom dobrze znajñcym jözyk C# lub Java pomoĔe taka analogia: symbole
w jözyku Ruby sñ jak äaþcuchy interned, przechowywane w puli äaþcuchów intern.

Obs

ĥuga wyjétków

Ruby, podobnie jak Java, C++ i inne jözyki programowania, udostöpnia obsäugö wyjñtków.
Wyjñtek wystöpuje, gdy program wykona coĈ nieprzewidzianego i zostanie przerwany jego
poprawny przepäyw. Ruby jest przygotowany do radzenia sobie z takimi problemami, lecz
moĔemy zajñè siö nimi na wäasny sposób, wykorzystujñc obsäugö wyjñtków.

W jözykach Java i C++ stosowane sñ bloki 

try

; w Ruby uĔyjemy po prostu bloku 

begin

. Odpo-

wiednikiem instrukcji 

catch

 z Javy i C++ sñ w Ruby instrukcje 

rescue

. Tam, gdzie w Javie

uĔywany jest warunek 

finally

, Ruby uĔywa warunku 

ensure

.

Korzystanie z obsäugi wyjñtków zostaäo opisane w rozdziale 10.