“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>

`g` 객체가 만들어진 이후에는 “Pat”이란 이름을 기억합니다. 직접 이름을 접근할 수 있냐구요?

<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>

보다시피 가능하지 않습니다.

## 객체 들여다보기

객체 변수는 객체 안에 숨겨져 있습니다. 사실 객체 변수가 그렇게 꽁꽁 숨겨져 있는 것은 아니지만, Ruby는 기본적으로 데이터를
숨겨두는 객체지향 방식을 따르고 있습니다. “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>

메서드가 상당히 많은 것을 알 수 있습니다. 우리가 정의한 메서드는 2개에 불과한데
어떻게 된 것일까요? 위의 목록은 “Greeter” 객체들의 메서드뿐만 아니라 **모든**
상속된 메서드도 포함하고 있기 때문입니다. `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>

우리의 “greeter” 객체가 어떤 메서드에 응답하는지를 개별적으로 확인하는 것도 가능합니다.

<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>

즉, `say_hi`라는 이름의 메서드를 가지고 있고 `to_s`(어떤 객체를 문자열로 변환하는
메서드로 모든 객체가 가지고 있습니다.)라는 이름의 메서드도 가지고 있지만,
`name`이란 이름의 메서드에 응답하지는 않습니다.

## 클래스 정의 변경하기-늦었다고 생각할 때가 가장 빠른 때죠

만약 "name"의 내용을 확인하고 또 변경하고 싶다면 어떻게 해야 할까요?
Ruby는 객체 변수를 접근하게 해주는 편리한 방법을 제공하고 있습니다.

<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>

Ruby에서는 클래스를 언제나 열어서 정의를 변경할 수 있습니다.
이 변경사항은 이미 존재하고 있는 객체에도 영향을 줄 수 있습니다.
새로운 객체를 만들어서 `@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>

`attr_accessor`은 두 개의 메서드를 새로 정의해줍니다. `name`은 인스턴스 변수의
값에 접근하기 위한 것이고 `name=`은 객체변수의 값을 변경하기 위한 것입니다.

## Mega Greeter

greeter는 시시하게도 한 번에 한 명밖에 처리하지 못합니다. 이번에는 온세상, 한 사람,
혹은 여러 명의 사람에게 인사를 할 수 있는 “MegaGreeter”를 한번 만들어 보면 어떨까요?

이번에는 IRB Ruby 인터랙티브 해석기를 사용하는 대신에 파일에 코드를 작성해봅시다.

IRB에서 빠져나오기 위해서는 “quit” 또는 “exit”이라고 입력하거나 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"># Change name to be "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"># Change the name to an array of names</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"># Change to 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>

위의 파일을 “ri20min.rb”로 저장을 하고, “ruby ri20min.rb”라고 입력해서 실행을 시키면,
다음과 같은 결과가 나올 것입니다.

<figure class="highlight"><pre><code class="language-irb" data-lang="irb"><span class="go">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!
</span><span class="c">...
...</span></code></pre></figure>

마지막 예제에는 새로운 내용들이 많으므로 [다음에서 좀 더 자세히 살펴보도록 합시다.](../4/)
