Utwórzmy teraz obiekt klasy Greeter:

<figure class="highlight"><pre><code class="language-irb" data-lang="irb"><span class="gp">irb(main):035:0&gt;</span><span class="w"> </span><span class="n">g</span> <span class="o">=</span> <span class="no">Greeter</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="s2">"Pat"</span><span class="p">)</span>
<span class="gp">=&gt; #&lt;Greeter:0x16cac @name="Pat"&gt;</span><span class="w">
</span><span class="gp">irb(main):036:0&gt;</span><span class="w"> </span><span class="n">g</span><span class="p">.</span><span class="nf">say_hi</span>
<span class="go">Hi Pat!
</span><span class="p">=&gt;</span> <span class="kp">nil</span>
<span class="gp">irb(main):037:0&gt;</span><span class="w"> </span><span class="n">g</span><span class="p">.</span><span class="nf">say_bye</span>
<span class="go">Bye Pat, come back soon.
</span><span class="p">=&gt;</span> <span class="kp">nil</span></code></pre></figure>

Gdy obiekt `g` jest utworzony, zapamiętuje on imię jako Pat. Hmm, co
jeśli chcielibyśmy dostać się bezpośrednio do imienia ?

<figure class="highlight"><pre><code class="language-irb" data-lang="irb"><span class="gp">irb(main):038:0&gt;</span><span class="w"> </span><span class="n">g</span><span class="o">.</span><span class="vi">@name</span>
<span class="gr">SyntaxError: compile error
(irb):52: syntax error
        from (irb):52</span></code></pre></figure>

Niestety, nie możemy tak zrobić.

## Pod Skórą Obiektu

Zmienne instancji są ukryte wewnątrz obiektu. Nie są ukryte jakoś bardzo
głęboko, zobaczysz je kiedy zbadasz bliżej obiekt. Isnieją inne metody
dostępu do zmiennych instancji, ale Ruby używa sprawdzonego, obiektowego
podejścia “trzymania danych w pewien sposób ukrytych”.

Więc jakie to metody istnieją dla obiektów klasy Greeter?

<figure class="highlight"><pre><code class="language-irb" data-lang="irb"><span class="gp">irb(main):039:0&gt;</span><span class="w"> </span><span class="no">Greeter</span><span class="p">.</span><span class="nf">instance_methods</span>
<span class="p">=&gt;</span> <span class="p">[</span><span class="s2">"method"</span><span class="p">,</span> <span class="s2">"send"</span><span class="p">,</span> <span class="s2">"object_id"</span><span class="p">,</span> <span class="s2">"singleton_methods"</span><span class="p">,</span>
    <span class="s2">"__send__"</span><span class="p">,</span> <span class="s2">"equal?"</span><span class="p">,</span> <span class="s2">"taint"</span><span class="p">,</span> <span class="s2">"frozen?"</span><span class="p">,</span>
    <span class="s2">"instance_variable_get"</span><span class="p">,</span> <span class="s2">"kind_of?"</span><span class="p">,</span> <span class="s2">"to_a"</span><span class="p">,</span>
    <span class="s2">"instance_eval"</span><span class="p">,</span> <span class="s2">"type"</span><span class="p">,</span> <span class="s2">"protected_methods"</span><span class="p">,</span> <span class="s2">"extend"</span><span class="p">,</span>
    <span class="s2">"eql?"</span><span class="p">,</span> <span class="s2">"display"</span><span class="p">,</span> <span class="s2">"instance_variable_set"</span><span class="p">,</span> <span class="s2">"hash"</span><span class="p">,</span>
    <span class="s2">"is_a?"</span><span class="p">,</span> <span class="s2">"to_s"</span><span class="p">,</span> <span class="s2">"class"</span><span class="p">,</span> <span class="s2">"tainted?"</span><span class="p">,</span> <span class="s2">"private_methods"</span><span class="p">,</span>
    <span class="s2">"untaint"</span><span class="p">,</span> <span class="s2">"say_hi"</span><span class="p">,</span> <span class="s2">"id"</span><span class="p">,</span> <span class="s2">"inspect"</span><span class="p">,</span> <span class="s2">"=="</span><span class="p">,</span> <span class="s2">"==="</span><span class="p">,</span>
    <span class="s2">"clone"</span><span class="p">,</span> <span class="s2">"public_methods"</span><span class="p">,</span> <span class="s2">"respond_to?"</span><span class="p">,</span> <span class="s2">"freeze"</span><span class="p">,</span>
    <span class="s2">"say_bye"</span><span class="p">,</span> <span class="s2">"__id__"</span><span class="p">,</span> <span class="s2">"=~"</span><span class="p">,</span> <span class="s2">"methods"</span><span class="p">,</span> <span class="s2">"nil?"</span><span class="p">,</span> <span class="s2">"dup"</span><span class="p">,</span>
    <span class="s2">"instance_variables"</span><span class="p">,</span> <span class="s2">"instance_of?"</span><span class="p">]</span></code></pre></figure>

