클래스와 속성에 접근하기, 클래스 변수와 메쏘드
이틀째 접어든 루비...

처음에 루비에서 클래스를 만들고 접근해서 사용하다보면... 클래스의 속성에 접근할 방법이 보이질 않는다. 하지만 방법이 없어서가 아니라 다른 랭귀지들과 약간 다르기 때문이다.
class Test
  def x
     10
  end
end
위와같은 클래스가 있다고 가정해보자. 그러면 위의 클래스의 인스턴스에 접근자를 사용해서 x를 호출하면 일반적인(?) 랭귀지와는 달리 뒤에 괄호를 붙이거나 할 필요가 전혀없다. 그냥 그 자체로 호출이 되고 10을 리턴하게 된다. 그러므로 다음과 같은 클래스가 있다면.. x라는 속성에 접근할 방법이 없다. 접근자를 사용해서 x를 호출하면 매쏘드를 찾기 때문이다.
class Test
  def initialize
     @x = 10
  end
end
그러면 이 경우에 있어서 어떻게 해야 할까? 물론 당연한 이야기지만 방법이 제공된다. 그리고 여타 다른 랭귀지보다 프로그래머를 즐겁게 해 줄 방법도 제공된다. 그 방법을 간단히 정리해본다

먼저 간단히 읽기 위해 접근하는 방법이 있다. 다음의 코드처럼 그냥 메쏘드를 만들어주면 된다.

class Test
  def initialize
     @x = 10
  end
  def x
     @x
  end
end
이렇게 하면 접근자를 사용해 x를 호출하면 위 x라는 메쏘드가 호출되어 "@x"값을 리턴한다. 하지만 단지 접근만을 하려는데 위처럼 하는 것은 조금 지나쳐 보인다. 그래서 루비는 다음과 같은 방법을 제공한다.

class Test
   attr_reader :x
   def initialize
     @x = 10
  end
end
위에서 굵게 표시된 부분이 바로 접근을 가능하게 해주는 부분이다. 그렇게 하면 단지 읽기만 접근이 가능하다. 그렇다면 쓰기는 어떻게 해야 할까? 적당히 짐작해볼 수 있듯이 attr_reader에서 reader을 writer로 바꿔주면 된다. 아래는 그 예이다.

class Test
  attr_reader :x
   attr_writer :x
   def initialize
     @x = 10
  end
end

t = Test.new
t.x = 20
puts t.x
당연한 이야기지만 쓰기 접근이 되므로 20이 출력된다. 그런데 여기에 더해 루비는 함수를 만들어서 접근하는 것을 지원한다. 아래가 그 예이다. 아래의 예는 위와 동일한 결과를 준다.

class Test
  attr_reader :x
  def initialize
     @x = 10
  end
   def x=(x)
      @x = x
   end
end

t = Test.new
t.x = 20
puts t.x

그러면 이것은 어디에 쓸까? 처음에 접근을 위한 함수를 만들때와 그 함수를 사용해서 속성을 가공해서 돌려줄 수 있듯이 이 함수 역시 속성에 값을 입력할 때 그 값을 가공해서 저장할 수 있다.

Programming RubyClasses, Objects, and Variables부분에 보면 그 예가 나온다. 음악의 길이를 입력받을 때 내부적으로 초로 처리하더라도 분으로 입력받게 하는 접근자를 만드는 예이다. 이와같이 조금만 생각해보면 위와같은 메쏘드를 이용한 접근이 얼마나 유용한지 알 수 있다.

잠깐!
위의 책, 즉 Programming Ruby를 보면 루비에서는 클래스 내에서 속성과 변수를 구분하고 있다는 것을 알 수 있다. 클래스에서 "@"를 하나 사용하고 있는 것들은 속성이고 두개 사용하고 있는 것들은 변수라고 부른다. 무엇인지 알고 보면 당연히 그래야 한다. 아무튼 그게 뭔지 알아보자. 아래의 예를 보면 그것이 무엇인지를 명확히 알 수 있다

class Test
  @@x=0
  def initialize
     @x=0
  end
  def out
     @x+=1
     @@x+=1
     puts "attribute is #@x, class variable is #@@x"
  end
end

t1 = Test.new
t2 = Test.new
t1.out
t2.out
t1.out
t2.out

위의 예에 대한 결과는 아래와 같다.
attribute is 1, class variable is 1
attribute is 1, class variable is 2
attribute is 2, class variable is 3
attribute is 2, class variable is 4
이 결과를 보면 느낌을 받을 것이다. 바로 루비에서 클래스 변수라고 부르는 것은 자바와 같은 언어에서는 정적 변수라는 것과 같다는 것이다. 인스턴스를 생성해도 그 값은 언제나 유지되고 전체 모든 인스턴스에서 공유된다는 것이다. 그리고 정적 메쏘드는 클래스 메쏘드라고 불린다. 그것을 선언하는 방법과 사용하는 것에 대한 예는 아래와 같다.

class Test
  @@x=0
  def initialize
     @x=0
  end
  def out
     @x+=1
     @@x+=1
     puts "attribute is #@x, class variable is #@@x"
  end
  def Test.outClassVariableX
     puts "class vartiable is #@@x"
  end
end

t1 = Test.new
t2 = Test.new
t1.out
t2.out
t1.out
t2.out
Test.outClassVariableX

결과는 다음과 같다
attribute is 1, class variable is 1
attribute is 1, class variable is 2
attribute is 2, class variable is 3
attribute is 2, class variable is 4
class vartiable is 4

루비는 배워볼 수록 재미있는 언어다... 다음이 기대가 된다..
by 이한길 | 2006/04/24 17:10 | Ruby | 트랙백(1) | 덧글(0)
트랙백 주소 : http://hangulee.egloos.com/tb/6564
☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]
Tracked from variab at 2008/10/18 05:02

제목 : variable life insurance
proscribe lessor bronchi audibly fiend ...more

:         :

:

비공개 덧글



< 이전페이지 다음페이지 >