Ruby/Łańcuchy znakowe
Łańcuchy znakowe
edytujRuby radzi sobie z łańcuchami znakowymi tak dobrze jak z danymi numerycznymi. Łańcuch może być ograniczony znakami podwójnego cudzysłowu ("...") lub pojedynczego (apostrof) ('...').
irb(main):001:0> "abc" => "abc" irb(main):002:0> 'abc' => "abc"
Używanie podwójnych lub pojedynczych cudzysłowów czasami może mieć różne efekty. Łańcuch ujęty w podwójny cudzysłów pozwala stosować znaki formatujące za pomocą odwróconego ukośnika oraz obliczać zagnieżdżone wyrażenia używając #{}. Łańcuch ujęty w apostrofy nie pozwala na taką interpretację; to co widzisz - to dostajesz. Przykłady:
irb(main):001:0> puts "a\nb\nc" a b c => nil irb(main):002:0> puts 'a\nb\nc' a\nb\nc => nil irb(main):003:0> "\n" => "\n" irb(main):004:0> '\n' => "\\n" irb(main):005:0> "\001" => "\001" irb(main):006:0> '\001' => "\\001" irb(main):007:0> "abcd #{5*3} efg" => "abcd 15 efg" irb(main):008:0> var = " abc " => " abc " irb(main):009:0> "1234#{var}5678" => "1234 abc 5678"
Manipulowanie łańcuchami w Rubim jest sprytniejsze i bardziej intuicyjne niż w C. Dla przykładu, możesz łączyć ze sobą łańcuch używając +, a powtarzać łańcuch wiele razy za pomocą *:
irb(main):001:0> "foo" + "bar" => "foobar" irb(main):002:0> "foo" * 2 => "foofoo"
Konkatenacja łańcuchów w C jest bardziej kłopotliwa z powodu konieczności bezpośredniego zarządzania pamięcią:
char *s = malloc(strlen(s1)+strlen(s2)+1);
strcpy(s, s1);
strcat(s, s2);
/* ... */
free(s);
W Rubim natomiast, nie musimy w ogóle zastanawiać się nad miejscem zajmowanym w pamięci przez łańcuch. Jesteśmy wolni od jakiegokolwiek zarządzania pamięcią.
Oto kilka rzeczy, które możesz zrobić z łańcuchami.
Konkatenacja:
slowo = "fo" + "o"
puts slowo #=> "foo"
Powtórzenie:
slowo = slowo * 2
puts slowo #=> "foofoo"
Ekstrahowanie znaków (zauważ, że znaki w Rubim są liczbami całkowitymi):
puts slowo[0] #=> 102
# 102 jest kodem ASCII znaku `f'
puts slowo[-1] #=> 111
# 111 jest kodem ASCII znaku `o'
(Wartości ujemne oznaczają liczbę znaków od końca łańcucha.)
Ekstrahowanie podłańcuchów:
warzywo = "pietruszka"
puts warzywo[0,1] #=> "p"
puts warzywo[-2,2] #=> "ka"
puts warzywo[0..3] #=> "piet"
puts warzywo[-5..-2] #=> "uszk"
Sprawdzanie równości:
puts "foo" == "foo" #=> true
puts "foo" == "bar" #=> false
Zróbmy użytek z kilku tych cech. Oto zgadywanka "co to za słowo", ale być może słowo "zgadywanka" to zbyt dużo dla tego kodu. ;-)
# zapisz to jako zgadnij.rb
slowa = ['fiolek', 'roza', 'bez']
sekret = slowa[rand(3)]
print "zgadniesz? "
while odp = STDIN.gets
odp.chop!
if odp == sekret
puts "Wygrales!"
break
else
puts "Przykro mi, przegrales."
end
print "zgadniesz? "
end
puts "Chodzilo o " + sekret + "."
Na razie nie przejmuj się za bardzo szczegółami powyższego kodu. Oto jak wygląda uruchomiona łamigłówka.
% ruby zgadnij.rb zgadniesz? fiolek Przykro mi, przegrales. zgadniesz? bez Przykro mi, przegrales. zgadniesz? ^D Chodzilo o roza.
(Mogło nam pójść nieco lepiej biorąc pod uwagę, że szansa na trafienie wynosi 1/3.)