Ruby – Calling Methods Dynamically

Tags:

Calling Methods Dynamically

Ruby에서 메소드를 동적으로 호출하는 방법입니다. (virtual 아님..)

typedef struct {
  char *name;
  void (*fptr)();
} Tuple;

Tuple list[]= {
  { "play",   fptr_play },
  { "stop",   fptr_stop },
  { "record", fptr_record },
  { 0, 0 },
};

 ...

 void dispatch(char *cmd) {
  int i = 0;
  for (; list[i].name; i++) {
    if (strncmp(list[i].name,cmd,strlen(cmd)) == 0) {
      list[i].fptr();
      return;
    }
  }
  /* not found */
}

이와같은 dispatch 대신,

commands.send(commandString)

와 같은 방법으로 commandString과 동일한 이름의 메소드를 호출할 수 있습니다. 또 Method 란 클래스도 있습니다. 예를들어,

trane = "John Coltrane".method(:length)
trane.call               # -> 13

이렇게 할 수도 있죠. 좀 정신없긴 한데 Proc 처럼도 쓸 수 있습니다.

def double(a)
  2*a
end

mObj = method(:double)

[1, 3, 5, 7].collect(&mObj)  # -> [2, 6, 10, 14]

eval 도 있습니다.

trane = %q{"John Coltrane".length}
eval trane     # -> 13

eval 의 경우엔 eval을 하는 현재 컨텍스가 적용됩니다. 즉 앞의 예라면, “John Coltrane”라는 String 클래스의 인스턴스안에서 해석하는게 아니므로 String 클래스 내부의 인스턴스 변수는 볼 수 없겠죠. 이때는 binding 을 쓸 수 있습니다.

class CoinSlot
  def initialize(amt=Cents.new(25))
    @amt = amt
    $here = binding
  end
end

a = CoinSlot.new
eval "puts @amt", $here

이쯤되면, orthogonality 가 그리워지는군요;; eval 이 다른 두 방식에 비해 속도가 제일 느립니다.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *