Ruby/Powrót do prostych przykładów: Różnice pomiędzy wersjami

Usunięta treść Dodana treść
Szymon wro (dyskusja | edycje)
mNie podano opisu zmian
Szymon wro (dyskusja | edycje)
Nie podano opisu zmian
Linia 80:
W tym programie użyta jest nowa struktura sterująca - <tt>while</tt>. Kod pomiędzy <tt>while</tt> a jej kończącym <tt>end</tt> będzie wykonywany w pętli tak długo jak pewien określony warunek pozostanie prawdziwy. W tym przypadku <tt>guess=STDIN.gets</tt> jest zarówno aktywną instrukcją (pobierającą linię wejściową od użytkownika i zachowującą ją jako <tt>guess</tt>), oraz warunkiem (jeżeli nie ma żadnego wejścia, <tt>guess</tt>, które reprezentuje wartość całego wyrażenia <tt>guess=STDIN.gets</tt>, będzie miało wartość <tt>nil</tt>, która spowoduje przerwanie pętli <tt>while</tt>).
 
<tt>STDIN</tt> oznacza obiekt standardowego wejścia. Zwykle, <tt>guess = gets</tt> robi to samo, co <tt>guess = STDIN.gets</tt>.
 
<tt>rand(3)</tt> w linii 2 zwraca losową liczbę w przedziale od 0 do 2. Ta losowa liczba jest użyta do wyciągnięcia jednego elementu z tablicy <tt>words</tt>.
Linia 88:
<tt>guess.chop!</tt> w linii 6 usuwa ostatni znak z <tt>guess</tt>. W tym wypadku zawsze będzie to znak nowej linii, gdyż <tt>gets</tt> dodaje ten znak by odzwierciedlić naciśnięcie przez użytkownika klawisza Enter (Return), co w naszym wypadku jest niepotrzebne.
 
W linii 15 drukujemy tajne słowo (<tt>secret</tt>). Zapisaliśmy to jako wyrażenie <tt>puts</tt> (skrót od ang. ''put string'' - dosł. "połóż łańcuch") z dwoma argumentami, które są drukowane jeden po drugim. Można to zapisać równoważnie z jednym argumentem, zapisując <tt>secret</tt> jako <tt>#{secret}</tt> by było jasne, że jest to zmienna do przetworzenia, a nie zaś literalne słowo:
 
<pre>puts "the word is #{secret}."</pre>
 
Wielu programistów uważa, że utworzenie on pojedynczego łańcucha jako argumentu metody <tt>puts</tt> to czytelniejszy sposób formułowania wyjścia.
 
Również my od teraz stosujemy pomysł z używaniem <tt>puts</tt> do standardowego wyjścia naszego skryptu, ale ten skrypt używa również <tt>print</tt> zamiast <tt>puts</tt>, w liniach 4 i 13. <tt>puts</tt> i <tt>print</tt> nie oznaczają dokładnie tego samego. <tt>print</tt> wyświetla dokładnie to, co jest podane;. <tt>puts</tt> ponadto zapewnia, że linia na wyjściu posiada znak końca linii. Używanie <tt>print</tt> w liniach 4 i 13 ustawia kursor dalej, poza uprzednio wydrukowanym tekstem zamiast przenosić go na początek następnego wiersza. Tworzy to rozpoznawalny znak zachęty do wprowadzania danych przez użytkownika.
 
W ogóle,Poniższe cztery wywołania wyjścia poniżej są równoważne:
 
<pre>
Linia 112:
</pre>
 
Jeden słaby punkt: czasami okno tekstowe z powodu prędkości działania posiada buforowane wyjście. Poszczególne znaki są buforowane i wyświetlane dopiero gdy pojawi się znak przejścia do nowej linii. Więc, jeżeli skrypt naszej zgadywanki nie pokazuje zachęty dla użytkownika dopóki użytkownik nie poda odpowiedzi, niemal na pewno winne jest buforowanie. Aby upewnić się, że tak się nie stanie możesz wyświetlić (ang. ''flush'' - dosł. "wylać") wyjście jak tylko zostanie wydrukowana zachęta dla użytkownika. <tt>flush</tt> mówi standardowemu urządzeniu wyjściowemu (obiekt nazwany <tt>STDOUT</tt>), "nie czekaj; - wyświetl to co masz w tej chwili.".
 
<pre>
Linia 120:
</pre>
 
I rzeczywiście, możemy jesteśmybędziemy z tym bardziej ostrożnibezpieczniejsi również w następnym skrypcie.
 
=== Wyrażenia regularne ===
Linia 142:
</pre>
 
