Ruby/Kontrola dostępu: Różnice pomiędzy wersjami

Usunięta treść Dodana treść
Gotar (dyskusja | edycje)
→‎Kontrola dostępu: poprawiony kod (niedotłumaczone?)
Nie podano opisu zmian
 
Linia 5:
Rozważmy, co się stanie, gdy zdefiniujemy metodę na samym szczycie hierarchii, nie wewnątrz jakiejkolwiek klasy? Możemy myśleć o takiej metodzie analogicznie jak o funkcji w bardziej tradycyjnym języku, takim jak C.
 
<sourcesyntaxhighlight lang="ruby">
def kwadrat(n)
n * n
Linia 11:
 
kwadrat(5) #=> 25
</syntaxhighlight>
</source>
 
Wydaje się, że nasza nowa metoda nie należy do żadnej klasy, ale w rzeczywistości Ruby dodał ją do klasy <tt>Object</tt> która jest nadklasą każdej innej klasy. W rezultacie każdy obiekt powinien mieć możliwość używania tej metody. Jest to prawdą, ale z małym kruczkiem: jest to ''prywatna'' metoda każdej klasy. Wprawdzie będziemy jeszcze dokładnie rozważać co to znaczy, ale zauważmy, że jedną z konsekwencji tego faktu jest to, że metoda ta może być wywołana tylko w funkcyjnym stylu, jak poniżej:
 
<sourcesyntaxhighlight lang="ruby">
class Klasa
def czwarta_potega_z(x)
Linia 23:
 
Klasa.new.czwarta_potega_z(10) #=> 10000
</syntaxhighlight>
</source>
 
Wyraźnie nie możemy wywołać metody na rzecz obiektu:
 
<sourcesyntaxhighlight lang="ruby">
"ryba".kwadrat(5)
ERR: (eval):1: private method `kwadrat' called for "ryba":String
</syntaxhighlight>
</source>
 
To raczej zręcznie chroni czysto obiektową naturę Rubiego (funkcje są wciąż metodami obiektów, ale odbiorcą domyślnie jest <tt>self</tt>) dostarczając funkcji które mogą być zapisane podobnie jak w bardziej tradycyjnym języku.
Linia 36:
Powszechną dyscypliną umysłową w programowaniu obiektowym, którą zasugerowaliśmy we wcześniejszym rozdziale, jest problem rozdzielenia ''specyfikacji'' i ''implementacji'', czyli ''jakie'' zadania wymagamy by obiekt wypełniał i ''jak'' je właściwie wypełnia. Wewnętrzne prace obiektu powinny być zazwyczaj ukryte przed jego użytkownikami. Powinni oni dbać o to, co wchodzi i wychodzi do/z obiektu oraz ufać, że obiekt wie co robi wewnętrznie z danymi. Z tego powodu często pomocne jest, gdy klasa posiada metody niewidoczne z zewnątrz, ale używane wewnętrznie, które mogą być poprawione przez programistę kiedy tylko zajdzie taka potrzeba, bez zmieniania sposobu, w jaki użytkownicy widzą obiekty danej klasy. W trywialnym przykładzie poniżej, pomyśl o metodzie <tt>eval</tt> jako o niewidocznych pracach klasy.
 
<sourcesyntaxhighlight lang="ruby">
class Test
def dwa_razy(a)
Linia 52:
test.wylicz(6)
ERR: (eval):1: private method `wylicz' called for #<Test:0x4017181c>
</syntaxhighlight>
</source>
 
<sourcesyntaxhighlight lang="ruby">
test.dwa_razy(6)
#=> 6 razy dwa to 12
</syntaxhighlight>
</source>
 
Moglibyśmy oczekiwać, że <tt>test.wylicz(6)</tt> zwróci <tt>12</tt>, ale zamiast tego nauczyliśmy się, że metoda <tt>wylicz</tt> jest niedostępna, gdy odgrywamy rolę użytkownika obiektu <tt>Test</tt>. Tylko inne metody klasy <tt>Test</tt>, takie jak <tt>dwa_razy</tt> mogą korzystać z <tt>wylicz</tt>. Od nas wymagane jest posługiwanie się publicznym interfejsem, który składa się z metody <tt>dwa_razy</tt>. Programista, który ma pod kontrolą tę klasę, może swobodnie modyfikować <tt>wylicz</tt> (tutaj, być może zmieniając <tt>b*2</tt> na <tt>b+b</tt> i argumentując to przypuszczalnie wzrostem wydajności) bez wpływania na to jak użytkownik współdziała z obiektami klasy <tt>Test</tt>. Ten przykład jest oczywiście zbyt prosty by był użyteczny; korzyści z metod kontroli dostępu staną się bardziej widoczne tylko wtedy, gdy zaczniemy tworzyć bardziej skomplikowane i interesujące klasy.
Linia 89:
==== Modyfikatory przed definicjami metod ====
 
<sourcesyntaxhighlight lang="ruby">
class Test
public # każda metoda (poza initialize, która jest prywatna) jest domyślnie publiczna
Linia 112:
end
end
</syntaxhighlight>
</source>
 
Jak widzimy, modyfikatory dostępu (<tt>private</tt>, <tt>protected</tt>, <tt>public</tt>) występują tu przed definicjami metod.
Linia 120:
Identyczny efekt (z tym, że dostęp będzie nadawany dynamicznie) można uzyskać stosując modyfikatory oraz nazwy metod jako ''symbole''. Co to są symbole powiemy dokładnie w [[Ruby/Symbole|rozdziale o symbolach]].
 
<sourcesyntaxhighlight lang="ruby">
class Test
def pub_met1
Linia 141:
protected :prot_met1, :prot_met2
end
</syntaxhighlight>
</source>
 
Nazwy metod po modyfikatorach poprzedzone są dwukropkami (<tt>:</tt>) - tak właśnie oznaczamy symbole. Ale czym są owe symbole? Dowiedzmy się!