Ruby - wprowadzenie

Posted by Jacek Galanciak on

Disclaimer : Tekst ten jest prezentacją języka Ruby dla tych, którzy jeszcze się z nim nie zetknęli. Dla pozostałych będzie on niewiele (lub nic) wnoszącym artykułem o tym, co już nie raz zostało poruszone. Czym ten post różni się od innych, traktujących o tej samej tematyce? Niczym. Jest to moje własne spojrzenie na ten język, manifest wielkiego entuzjazmu z nim związanego oraz próba zaprezentowania Rubiego większej liczbie programistów. Bo jest co pokazywać.

Yukihiro Matsumoto a.k.a. Matz, twórca Rubiego, po raz pierwszy wypuścił swój klejnot na świat w roku 1995. Pragnął stworzyć język o potężnych możliwościach, bardziej obiektowy niż ówczesne języki skryptowe, nadający się do codziennych zastosowań wszelkiego typu oraz sprawiający, że programowanie to czysta przyjemność, a nie naginanie topornej składni w celu osiągnięcia żądanego rezultatu. Wszystko to udało mu się osiągnąć. I znacznie więcej.

Co takiego sprawia, że Ruby jest wyjątkowy?

Wszystko jest obiektem

Stwierdzenie to jest nie do końca prawdziwe, ale to teraz nieistotne. Ruby miał być z założenia w pełni obiektowy. Każda liczba (czy to całkowita czy zmiennoprzecinkowa), tablica czy string to obiekt. Nawet nil (odpowiednik NULL-a z PHP czy C) jest obiektem. Jakże to tak? nil to przecież nic! Owszem. W Rubim reprezentujemy to za pomocą obiektu, który modeluje „nic”.

# To jest komentarz w Ruby. 
# Komentarz za każdą instrukcją niech oznacza
# dla nas to, co instrukcja daje na wyjściu
puts 5.class # Fixnum
puts (1.2).class # Float
puts "tekst".class # String
puts (2..5).class # Range
puts -3.abs # 3
puts (-5.3424).round # -5
puts "Ala ma chomika".length # 14
puts 6.zero? # false

Osobom nadal uważającym, że ich kochane C++ czy PHP jest w pełni obiektowe, polecam pójście do kąta i przemyślenie sprawy raz jeszcze.

Ruby jest językiem dynamicznym…

…i bynajmniej nie oznacza to tego, że oferuje jedynie dynamiczną typizację. Skoro każda liczba jest obiektem, spróbujmy sprawdzić nieparzystość 5:

puts 5.odd?

test.rb:15: undefined method `odd?' for 5:Fixnum (NoMethodError)

Błąd? Nie szkodzi. Ruby jest dynamiczny.

class Integer
  def odd?
    (self % 2) == 1
  end
end

puts 5.odd? # true
puts 6.odd? # false
puts 7.odd? # true

Nie trzeba chyba mówić, jak potężnym to może być narzędziem w rękach wprawnego programisty. Dzięki temu nie ma najmniejszego problemu, by liczby rzeczywiste rozszerzyć o część urojoną, a URL-e zacząć traktować jak zwykłe pliki.

Ruby jest językiem przejrzystym i naturalnym

A oto parę przykładów. Ciekawsza część opatrzona została tym, co skrypt daje na wyjściu - pozostałe przykłady są oczywiste nawet dla tych, którzy Rubiego nie znają.

5.times do
  puts "Ruby!"
end

for i in 1..5 
  puts i
end
5.downto(1) { |i| puts i }

a = 5
# Pierwsze podejście
unless a == 5
  puts "a != 5"
else
  puts "a = 5"
end
# Drugie podejście
if a == 5 then
  puts "a = 5"
else
  puts "a != 5"
end
# Trzecie podejście
puts "a = 5" if a == 5

animals = ["kot", "pies", "chomik", "surykatka"]
animals.each { |animal| puts animal }
puts defined? animals

kot
pies
chomik
surykatka
local-variable

File.open "test.rb" do |file|
  file.each_line { |str| puts str }
end

Kod Rubiego jest nie tylko przejrzysty, ale i zwięzły

W Sieci nietrudno znaleźć listingi parolinijkowych programów, które napisane w innych językach zajmują ich wielokrotnie więcej. Przykłady podane wyżej pokazały, że jest to możliwe, ale jak widać to nie koniec:

def bizarre_proc
  yield
  yield
  yield
  puts "A masz! jeszcze raz!"
  yield
end

bizarre_proc { puts "Bum!" }
bizarre_proc do
  5.times { |i| puts i}
  puts "I jeszcze jeden!"
end

Pokazywanie outputu jest pozbawione sensu (jest zbyt długi) - sprawdźcie u siebie co ten kod produkuje. :)

Jedną z ważniejszych zasad Rubiego jest DRY. Jak widać, yield doskonale ułatwia realizację tej wskazówki. Instrukcja ta ma wiele potężnych zastosowań, które wkrótce poznamy.

Ruby jest obiektowy. I jest Rubim

Tak, to już było. Tyle, że Ruby oferuje masę wspaniałych rozwiązań. Duck typing pozwala na zajęcie się funkcjonalnością, a nie martwieniem się o interfejsy. Moduły dają nam przestrzenie nazw, miksiny oferują przejrzystszy odpowiednik dziedziczenia wielokrotnego, a wszystko to jest podane w zwięzłej i, nie oszukujmy się, pięknej składni Rubiego, dającej tyle możliwości i usprawnień, że nie sposób tego tu i teraz zaprezentować. Tym razem nie będzie przykładowego kodu, po prostu uwierzcie mi na słowo.

Ruby może naprawdę wszystko…

…a to za sprawą licznych modułów i bibliotek. Nie tylko standardowych. Aplikacje webowe? GUI? OpenGL? XML? Automatyzacja systemu? Win32 API? Bez najmniejszego problemu.

Nic nie stoi na przeszkodzie, by samemu napisać rozszerzenie do Rubiego w C, lub wykorzystać ten język do oskryptowania sztucznej inteligencji w swojej grze komputerowej. Wszystko oczywiście prościej, niż znamy to z innych języków.

Ruby jest Twoim przyjacielem…

…bo tylko przyjaciel może się okazać tak pomocny i zaoferować m. in.:

  • irb – interaktywną powłokę Rubiego, przydatną nie tylko przy poznawaniu tego języka
  • ri – dokumentację języka
  • gem – system zarządzania pakietami i bibliotekami

Chcesz użyć modułu RedCloth, którego nie posiadasz w swojej dystrybucji Rubiego?

gem install RedCloth

Moduł zostanie pobrany z Sieci i automatycznie zainstalowany; zupełnie jak w BSD czy Gentoo.

Ruby posiada swoje Rails…

…czym nie może się pochwalić żaden inny język. Prosty system blogowy napisany w 15 minut? No problem, nawet z objaśnieniami każdej linijki kodu. Nie wierzysz? Więcej takich smaczków znajdziesz tutaj.

Ruby ma fajną nazwę :-)

W czym programujesz? C? D? Ą? PHP? A ja w Rubim. I kto tu jest lepszy? ;-)

A teraz czas na pierwszy program…

…bo czym byłaby pierwsza część tutoriala bez tego?

def hello(name)
  puts "Hello, #{name.capitalize}!"
end

hello "ruby"

Hello, Ruby!

Witajcie w świecie Rubiego. Klik.