Ruby Meta Programming
  Dashboard > Ruby > Home > Ruby Meta Programming
Community
  Ruby Log In | Sign Up   View a printable version of the current page.  
Added by 박재성, last edited by 박재성 on 12월 07, 2006  (view change)
Labels: 
(None)

Meta Programming이란?

  • 자바 언어 기반으로 개발을 해온 필자도 Ruby를 접하면서 처음 접근해보는 새로운 개념이다. 이런 관점에서보면 엮이 다양한 언어를 접하는 것이 개발자에게는 큰 도움으로 다가온다. 그런데 이놈은 도대체 뭘까?
  • Meta Programming에 대하여 다루고 있는 문서는 Metaprogramming Ruby 문서이다. 이 문서 하나만 잘 이해해도 Ruby의 Meta Programming에 대하여 이해할 수 있을 것으로 생각한다.
  • Meta Programming에 대한 가장 좋은 정의는 Metaprogramming Ruby에서 다루고 있듯이 "프로그래밍을 위한 프로그래밍"이다. Metadata가 "Data를 위한 Data"인 것처럼 Meta Programming 또한 같은 맥락이다. 우리가 기존의 Programming 방식을 바꿀 수 있는 자유도를 보장해주겠다는 것이다.

Built In MetaProgramming

  • Ruby는 기본적으로 이미 정의되어 있는 Meta Programming이 존재하고 있다. 다음의 예제 코드가 Ruby에서 이미 정의되어 있는 Meta Programming을 사용한 예이다.
attr_reader :id, :age
attr_writer :name
attr_accessor :color

attr_reader

class Module
   def attr_reader (*syms)
     syms.each do |sym|
        class_eval %{def #{sym}
                         @#{sym}
                       end}
     end
   end
end

attr_writer

class Module
   def attr_writer (*syms)
     syms.each do |sym|
        class_eval %{def #{sym}= (val)
                         @#{sym} = val
                       end}
     end
   end
end

Reflection

자바의 Reflection과 같은 기능을 Ruby에서도 가지고 있으며, 이를 Reflection이라고 칭한다. 그러나 Ruby가 가지는 Reflection은 자바 그 이상이다. Ruby의 Reflection을 통하여 할 수 있는 작업

  • what objects it contains
  • the class hierarchy
  • the attributes and methods of objects
  • information on methods
  • Class도 Object이다. Class가 단지 하나만 존재하지만 이 자체도 하나의 Object로 생각해야한다.

Looking at Objects

a = 102.7
b = 95.1
ObjectSpace.each_object(Numeric) { |x| p x }
  • 위 결과값을 추축해 보기 바란다. ObjectSpace는 Numeric Type에 해당하는 모든 Object를 찾아 Iteration을 도는 역할을 한다.
result
95.1
102.7
2.71828182845905
3.14159265358979
2.22044604925031e-16
1.79769313486232e+308
2.2250738585072e-308

Looking Inside Objects

r = 1..10 #Create a Range Object
list = r.methods
p list.length
p list[0..3]
result
68
["collect", "inspect", "send", "all?"]

위 예제에서 보는 바와 같이 모든 Object는 그 자신에 대한 Object 정보에 접근할 수 있는 메써드를 제공한다. 또한 다음과 같은 방법으로 특정 메써드가 존재하는지의 여부를 체크하는 것이 가능하다.

r = "you"
r.respond_to?("frozen?") => true
r.respond_to?(:has_key?) => false
"me".respond_to?("==") => true

Object 정보를 얻어낼 수 있는 다양한 방법

num = 1
p num.object_id => 3
p num.class => Fixnum
p num.kind_of?(Fixnum) => true
p num.kind_of?(Numeric) => true
p num.instance_of?(Fixnum) => true
p num.instance_of?(Numeric) => false
메써드에 인자를 전달하는 경우

위 예제와 같이 메써드에 인자를 전달하는 경우 최신버전(1.8.5)에서는 ()를 하지 않을 경우 다음과 같은 Warning 메세지가 출력된다.

/home/javajigi/Ruby/workspace/study/Reflection.rb:18: warning: parenthesize argument(s) for future version

향후 버전에서는 메써드에 인자를 전달할 때 method(arguments)로 변경될 것이기 때문에 Ruby를 시작할 때부터 위와 같은 개발하도록 습관을 들이는 것이 좋을 것으로 생각한다.

Looking at Classes

참고 문헌

  • Programming Ruby : 이 책의 Chapter 26 Reflection, Objectspace, Distributed Ruby 참조

Site running on a free Atlassian Confluence Open Source Project License granted to JavaJiGi Project. Evaluate Confluence today.
Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.3.1 Build:#643 1월 22, 2007) - Bug/feature request - Contact Administrators