inject:into:를 쓰는곳은 종종있는데 (배열 내부 element의 합을 구하는경우)
그게 어떤식으로 동작하는지에 대해 좀 자세히 쓰여진 내용이 없더군요.
그래서 대체 어떻게 돌아가는지 궁금해지기 시작했습니다.
일단 gnu smalltalk에서 제공되는 예제를 보겠습니다.
(출처 : http://en.wikipedia.org/wiki/GNU_Smalltalk)
#(1 3 5) inject: 10 into: [ :sum :element | sum + element ] "=> 19"
오호라… 이렇게 하니까 19가 나온대요..(물론 printIt으로 보는거라는건 알고 계시겠죠 다들?)
………..
………………..
야.. 내부를 더한다매 왜 19야?
그렇죠.. 10+1+3+5의 결과니깐 저렇게 19가 되는겁니다.
대체 어떤 순서로 동작하길래 저런결과가 나오는걸까요?
그래서 step별로 각 변수의 value를 추적해보면 다음과같은 결과를 얻을 수 있습니다.
1step. sum=10, element=1 2step. sum=11, element=3 3step. sum=14, element=5
오호…. 이것봐라? 기본적으로 inject에 있는 10을 기본값으로 잡고 a=a+b의 식으로 연산을 하고있군요.
그럼 첫째 변수가 inject초기값 그리고 덧셈의 결과값을 항상 가지고있게되고 둘째변수는 배열의 순번에 따라
차례대로 배열 내의 element의 값을 가져오게 되는거같습니다.
(………..사실 변수이름을 생각해보면 간단한거였는데…. 역시 바보는 어쩔수없…-.-)
그럼 대체 어떻가 값을 trace하는가?
승범님이 알려주신대로의 문장을 적어보면 다음과같은 형식이 됩니다.
#(1 3 5) inject: 5 into: [ :sum :element | Transcript show: sum; cr. sum + element ]
이야.. 블록식 안쪽에 바로 넣어버리네요… 사실 저는 printf를 쓰는거라면 익숙합니다만..
어떻게 해야할지 감을 못잡았는데…
(알려주신 승범님 감사합니다)
블록식 안쪽이 연산식이라고 생각하면 당연히 성립했어야 하는건데 생각을 제대로 못했네요.
이런방법으로 블록식 안쪽의 변수값을 step마다 trace해서 Transcript에 찍을 수 있습니다.
물론 sum 외의 i 값도 당연히 trace를 할 수 있겠죠.
이미 짐작하신분이 있다시피 이 경우는 element라는 변수가 Iterator로서의 역할을 하게되는거라고
생각해주시면 되겠습니다. 😀