# Fibonacci series
def fib_upto(n)
n1, n2 = 1, 1
while n1 < n
n1, n2 = n2, n1 + n2
# Let the block do whatever
# it want.
yield n1
end
end
# What to do with the value is stated
# explicitly. In this case, we print the
# value.
fib_upto(20) { |n| puts n }
# Okay, make 'what to do' transparent
# using closure.
def into_arr (arr)
return proc { |n| arr << n }
end
# Pass 'what to do' generator as argument
fib_upto(20, &into_arr(a = []))
puts a.inspect
[/code]
Closure 를 사용해서 "무엇을 해라" 라는 부분을 인자로 넘기게 되면서, fib_upto 가 다른 처리기를 호출하는 것이 아니라, 처리기 (이 경우엔 proc ...)가 fib_upto 의 계산중인 값(n1)을 접근하게 됩니다.
써놓고 보니 명확하지 않은 듯 해서 첨언합니다. 만약 자바였다고 해보죠.
[code lang="java"]
private IValueChangeListener fListener;
public void fibUpTo(int n) {
....
fListener.notify(n1);
...
}
[/code]
여기서의 notify는 n1을 등록되어있는 listener에게 인자로 넘겨줍니다. 그리고 fListener의 초기화는 생성자에서 받거나 addListenr()를 통해 등록하게 됩니다. 그리고 바로 이것이 dependency가 시작되는 부분이 되죠. fibUpTo 는 인자를 가지고 notify 라는 메소드를 호출합니다.
Ruby의 경우에는 외부의 리스너는 인자로 언제든지 변경이 가능합니다. n1을 정하고 나면 블럭에게 처리를 양보(yield)합니다. 그러면 외부의 블럭이 n1을 가지고 처리를 하고 다시 실행을 fib_upto에게 넘기게 됩니다.
Ruby에서 Closure를 사용한 Dependency Injection
Tags:
Leave a Reply