Proste typy danych

Programista podczas tworzenia programów musi operować na różnych typach danych - liczbach, napisach i nie tylko... W tym rozdziale poznamy wszystkie podstawowe typy danych w Rubym, jednak najpierw - zapoznamy się z pojęciem zmiennej.

Zmienne

Tworząc program, często chcemy użyć tych samych danych w kilku miejscach programu. Wpisywanie ich za każdym razem od nowa jest dosyć uciążliwe, dlatego warto przypisać je na zmienną:

irb(main):001:0> my_number = 54684859685469496879168591685
=> 54684859685469496879168591685

Aby przypisać jakiś obiekt (np. napis) na zmienną, należy wpisać jej nazwę (dowolny ciąg znaków (małych i wielkich liter, cyfr i podkreślników), przy czym pierwszy znak musi być małą literą lub podkreślnikiem), znak równości i przypisywany obiekt. W powyższym przykładzie przypisaliśmy liczbę 5468485968546.9496879168591685 na zmienną o nazwie my_number. Dzięki temu nie musimy jej wpisywać za każdym razem od nowa, wystarczy użyć nazwy zmiennej, na którą została przypisana:

irb(main):001:0> my_number = 54684859685469496879168591685
=> 54684859685469496879168591685
irb(main):002:0> my_number+123456789
=> 54684859685469496879292048474
irb(main):003:0> my_number*3
=> 164054579056408490637505775055
irb(main):004:0>my_number**2 # Exponentiation
=> 2990433878819487041144980098826114485630894125386251139225

Jak widzisz, Ruby sprawuje się całkiem nieźle jako kalkulator ;) W ostatnim wpisanym poleceniu możesz zauważyć krzyżyk (hash). Służy on do umieszczania komentarzy w kodzie programu (interpreter Ruby’iego pomija napisy/kod, które znajdują się po prawej stronie krzyżyka, aż do następnej linijki). Komentarze są bardzo cenne, kiedy pracujesz nad programem w zespole lub gdy zajrzysz do swojego kodu po długim czasie ;)

Czasem możemy chcieć zmienić wartość naszej zmiennej. Aby to zrobić wystarczy po prostu przypisać na naszą zmienną nowy obiekt. Nie musi być takiego samego typu jak poprzedni! Np. jeśli zmienna my_number była liczbą, możemy teraz przypisać napis:

irb(main):001:0> my_number = 5
=> 5
irb(main):002:0> my_number = 'seven'
=> 'seven'

Zauważ, że napisy w Rubym (jak w większości innych języków programowania) zapisujemy między dwoma apostrofami (lub w cudzysłowiu, ale o tym trochę później). Jeśli o tym zapomnimy interpreter "pomyśli", że chodzi nam o zmienną, a nie napis ;)

Proste typy danych

Wiesz już jak przypisać coś na zmienną. Czas dowiedzieć się co można na nią przypisać ;)

Liczby (Fixnums & Floats)
Na tym typie danych operowaliśmy do tej pory najwięcej, więc już wiesz jak działa. Warto jednak wspomnieć, że w Rubym mamy do wyboru mamy dwa typy reprezentujące liczby: całkowite i zmiennoprzecinkowe. Te pierwsze zapisujemy bardzo intuicyjnie (np. 5, 123, czy -10). Te drugie też, ale musimy pamiętać, że część ułamkową oddzielamy od części całkowitej kropką, a nie przecinkiem (np. 12.34, 17.5, -0.001). Czym się różnią w praktyce te dwa typy? Otóż wynik działania, w którym występują same liczby całkowite zawsze będzie liczbą całkowitą (podłogą wyniku)! 

irb(main):001:0> 5/2
=> 2

Na pierwszy rzut oka wydaje się to bardzo nieintuicyjne, ale za jakiś czas zobaczysz sytuacje, w których ten mechanizm będzie bardzo pomocny. Aczkolwiek nie zawsze tak jest (np. gdy chcesz po prostu dowiedzieć się ile to jest pięć podzielić na dwa ;)). Co więc musimy zrobić, aby otrzymać poprawny matematycznie wynik? Zapisać co najmniej jedną z tych liczb jako liczbę zmiennoprzecinkową (czyli dopisać .0):