Dużo metod. My zdefiniowaliśmy tylko dwie metody. Co tutaj się dzieje?
No coż, to są **wszystkie** metody obiektów klas Greeter, kompletna
lista, wliczając w to metody zdefiniowane w klasach nadrzędnych. Jeśli
chcemy wyświetlić tylko metody zdefiniowane w klasie Greeter, możemy
wskazać, że nie chcemy wyświetlać metod zdefiniowanych w klasach
nadrzędnych poprzez przekazanie parametru `false`.

<figure class="highlight"><pre><code class="language-irb" data-lang="irb"><span class="gp">irb(main):040:0&gt;</span><span class="w"> </span><span class="no">Greeter</span><span class="p">.</span><span class="nf">instance_methods</span><span class="p">(</span><span class="kp">false</span><span class="p">)</span>
<span class="p">=&gt;</span> <span class="p">[</span><span class="s2">"say_bye"</span><span class="p">,</span> <span class="s2">"say_hi"</span><span class="p">]</span></code></pre></figure>

Zobaczmy więc, na jakie metody nasz obiekt odpowiada (responds\_to):

<figure class="highlight"><pre><code class="language-irb" data-lang="irb"><span class="gp">irb(main):041:0&gt;</span><span class="w"> </span><span class="n">g</span><span class="p">.</span><span class="nf">respond_to?</span><span class="p">(</span><span class="s2">"name"</span><span class="p">)</span>
<span class="p">=&gt;</span> <span class="kp">false</span>
<span class="gp">irb(main):042:0&gt;</span><span class="w"> </span><span class="n">g</span><span class="p">.</span><span class="nf">respond_to?</span><span class="p">(</span><span class="s2">"say_hi"</span><span class="p">)</span>
<span class="p">=&gt;</span> <span class="kp">true</span>
<span class="gp">irb(main):043:0&gt;</span><span class="w"> </span><span class="n">g</span><span class="p">.</span><span class="nf">respond_to?</span><span class="p">(</span><span class="s2">"to_s"</span><span class="p">)</span>
<span class="p">=&gt;</span> <span class="kp">true</span></code></pre></figure>

Rozumie więc `say_hi`, oraz `to_s` (oznaczającą zamienienie czegoś w
stringa, metoda która jest zdefiniowana domyślnie dla każdego obiektu),
ale nie wie nic o metodzie `name`.

## Zmienianie Klas—Na To Nigdy Nie Jest Za Późno

Co jeśli chielibyśmy wyświetlić albo zmienić imię (name)? Ruby zapewnia
nam łatwy dostępn do zmiennych obiektu.

<figure class="highlight"><pre><code class="language-irb" data-lang="irb"><span class="gp">irb(main):044:0&gt;</span><span class="w"> </span><span class="k">class</span> <span class="nc">Greeter</span>
<span class="gp">irb(main):045:1&gt;</span><span class="w">   </span><span class="nb">attr_accessor</span> <span class="ss">:name</span>
<span class="gp">irb(main):046:1&gt;</span><span class="w"> </span><span class="k">end</span>
<span class="p">=&gt;</span> <span class="p">[</span><span class="ss">:name</span><span class="p">,</span> <span class="ss">:name</span><span class="o">=</span><span class="p">]</span></code></pre></figure>

W Rubim możesz ponownie otworzyć klasę i zmodyfikować ją. To nie zmienia
żadnych obiektów, które juz isnieją, ale zmienia obiekty, które dopiero
powstaną. Utwórzmy więc nowy obiekt i pobawmy się jego właściwością
`@name`.

