Any fool can make things bigger, more complex, and more violent. It takes a touch of genius and a lot of courage to move in the opposite direction. Albert Einstein

o Ruby

Interaktywny Ruby

8 komentarzy | Kategorie: Ruby, Techblog, Tips & tricks | trackback
Tagi:

Typowanie dynamiczne

Języki dynamiczne, takie jak Ruby, Python czy też Php wymagają w zasadzie zupełnie innego podejścia niż do języków typowanych statycznie, tj. Java czy też C#. Otóż gdy pisząc w Javie, gdy natkiemy się na poniższą deklarację:

public String toRoman(int number) {
       /* tutaj definicja metody */
}

to dobrze wiemy co możemy wrzucić do metody (liczbę typu int) oraz co dostaniemy na wyjściu (obiekt typu String). Nie zamierzam w tym miejscu rozpoczynać dyskusji, które podejście jest lepsze, bo nie ma jednoznacznej odpowiedzi. Powiedzmy sobie krótko: każdy wybiera to co lubi, co mu bardziej pasuje. Początkujący programiści języków dynamicznych (zwłaszcza jeśli do tej pory używali tylko typowania statycznego) mogą czuć się nieswojo, gdy patrząc na jakąś metodę, czy to w dokumentacji (niestety nie zawsze jest wszystko opisane) czy też w kodzie źródłowym, nie znają odpowiedzi na proste pytanie: "Co mam przesłać do tej metody, a co najważniejsze co od niej dostanę z powrotem?". Dlatego postaram się dać kilka wskazówek dla nowicjuszy w tej dziedzinie, aby w tym nowym świecie poczuli się jak u siebie w domu :-).

Konsola to podstawa

Pisanie prostych skryptów dla wprawek jest męczące. Najlepiej przygodą swą zacząć od... konsoli. Jednakże nie od tej znanej użytkownikom linuksa, tylko od interaktywnej konsoli, która pozwala na bezpośrednie wpisywanie kodu źródłowego i natychmiastowe oglądanie wyniku. Dla Rubiego interaktywna konsola do irb (Iteractive Ruby). Jest to standardowe narzędzie dołączone do interpretera Rubiego, toteż nie jest wymagana dodatkowa instalacja tego narzędzia. Po odpaleniu irb powinniśmy zobaczyć:

irb(main):001:0>

...i migający kursor zachęty. Teraz możemy pisać kod źródłowy, który na bieżąco będzie interpretowany. Zapewniam Was, że po krótkiej chwili obcowania z tym narzędziem, za każdym razem pisząc program w Rubim pierwszym odpalanym programem będzie właśnie irb :-). Dlatego też podam jeszcze kilka innych sposobów na odpalenie tego narzędzia (przydatne zwłaszcza gdy nie mamy dostępu do swojej maszyny, ale jest dostęp do internetu).

Sposób 1

Odwiedzamy stronę http://tryruby.hobix.com/ i cieszymy się Rubim w przeglądarce internetowej. Tak przy okazji, jeśli nie przechodziłeś tego kursu dla początkujących, zrób to jak najprędzej :-).

Sposób 2

Odwiedzamy stronę Hackety.org i ściągamy jeden z plików (w zależności od platformy na której pracujemy plik .bat lub .sh). To niesamowite co ludzie potrafią zmieścić w około 700 (.bat) i 1350 (.sh) bajtach. Generalnie skrypty te łączą się ze stroną podaną wcześniej, tj. http://tryruby.hobix.com/ i do niej przesyłają to co wpisujemy, a wypisują na ekran to co dostaną z powrotem. Ten prosty skrypt możemy nagrać np. na pendrive i nosić razem ze sobą :-).

Sposób 3

Dzięki JRuby (interpreterowi Rubiego napisanego w 100% w Javie) można odpalać irb jako aplikację desktopową (także bezpośrednio z przeglądarki dzięki JWS) bądź też... aplet.
JRuby IRB Console, jako aplikacja desktopowa
JRuby IRB Console, uruchamiane z przeglądarki poprzez JWS
Przeglądnąłem także kod źródłowy JRubiego i okazało się, że zawiera konsolę irb w formie apletu. Zaaplikowałem go na swój blog, możesz go uruchomić klikając tutaj (uwaga, około 2.5MB) bądź też z prawej strony w menu "Narzędzia". Nie jest to jeszcze idealnie działający aplet, ale umożliwia zabawę z Rubim.