W linii 6 w warunku dla pętli <tt>while</tt> zakodowana jest "na sztywno" wartość <tt>true</tt>, co w efekcie daje nam nieskończoną pętlę. Aby więc przerwać wykonywanie pętli umieściliśmy instrukcje <tt>break</tt> w liniach 8 i 10. Te dwie instrukcje są również przykładem "''modyfikatorów'' <tt>if</tt>". ''Modyfikator if'' <tt>if</tt> wykonuje wyrażenie po swojej lewej stronie wtedy i tylko wtedy, gdy określony warunek jest prawdziwy. Konstrukcja ta jest niezwykła, gdyż działa logicznie od prawej do lewej strony, ale jest dostępna, ponieważ wielu ludziom przypomina ona podobne wzorce obecne w mowie potocznej. Dodatkowo jest ona zwięzła - nie potrzebuje wyrażenia <tt>end</tt> by wskazać interpreterowi ile kodu następującego po <tt>if</tt> ma być traktowane jako warunek. ''Modyfikator if'' <tt>if</tt> jest wygodnym sposobem używanym w sytuacjach, gdzie wyrażenie i warunek są wystarczająco krótkie by zmieścić się razem w jednej linii skryptu.
 
RozważRozważmy zmiany w interfejsie użytkownika w stosunku do poprzedniego skryptu - łamigłówki. Bieżący interfejs pozwala użytkownikowi zakończyć program poprzez wciśnięcie klawisza Enter (Return) przy pustej linii. Sprawdzamy czy każda linia z wejścia jest pustym łańcuchem, a nie czy niew ogóle istnieje.
 
W liniach 7 i 9 mamy "nie-destruktywny" <tt>chop</tt>;. znów, pozbywamyPozbywamy się tak niechcianego znaku końca linii, który zawsze otrzymujemy od <tt>gets</tt>. DodajmyJak wykrzyknikdodamy iwykrzyknik, będziemy mieli "destruktywny" <tt>chop</tt>. Jaka to różnica? W Rubim istnieje konwencja dołączania znaków '<tt>!'</tt> lub '<tt>?'</tt> do końca nazw pewnych metod. Wykrzyknik (<tt>!, czasami wymawiany jako "bang!"</tt>) oznacza coś potencjalnie destruktywnego, można powiedzieć, coś co może zmienić wartość przylegającego wyrażenia. <tt>chop!</tt> zmienia łańcuch bezpośrednio, ale <tt>chop</tt> daje ci obciętą kopiekopię bez psucia oryginału. Oto ilustracja tej różnicy.
 
<pre>
Linia 159:
</pre>
 
Czasem będziesz też widział w użyciu <tt>chomp</tt> i <tt>chomp!</tt>. Te dwa są bardziej selektywne: końcówka łańcucha jest obcinana tylko wtedy, gdy jest znakiem końca linii. Dla przykładu, <tt>"XYZ".chomp!</tt> nie robizrobi nic. Jeżeli potrzebujesz jakiegoś triku by zapamiętać różnice, pomyśl o osobie lub zwierzęciu, które smakuje coś nim zdecyduje się to ugryźć (ang. ''chomp'' - "jeść niechlujnie"), a toporze rąbiącym jak popadnie (ang. ''chop'' - "odrąbanie").
 
Pozostałe konwencje nazywania metod pojawiają się w liniach 8 i 10. Znak zapytania (<tt>?, czasem wymawiany w angielskim jako "huh?"</tt>) oznacza metodę - "predykat"predykatową (orzekającą o czymś), która zwraca albo prawdę (<tt>true</tt>) albo fałsz (<tt>false</tt>).
 
Linia 11 tworzy obiekt będący wyrażeniem regularnym z łańcucha podanego przez użytkownika. Cała właściwa praca wykonywana jest wreszcie w linii 12, która używa <tt>gsub</tt> do globalnego podstawienia każdego spasowaniadopasowania naszego wyrażenia z samym sobą, ale otoczonego przez znaczniki ANSI;. również taTa sama linia wyświetla również wyniki.
 
Mogli byśmyMoglibyśmy podzielić linię 12 na osobne linie, tak jak tutaj:
 
<pre>
Linia 179:
</pre>
 
Spójrz ponownie na ostatnią część linii 12. <tt>st</tt> i <tt>en</tt> były zdefiniowane w liniach 1-2 jako sekwencje ANSI które odpowiednio zmieniają i przywracają kolor tekstu. W linii 12 są one zawarte w <tt>#{}</tt> by zostały w ten sposób były właściwie zinterpretowaneinterpretowane (i nie zobaczymywystąpiły zamiast nich nazwnazwy zmiennych). Pomiędzy nimi widzimy <tt>\\&</tt>. Jest to trochę podstępne. Ponieważ podstawiany łańcuch zawarty jest w cudzysłowach (podwójnych), para odwróconych ukośników będzie zinterpretowana jako jeden ukośnik;, co <tt>gsub</tt> zobaczy właściwie jako <tt>\&</tt>,. i coTo spowoduje powstanie specjalnego kodu, który z kolei odwoła się do czegokolwiek, co jako pierwsze będzie pasować do wzorca. Tak więc nowy łańcuch, gdy będzie wyświetlony będzie wyglądał tak jak pierwszy z wyjątkiem tego, że te fragmenty które pasują do wzorca będą wyświetlone w odwróconych kolorach.
<noinclude>
{{ProstaNawigacja|spis=Ruby|poprzart=Ruby/Tablice|poprz=Tablice|nastart=Ruby/Struktury sterujące|nast=Struktury sterujące}}