<figure class="highlight"><pre><code class="language-irb" data-lang="irb"><span class="gp">irb(main):047:0&gt;</span><span class="w"> </span><span class="n">g</span> <span class="o">=</span> <span class="no">Greeter</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="s2">"Andy"</span><span class="p">)</span>
<span class="gp">=&gt; #&lt;Greeter:0x3c9b0 @name="Andy"&gt;</span><span class="w">
</span><span class="gp">irb(main):048:0&gt;</span><span class="w"> </span><span class="n">g</span><span class="p">.</span><span class="nf">respond_to?</span><span class="p">(</span><span class="s2">"name"</span><span class="p">)</span>
<span class="p">=&gt;</span> <span class="kp">true</span>
<span class="gp">irb(main):049:0&gt;</span><span class="w"> </span><span class="n">g</span><span class="p">.</span><span class="nf">respond_to?</span><span class="p">(</span><span class="s2">"name="</span><span class="p">)</span>
<span class="p">=&gt;</span> <span class="kp">true</span>
<span class="gp">irb(main):050:0&gt;</span><span class="w"> </span><span class="n">g</span><span class="p">.</span><span class="nf">say_hi</span>
<span class="go">Hi Andy!
</span><span class="p">=&gt;</span> <span class="kp">nil</span>
<span class="gp">irb(main):051:0&gt;</span><span class="w"> </span><span class="n">g</span><span class="p">.</span><span class="nf">name</span><span class="o">=</span><span class="s2">"Betty"</span>
<span class="p">=&gt;</span> <span class="s2">"Betty"</span>
<span class="gp">irb(main):052:0&gt;</span><span class="w"> </span><span class="n">g</span>
<span class="gp">=&gt; #&lt;Greeter:0x3c9b0 @name="Betty"&gt;</span><span class="w">
</span><span class="gp">irb(main):053:0&gt;</span><span class="w"> </span><span class="n">g</span><span class="p">.</span><span class="nf">name</span>
<span class="p">=&gt;</span> <span class="s2">"Betty"</span>
<span class="gp">irb(main):054:0&gt;</span><span class="w"> </span><span class="n">g</span><span class="p">.</span><span class="nf">say_hi</span>
<span class="go">Hi Betty!
</span><span class="p">=&gt;</span> <span class="kp">nil</span></code></pre></figure>

Użycie `attr_accessor` zdefiniowało dwie nowe metody dla nas, `name` aby
odczytać wartość oraz `name=` aby ją ustawić.

## Witanie Wszystkiego, MegaGreeter Nie Opuszcza Niczego!

Nasz witający obiekt nie jest bardzo interesujący, może on zajmować się
tylko jedną osobą naraz. Co jeśli mielibyśmy pewien rodzaj
MegaGreeter’a, który mógłby witać albo cały świat, jedną osobę albo całą
listę osób ?

Napiszmy go tym razem w pliku a nie w interaktywnej konsoli IRB’a.

Aby wyjść z IRB’a wpisz “quit”, “exit” albo po prostu naciśnij
Control-D.

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="c1">#!/usr/bin/env ruby</span>