Jak odnaleźć się w świecie dynamicznym?

Otóż tak jak wspomniałem wcześniej podczas pracy z Rubim nie zawsze wiemy "na jaki obiekt aktualnie patrzymy". Jeśli pamiętamy podstawową zaletę Rubiego, prawie wszystko jest w nim obiektem. Toteż aby sprawdzić klasę danego obiektu używamy metody class. Ruby posiada także bardzo prosty sposób introspekcji, dzięki któremu można pobrać metody danego obiektu, klasy. Załóżmy, że chcemy porównać pewien łańcuch z wyrażeniem regularnym...

match = /(\d+)(\w+)(\d+)/.match("<<<123abc456>>>")
#zbadajmy co nam zwrocila metoda match
match.class #=> MatchData

MatchData.methods #metody klasy
MatchData.instance_methods #metody instancyjne
MatchData.instance_methods(false) #to samo co wyzej, ale bez odziedziczonych
MatchData.instance_methods(false).include? "to_s" #=> true
MatchData.superclass #=> Object (dziedziczy po Object)

#zajmijmy sie naszym obiektem match
match.public_methods(false).sort #posortowane metody, ["[]", "begin", "captures", "end"...
#i tu sie zaczyna cala zabawa, widzimy metody takie jak begin, captures, end.. sprawdzmy co one zwracaja
match.captures #=> ["123", "abc45", "6"]
match.pre_match #=> <<<
match.post_match #=> >>>
#i tak dalej...

Dopełnianie kodu, czyli TAB, TAB

Pamiętajmy także, że irb umożliwia automatyczne dopełnianie kodu. Przykładowo pamiętamy, że jest jakaś metoda w klasie String na literkę 's', która zamienia nam wielkości liter, ale nie pamiętamy dokładnie jak się nazywa. Zamiast szukać dokumentacji wystarczy wpisać "aZ".s i nacisnąć 2 razy tab. Powinniśmy zobaczyć spis metod, zaczynających się na od litery 's'. Jest wśród nich metoda swapcase, której to potrzebujemy. Jeśli z jakiejś przyczyny nie działa dopełnianie kodu wystarczy do pliku .irbrc (znajdującego się w katalogu domowym użytkownika) dopisać require 'irb/completion'.

Pokoloruj mój świat (na żółto i na niebiesko)

Po dłuższej pracy w irb'ie może się okazać trochę mecząca monotonność białego i czarnego koloru. Bardzo przydatnym może okazać się wirble, czyli mała biblioteka dodająca kolorowanie składni w irb'ie. Jak prawie wszystko w Rubim, tak i instalacja tego narzędzia jest banalnie prosta. Wykonujemy dwa proste kroki:

gem install -y wirble

... oraz dodajemy do .irbrc

require 'rubygems'
require 'wirble'
Wirble.init
Wirble.colorize

Po tym zabiegu cieszymy się kolorowaniem składni:

wirble

Dodatkowo wirble dodaje możliwość bezpośredniego wywołania ri (Ruby Information) bezpośrednio w irb'ie.

>> ri 'length'
More than one method matched your request. You can refine
your search by asking for information on one of:

     Struct#length, Queue#length, Array#length, MatchData#length,
     Hash#length, Set#length, StringIO#length, SyncEnumerator#length,
     Tempfile#length, String#length, REXML::Functions::string_length,
     REXML::Attributes#length, REXML::SyncEnumerator#length,
     Net::HTTPHeader#content_length=, Net::HTTPHeader#content_length,
     Net::HTTPHeader#range_length
=> nil
>> ri 'String#length'
---------------------------------------------------------- String#length
     str.length   => integer
------------------------------------------------------------------------
     Returns the length of _str_.

=> nil

Wygodniej już się nie da :-).

Bardziej życiowy przykład

Do tej pory pokazałem jak używać irb'a i jak go podrasować. Chciałbym na koniec pokazać, że irb może służyć także do innych zadań niż poznawanie języka, składni i obiektów. Irb w sam raz nadaje się do zadań, do których pisanie skryptu byłoby stratą czasu, bądź też do pisania skryptów wraz z debugowaniem na żywo (patrzymy czy coś się nie wysypuje).

