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:

RUBY:
  1. cc=%w?Tif\ 3\ hsfbu\ wjsuvft\
  2.  pg\ b\ qsphsbnnfs: Lbzjoftt,\ \
  3. Inqbujfodf,\ aoe\ Hvcsjt.?;  b =
  4. "Lbssz Wbmm"; b.tr!("b-z","a-z")
  5. cc.each{|i| i.tr!("b-y", "a-z")}.
  6. last.gsub!(/\, (\n)(I)/, ', I' );
  7. 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:

RUBY:
  1. cc = %w?Tif\ 3\ hsfbu\ wjsuvft\
  2.  pg\ b\ qsphsbnnfs: Lbzjoftt,\ \
  3. Inqbujfodf,\ aoe\ Hvcsjt.?; 
  4. b = "Lbssz Wbmm";
  5. b.tr!("b-z","a-z")
  6. cc.each{|i| i.tr!("b-y", "a-z")}.last.gsub!(/\, (\n)(I)/, ', I' );
  7. 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:

RUBY:
  1. cc=["Tif 3 hsfbu wjsuvft\n",
  2.     "pg b qsphsbnnfs:",
  3.     "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:

RUBY:
  1. 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:

RUBY:
  1. # dekodowanie stringow z tablicy cc
  2. cc.each{|i| i.tr!("b-y", "a-z")}
  3. # usunięcie \n z ostatniego elementu w tablicy
  4. 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.

[]
Spodobało się? Podziel się z innymi: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • del.icio.us
  • Wykop
  • Gwar
  • Digg
  • Technorati

Liczba komentarzy: 7 »

  1. plastic said,

    lipiec 5, 2006 @ 23:10

    Na dworze ukrop a Ty sie nudzisz ?:)

  2. ciukes said,

    lipiec 5, 2006 @ 23:51

    “Prawdziwy programisty potrafi pisac assemblerem w dowolnym jezyku”
    - Larry Wall (cytat z pamieci)

  3. daniel said,

    lipiec 6, 2006 @ 01:15

    @plastic: może to właśnie ukrop tak miesza w kodzie ??

  4. 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?

  5. 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 :)

  6. 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) :)

  7. ciukes said,

    lipiec 19, 2007 @ 00:49

    Manthios: http://www.rubyquiz.com/

RSS feed for comments on this post

Dodaj komentarz