<span class="k">class</span> <span class="nc">MegaGreeter</span>
  <span class="nb">attr_accessor</span> <span class="ss">:names</span>

  <span class="c1"># Create the object</span>
  <span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">names</span> <span class="o">=</span> <span class="s2">"World"</span><span class="p">)</span>
    <span class="vi">@names</span> <span class="o">=</span> <span class="n">names</span>
  <span class="k">end</span>

  <span class="c1"># Say hi to everybody</span>
  <span class="k">def</span> <span class="nf">say_hi</span>
    <span class="k">if</span> <span class="vi">@names</span><span class="p">.</span><span class="nf">nil?</span>
      <span class="nb">puts</span> <span class="s2">"..."</span>
    <span class="k">elsif</span> <span class="vi">@names</span><span class="p">.</span><span class="nf">respond_to?</span><span class="p">(</span><span class="s2">"each"</span><span class="p">)</span>
      <span class="c1"># @names is a list of some kind, iterate!</span>
      <span class="vi">@names</span><span class="p">.</span><span class="nf">each</span> <span class="k">do</span> <span class="o">|</span><span class="nb">name</span><span class="o">|</span>
        <span class="nb">puts</span> <span class="s2">"Hello </span><span class="si">#{</span><span class="nb">name</span><span class="si">}</span><span class="s2">!"</span>
      <span class="k">end</span>
    <span class="k">else</span>
      <span class="nb">puts</span> <span class="s2">"Hello </span><span class="si">#{</span><span class="vi">@names</span><span class="si">}</span><span class="s2">!"</span>
    <span class="k">end</span>
  <span class="k">end</span>

  <span class="c1"># Say bye to everybody</span>
  <span class="k">def</span> <span class="nf">say_bye</span>
    <span class="k">if</span> <span class="vi">@names</span><span class="p">.</span><span class="nf">nil?</span>
      <span class="nb">puts</span> <span class="s2">"..."</span>
    <span class="k">elsif</span> <span class="vi">@names</span><span class="p">.</span><span class="nf">respond_to?</span><span class="p">(</span><span class="s2">"join"</span><span class="p">)</span>
      <span class="c1"># Join the list elements with commas</span>
      <span class="nb">puts</span> <span class="s2">"Goodbye </span><span class="si">#{</span><span class="vi">@names</span><span class="p">.</span><span class="nf">join</span><span class="p">(</span><span class="s2">", "</span><span class="p">)</span><span class="si">}</span><span class="s2">.  Come back soon!"</span>
    <span class="k">else</span>
      <span class="nb">puts</span> <span class="s2">"Goodbye </span><span class="si">#{</span><span class="vi">@names</span><span class="si">}</span><span class="s2">.  Come back soon!"</span>
    <span class="k">end</span>
  <span class="k">end</span>

<span class="k">end</span>


<span class="k">if</span> <span class="kp">__FILE__</span> <span class="o">==</span> <span class="vg">$0</span>
  <span class="n">mg</span> <span class="o">=</span> <span class="no">MegaGreeter</span><span class="p">.</span><span class="nf">new</span>
  <span class="n">mg</span><span class="p">.</span><span class="nf">say_hi</span>
  <span class="n">mg</span><span class="p">.</span><span class="nf">say_bye</span>

  <span class="c1"># Zmień imię na "Zeke"</span>
  <span class="n">mg</span><span class="p">.</span><span class="nf">names</span> <span class="o">=</span> <span class="s2">"Zeke"</span>
  <span class="n">mg</span><span class="p">.</span><span class="nf">say_hi</span>
  <span class="n">mg</span><span class="p">.</span><span class="nf">say_bye</span>

  <span class="c1"># Zmień imię na tablicę imion</span>
  <span class="n">mg</span><span class="p">.</span><span class="nf">names</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"Albert"</span><span class="p">,</span> <span class="s2">"Brenda"</span><span class="p">,</span> <span class="s2">"Charles"</span><span class="p">,</span>
    <span class="s2">"Dave"</span><span class="p">,</span> <span class="s2">"Engelbert"</span><span class="p">]</span>
  <span class="n">mg</span><span class="p">.</span><span class="nf">say_hi</span>
  <span class="n">mg</span><span class="p">.</span><span class="nf">say_bye</span>

  <span class="c1"># Zmień imię na nil</span>
  <span class="n">mg</span><span class="p">.</span><span class="nf">names</span> <span class="o">=</span> <span class="kp">nil</span>
  <span class="n">mg</span><span class="p">.</span><span class="nf">say_hi</span>
  <span class="n">mg</span><span class="p">.</span><span class="nf">say_bye</span>
<span class="k">end</span></code></pre></figure>

Zapisz ten plik pod nazwą “ri20min.rb”, i uruchom go wpisując “ruby
ri20min.rb”. Wynik poniżej:

    Hello World!
    Goodbye World.  Come back soon!
    Hello Zeke!
    Goodbye Zeke.  Come back soon!
    Hello Albert!
    Hello Brenda!
    Hello Charles!
    Hello Dave!
    Hello Engelbert!
    Goodbye Albert, Brenda, Charles, Dave, Engelbert.  Come
    back soon!
    ...
    ...
{: .code}

W powyższym przykładzie jest sporo nowych rzeczy, [którym możemy się
bliżej przyjrzeć.](../4/)
