Interaktywny Ruby
8 komentarzy | Kategorie: Ruby, Techblog, Tips & tricks | trackbackTagi: interactive irb ruby shell tips&tricks
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:
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.
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.
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.
Ciekawy blog, oby tak dalej :)
Konsola RoR pozwala na dużo więcej niż testowanie modeli. Polecam irb Mix Tape.
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 :).
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;0mjakieś pomysły?
Tomi, zainstaluj sobie gem win32console i dodaj do ~/.irbrc:
Powinno pomóc.
kolorki są, ale skopało się coś innego, jak użyje backspace usuwany jest przedostatni znak
Ogólnie to jest problem z tym pod windowsem. Może pora zmienić system?:)