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 이 다른 두 방식에 비해 속도가 제일 느립니다.
Leave a Reply