Rubicy nie gęsi i swój galimatias mają
Znalazłem gdzieś w trzewiach sieci ostateczny dowód na potęgę Ruby'ego :)
Dodałem od siebie jedną linijkę i oto jak ów dowód prezentuje się w całej krasie:
-
cc=%w?Tif\ 3\ hsfbu\ wjsuvft\
-
pg\ b\ qsphsbnnfs: Lbzjoftt,\ \
-
Inqbujfodf,\ aoe\ Hvcsjt.?; b =
-
"Lbssz Wbmm"; b.tr!("b-z","a-z")
-
cc.each{|i| i.tr!("b-y", "a-z")}.
-
last.gsub!(/\, (\n)(I)/, ', I' );
-
puts cc, "\n\t\t--\s#{b}","\n\n"
Prezentacja takiego zperlonego kodu byłaby niepełna bez analizy tego co ten kod robi, zatem do dzieła...
Po rozbiciu kodu na poszczególne wyrażenia całość już tak strasznie nie wygląda:
-
cc = %w?Tif\ 3\ hsfbu\ wjsuvft\
-
pg\ b\ qsphsbnnfs: Lbzjoftt,\ \
-
Inqbujfodf,\ aoe\ Hvcsjt.?;
-
b = "Lbssz Wbmm";
-
b.tr!("b-z","a-z")
-
cc.each{|i| i.tr!("b-y", "a-z")}.last.gsub!(/\, (\n)(I)/, ', I' );
-
puts cc, "\n\t\t--\s#{b}","\n\n"
Linie 1-3 to tworzenie tablicy stringów i przypisanie jej zmiennej cc. Znak \ na koncu wiersza pozwala na kontynuacje stringa w nowym wierszu. Ciekawie wykorzystano tu możliwość definiowania tablic stringów bez korzystania z przecinków i znaków ' " — za pomocą skrótu %w. Jako ogranicznik tekstu zamiast zwyczajowej pary {} wykorzytano tu znak ?. Ten fragment w postaci całkowicie czytelniej wygląda tak:
-
cc=["Tif 3 hsfbu wjsuvft\n",
-
"pg b qsphsbnnfs:",
-
"Lbzjoftt, \nInqbujfodf, aoe Hvcsjt."]
Linia 4 nie wymaga chyba komentarza, w lini 5 mamy za pomocą metody tr!() dokonywana jest zamiana liter w ciągu b. Wykrzyknik na końcu nazwy metody oznacza ze modyfikowana jest wartość zmiennej b (konwencja nazewnicza przyjęta w Rubym). Wykorzystany tu jest skrócony sposób przekazywania parametrów - za pomocą zakresu znaków. Ta linia mogłaby wyglądać też tak:
-
b.tr!('bcdefghijklmnopqrstuvxyz', 'abcdefghijklmnopqrstuvxyz')
Lina 6 to kolejny pokaz potęgi, w jedenej lini wykorzystane są: iterator z blokiem kodu, wyrażenie regularne i łańcuchowe wywołanie metod. No ale po kolei, za pomocą iteratora each() 'dekodujemy' w opisany już powyżej sposób każdy z ciągów w tablicy cc (to iterator i blok kodu). Następnie korzystając z tego, że iterator zwraca self (jak większość metod w Rubym) dobieramy się do ostatniego elementu tablicy (metoda last) i za pomocą wyrażenia regularnego (troche przekombinowanego) usuwamy znak nowego wiersza (to właśnie łancuchowe wywołanie metod). Teraz jeszcze raz wszystko w zwolnionym tempie:
-
# dekodowanie stringow z tablicy cc
-
cc.each{|i| i.tr!("b-y", "a-z")}
-
# usunięcie \n z ostatniego elementu w tablicy
-
cc.last.gsub!(/\, (\n)(I)/, ', I' );
Wyrażenie regularne w tym przypadku możnaby zastąpić z powodzeniem metodą tr! - no ale nie byłoby takiego smaczku.
Koniec wieńczy dzieło - w lini 7 mamy wypisanie wyników naszych działań na ekranie. Ciekawe jest tu chyba tylko to wykorzystanie metody puts() z kilkoma parametrami - w efekcie każdy z nich będzie wypisany w nowej lini.
Ruby to potęga... ;)
QED
PS: cytat który jest efektem działania kodu tu analizowanego uważam za jeden z najbardziej trafnych cytatów jakie spotkałem.
[ruby]








plastic said,
lipiec 5, 2006 @ 23:10
Na dworze ukrop a Ty sie nudzisz ?:)
ciukes said,
lipiec 5, 2006 @ 23:51
“Prawdziwy programisty potrafi pisac assemblerem w dowolnym jezyku”
- Larry Wall (cytat z pamieci)
daniel said,
lipiec 6, 2006 @ 01:15
@plastic: może to właśnie ukrop tak miesza w kodzie ??
ciukes said,
lipiec 6, 2006 @ 15:40
Po odrobinie zastanowienie postwailem sobie pytanie: “Czego ten przyklad dowodzi?”
Jestem rubinowym laikiem i jedyne co widze to mozliwosc napisania kodu ktory stanowi ciekawostke przyrodnicza - nic wiecej.
Oswiec mnie, czy jest jakis inny (szczytny) cel uzywania takich zapisow?
daniel said,
lipiec 6, 2006 @ 16:09
ej tam czepiasz sie… troche za ciepło żeby sie baaardzo zastanawiać !
‘takie zapisy’ to poprostu sposób tworzenia kodu w Rubym i tyle.
Kod tego typu ma zawsze chyba charakter bardziej edukacyjny i rozrywkowy - jedyne zastosowanie jak widze to np umieszczenie sobie go na koszulce :)
Manthios said,
lipiec 8, 2006 @ 18:45
To w takim razie zapraszam tutaj:
http://pl.wikipedia.org/wiki/Perl_golf
Moze uruchomisz RubyGolf (jesli jeszcze nie ma) :)
ciukes said,
lipiec 19, 2007 @ 00:49
Manthios: http://www.rubyquiz.com/