Stringi w Rubim

(5 komentarzy)

W kategoriach: Ruby , Ruby tutorial , Techblog / 04 maja 2007 [10:13:28]

Tagi technorati:

String jest jedną z większych klas standardowych w języku Ruby - a to za sprawą ponad 70 metod. Nie trzeba chyba nikomu przypominać o ważności tego typu - przejdźmy od razu do poznawania, jak to wszystko wygląda w Rubim.

Tworzymy Stringa

Zacznijmy od pojedynczych apostrofów:

a = 'zwykle przypisanie'      # => "zwykle przypisanie"
b = '"cos", \'cokolwiek\''    # => "\"cos\", 'cokolwiek'"
c = '(nie)dzialanie \n, /'    # => "(nie)dzialanie \\n, /"

puts a, b, c

Na wyjściu mamy:

zwykle przypisanie
"cos", 'cokolwiek'
(nie)dzialanie \n, /

Widzimy tutaj, że jedyny znak, który może nam przerwać łańcuch to ', dlatego jeśli chcemy go umieścić w Stringu, musimy go poprzedzić ukośnikiem \. Zwrócmy uwagę na to, jak kodowane są znaki " i \.

Jeśli nie odpowiadają nam apostrofy, możemy użyć innych ograniczników:

a = %q/zwykle przypisanie/                    # => "zwykle przypisanie"
b = %q!niemal\! ko\mpletna" ' / samowolka\\!  # => "niemal! ko\\mpletna\" ' / samowolka\\"
c = %q(w nawiasach () tez dziala'")           # => "w nawiasach () tez dziala'\""

puts a, b, c

Wyjście:

zwykle przypisanie
niemal! ko\mpletna" ' / samowolka\
w nawiasach () tez dziala'"

Powyższe przykłady pokazują, że możemy użyć alternatywnych apostrofów ograniczających naszego Stringa. Pamiętać trzeba tylko o tym, że jeśli umieszczamy ów apostrof w Stringu, należy poprzedzić go ukośnikiem, by zaznaczyć, że jeszcze go nie kończymy.

Podobnie jak w innych językach skryptowych, Stringi można tworzyć, uwzględniając dodatkowe podstawienia, za pomocą cudzysłowia:

a = "zwykle podstawienie"                     # => "zwykle podstawienie"
b = "dodatkowe ' znaki \\ / \""               # => "dodatkowe ' znaki \\ / \""
c = "2 + 2 = #{2 + 2}\na: #{a.upcase}"        # => "2 + 2 = 4\na: ZWYKLE PODSTAWIENIE"
d = "5! = #{ def factorial(n)
               n > 1 ? n*factorial(n - 1) : 1
             end
             factorial(5)}"                   # => "5! = 120"

puts a, b, c, d

Na wyjściu otrzymujemy:

zwykle podstawienie
dodatkowe ' znaki \ / "
2 + 2 = 4
a: ZWYKLE PODSTAWIENIE
5! = 120

Powyższe przykłady pokazują, że znaki cudzysłowia oferują nam znacznie więcej niż apostrofy: możemy dodatkowo podstawiać znaki specjalne (takie jak koniec linii), wartości zmiennych czy nawet duże i skomplikowane wyrażenia.

Istnieje możliwość podawania kodów ASCII wybranych przez nas znaków:

puts "\141b\143"

Na wyjściu otrzymamy oczywiście abc. Kody podajemy w postaci ósemkowej!

Podobnie jak apostrofy, znaki cudzysłowia można zastępować alternatywną formą:

a = %Q{To jest to samo, co "}               # => "To jest to samo, co \""
b = %<tak tez mozna: #{1 + 1}>              # => "tak tez mozna: 2"
c = %{dzialaja znaki "/' i {}, ale samo \} i \\ juz nie}
                             # => "dzialaja znaki \"/' i {}, ale samo } i \\ juz nie"
puts a, b, c

Wyjście:

To jest to samo, co "
tak tez mozna: 2
dzialaja znaki "/' i {}, ale samo } i \ juz nie

Kiedy trzeba dłuższych łańcuchów...

Czasem musimy użyć nieco dłuższych Stringów, a formatowanie takich nie jest zbyt wygodne przy użyciu wymienionych wyżej sposobów. Z pomocą przychodzi nam znana z innych języków skryptowych konstrukcja tzn. heredoc.

a = <<HERE
To jest przykladowy
heredoc z podstawieniem: #{1 + 1}
Dzialaja znaki " ' /, ale nie \\
HERE

b = <<-'TUTAJ'
To jest przykladowy
heredoc z podstawieniem: #{1 + 1}
Dzialaja znaki " ' /, ale nie \\
TUTAJ

puts a, b

Wyjście:

To jest przykladowy
heredoc z podstawieniem: 2
Dzialaja znaki " ' /, ale nie \
To jest przykladowy
heredoc z podstawieniem: #{1 + 1}
Dzialaja znaki " ' /, ale nie \\

Łatwo zauważyć różnice w poszczególnych formach oraz fakt, że jeden z nich jest cudzysłowiem, a drugi - apostrofem.

Stringowa "matematyka"

W Rubim Stringi możemy nie tylko sklejać, ale i mnożyć:

puts "bua" + "ha"*3
buahahaha

To nie wszystko. Mamy także operator modulo ( % ), który w Stringach jest operatorem formatowania:

puts "%.5f" % Math::PI
puts "%s ma %02d lat" % ["Ala", 5]

Co na wyjściu da nam:

3.14159
Ala ma 05 lat

Sposób formatowania jest taki sam, jak w metodzie sprintf, przy więcej niż jednym elemencie należy użyć tablicy do przekazywania parametrów.

Szczypta metod

Poznamy teraz parę wybranych metod (umówienie całości nie ma sensu - ri String!).

"Ala ma tyfus".length             # => 12
"przykladowy tekst".capitalize    # => "Przykladowy tekst"
"".empty?                         # => true
"abc".empty?                      # => false
"ucinam".chop                     # => "ucina"
"gdzie ten kot sie schowal?".index("kot")
                                  # => 10
"ruby".reverse                    # "ybur"
"Ala ma kota"[0]                  # 65
"Ala ma kota"[0..2]               # "Ala"
"Ala ma kota"[-4..-1]             # "kota"
"Ala ma kota".slice(-4..-1)       # "kota"
                                  # metody te są synonimiczne
"ssssssciiiiisssssskammmy".squeeze("sm")
                                  # => "sciiiiiskamy"
"12:15:30".split(':')             # => ["12", "15", "30"]
"abcd".succ                       # => "abce"
"99zz".succ                       # => "100aa"
"PoSzLeM nA iMpReSke".swapcase    # => "pOsZlEm Na ImPrEsKE"
"125".to_i                        # => 125
"abc" > "cde"                     # false
"abc" <=> "cde"                   # -1

"Psujemy" Stringa

Kiedy wywołujemy wszystkie powyższe metody, wartość samego obiektu nie jest modyfikowana - zwracana jest jedynie wartość z wynikiem działania. Istnieje jednak możliwość bezpośredniej zmiany wartości naszego Stringa:

a = "psuja!"      # => "psuja!"
a.upcase          # => "PSUJA!"
a                 # => "psuja!"
a.upcase!         # => "PSUJA!"
a                 # => "PSUJA!"

Przyjęło się w Rubim, że metody zakończone wykrzyknikiem mogą być niebezpieczne dla naszych danych. W kontekście Stringów bezpowrotnie modyfikują sam obiekt.

Podsumowanie

Stringi w Rubim mają potężne możliwości. Warto je wszystkie poznać, choćby po to, by uniknąć ponownego pisania gotowego już kodu.

Komentarze: Skocz na dół, na górę

  1. Rub*i*m !?

  2. Nasz ojczysty język mnie zawsze zaskakiwał.

    Spójrz na oficjalną stronę Rubiego po polsku – to niesamowite, ale właśnie tak to się pisze! :-)

  3. (Komentarz zmodyfikowany 04.05.2007 o 20:05)

    Jeśli chodzi o stringi, to najbardziej lubię je delikatnie ściągać z pupy mej życiowej partnerki.
    I to wszystko, co chciałem powiedzieć na ten temat.

  4. Nie wyczytałem tu nic że stringi to obiekty mutowalne a takimi są w przeciwieństwie do np. .NET’woych czy tez Pythonowych stringów. Koment o sciąganiu z pupy też jest dobry :)

  5. A mnie zabrakło słowa o pojedynczych znakach, jako że różnią się nieco od tych np. z C/C++.

    Po tym właśnie można rozpoznać doświadczenie programisty: początkujący pracując z łańcuchami znaków myślą o majciochach, a doświadczeni na odwrót.

Dodaj komentarz na temat

Zanim skomentujesz...

W komentarzach działają znaczniki Textile.
Zastrzegam sobie prawo do edycji Twojego komentarza tylko i wyłącznie w celach estetycznych (naprawienie źle wstawionego kodu, itp). Nie zmieniam ich treści, ortografii, interpunkcji. Jeśli odczuwasz potrzebę edycji swojego komentarza, skontaktuj się ze mną, a zdziałamy co trzeba.