Irb jako kalkulator, nawet dla bardzo dużych liczb.

>> 2 ** 1000 - 1
=> 10715086071862673209484250490600018105614048117055336074437503883703510511249361224931983788156958581275946729175531468251871452856923140435984577574698574803934567774824230985421074605062371141877954182153046474983581941267398767559165543946077062914571196477686542167660429831652624386837205668069375

Prosty skrypt odczutyjący nagłówki wykopanych stron na wykopie. Pisany "z palca" metodą prób i błędów. Jeszcze raz podkreślam ekspresyjność Rubiego, a zarazem czytelność (oczywiście pomniejszoną faktem, że to program typu jednolinijowych).

require 'open-uri'
content = open('http://wykop.pl').read
puts content.scan(/<li class="link_item".*?<h3 class="link_title"><a.*?>(.*?)</a>/m).flatten
#Bananowa sztuka
#Jak ERA oszukuje klientów...
#Drukarki 3D
#...

A czy Wy znacie jeszcze ciekawe zastosowanie irb'a? Może jakieś tips&tricks? Albo jak go jeszcze podrasować (pimp my irb:-) )? Podzielcie się z innymi.

Jeśli spodobał Ci się wpis to może umieścisz ten blog w swoim czytniku RSS?

Komentarze

1. avatar icon Seban napisał(a) 28 Maj 2007 o godz. 18:37:

Wow, nie wiedziałem o tym kolorowaniu irba. Przyda się bo nieraz jak się próbuje w nim coś dłuższego napisać to źle się czyta.
Nie wiem czy to się kwalifikuje do podrasowanie irb, ale każdy railsowy projekt ma własną konsolę, chyba opartą o irba. Też bardzo przydatna rzecz.

2. avatar icon Radarek napisał(a) 29 Maj 2007 o godz. 01:47:

Tak, railsowa konsola oparta jest na irb’ie. Jest to bardzo przydatne narzędzie, zwłaszcza przydaje się (w przypadku railsów) do testowania w działaniu modeli.

3. avatar icon Wojciech Piekutowski napisał(a) 02 Cze 2007 o godz. 01:10:

Ciekawy blog, oby tak dalej :)

Konsola RoR pozwala na dużo więcej niż testowanie modeli. Polecam irb Mix Tape.

4. avatar icon Radarek napisał(a) 02 Cze 2007 o godz. 01:14:

Genialne :). Mam tego bloga w rss’ach ale wpis jest na tyle stary, że nie natknąłem się na niego. Wielkie dzięki. Zapraszam ponownie :).

5. avatar icon Tomi napisał(a) 30 Mar 2009 o godz. 20:41:

mam problem (o dziwo) z wirble, po zainstalowaniu biblioteki i dodaniu wpisu do .irbrc w katalogu głównym Ruby znak zachęty zmienił się, lecz składnia kolorowa nie działa, zamiast niej wywala krzaki (oznaczenia kolorów?), konfiguracja: Vista, Ruby 1.8.6, irb 0.9.5

>> "a" => ←[0;31m"←[0;0m←[0;36ma←[0;0m←[0;31m"←[0;0m

jakieś pomysły?

6. avatar icon Radarek napisał(a) 30 Mar 2009 o godz. 20:56:

Tomi, zainstaluj sobie gem win32console i dodaj do ~/.irbrc:

require "win32console"

Powinno pomóc.

7. avatar icon Tomi napisał(a) 30 Mar 2009 o godz. 21:43:

kolorki są, ale skopało się coś innego, jak użyje backspace usuwany jest przedostatni znak

8. avatar icon Radarek napisał(a) 30 Mar 2009 o godz. 21:49:

Ogólnie to jest problem z tym pod windowsem. Może pora zmienić system?:)

Dodaj coś od siebie

Możesz korzystać ze składni Textile.

Pola oznaczone * są wymagane.

Proszę o dodawanie komentarzy związanych z tematem postu, sprawy osobiste proszę załatwiać przez maila bądź gg.

Zastrzegam sobie prawo do moderacji komentarzy (edycja, usuwanie).