Stringi w Rubim
Posted by Jacek Galanciak on May 4 2007
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.