irb(main):001:0> 5/2
=> 2
irb(main):002:0> 5/2.0
=> 2.5

Co ciekawe (i unikatowe dla Ruby’iego), dla czytelności zapisu możemy oddzielać cyfry podkreślnikami. Poprawny więc będzie zapis 1_000_000_000 (który jest bardziej czytelny niż 1000000000).

Napisy (Strings)
Z napisem też już się raz spotkaliśmy. Zapisujemy je za pomocą apostrofów lub w cudzysłowie, np. "Short text", 'Short text, but longer than the previous one'. Czym różnią się te formy zapisu? Tekst między apostrofami zostanie zinterpretowany dokładnie tak jak został wpisany. Jeżeli zaś napis zostanie umieszczony w cudzysłowie, interpreter zmieni nieco jego wygląd, jeśli trafi na znak ucieczki (odwrócony ukośnik, np. fragment napisu “\n” zostanie zinterpretowany jako znak nowej linii, a “\t” jako tabulator) lub string interpolation, czyli “wstrzyknięcie” zmiennej, lub nawet całego wyrażenia w napis, za pomocą krzyżyka i nawiasów klamrowych, np. "I'm #{2016-1994} y.o.". Zobaczmy jak to wygląda w praktyce (zauważ, że pierwsze okienko symbolizuje plik tekstowy (co zaznaczone jest odpowiednim komentarzem), a drugie konsolę):

#File: Strings.rb
puts 'Hey'
puts "Hey"
puts 'Do not look down!\n\n\n\n\n\n\n\n\n\n\n\nOh, you!'
puts "Do not look down!\n\n\n\n\n\n\n\n\n\n\n\nOh, you!"
puts 'I am #{2016-1994} y.o.'
puts "I am #{2016-1994} y.o."
jan@Stacja-Linux ~/Pulpit $ ruby Strings.rb 
Hey
Hey
Do not look down!\n\n\n\n\n\n\n\n\n\n\n\nOh, you!
Do not look down!
 
 
 
 
 
 
 
 
 
 
 
Oh, you!
I’m #{2016-1994} y.o.
I’m 22 y.o.

Zauważ, że w cudzysłowie można bez obaw zapisać apostrof i odwrotnie. Jeśli zaś, zapiszemy cudzysłów wewnątrz napisu utworzonego cudzysłowem zakończy się to błędem, gdyż interpreter źle “określi” miejsce, w którym chcemy zakończyć napis:

irb(main):001:0> puts "She said "Hi""
SyntaxError: (irb):1: syntax error, unexpected tCONSTANT, expecting end-of-input
puts "She said "Hi""
                  ^
	from /home/jan/.rbenv/versions/2.1.7/bin/irb:11:in `<main>'

Możemy to jednak przezwyciężyć znakami ucieczki:

irb(main):002:0> puts "She said \"Hi\"" 
She said "Hi"
=> nil

Typ logiczny (Boolean)
Czasem zdarza się, że chcemy zapisać w programie dane, które mogą przyjąć tylko dwa stany (np. włączony/wyłączony, prawda/fałsz, krajowy/zagraniczny). Służy do tego specjalny, logiczny typ danych. Ma tylko dwie możliwe wartości: true i false. Mamy z nimi do czynienia na przykład przy porównaniach:

irb(main):001:0> 5>1
=> true
irb(main):002:0> 3<2.999
=> false
irb(main):003:0> 17>=10+2+5
=> true
irb(main):004:0> 2+2==2*2 # is L equal to R?
=> true
irb(main):004:0> 3+3+3!=3*3 # is L not equal to R?
=> false

Nil
Ciężko sobie wyobrazić typ danych, który byłby prostszy niż boolean, ale takowy istnieje. Istnieje, gdy coś nie istnieje ;). W poprzednim rozdziale używaliśmy polecenia puts do wypisywania napisów w IRB. IRB po wykonaniu polecenia zawsze zwraca wartość ostatniego przetworzonego wyrażenia. Ale jaka miałaby być wartość wyrażenia wypisującego tekst? W Rubym jest to nil, czyli pustka, nieokreśloność, nic...