본문 바로가기

Development

루비가 쿨한 이유 2 - 블록

 

  • 이글은 황대산님의 블로그에서 복사한 글입니다.

 

[참고: 이 글은 루비가 쿨한 이유 1 - irb에 이어지는 시리즈임.]

블록을 처음 접한 사람은 조금 당황하게 마련이다. 자바나 C 등의 기존 언어에서는 전혀 볼 수 없었던 기능이기 때문이다. 조금 새롭겠지만 정말로 강력하고 편리한 기능이므로 심호흡을 가다듬고 꼭 읽어보시길.

프로그래밍을 하다보면 배열의 내용물을 차례차례 하나씩 처리해야 하는 경우가 늘상 있다. 이런 경우에 자바와 같은 언어에서는 다음처럼 for 루프를 쓰는게 보통이다.

import java.util.*;

class PrintArray {
public static void main(String[] argv) {
String[] arr = {"mike", "nancy", "john", "cathy"};

for (int i=0; i<arr.length; i++) {
System.out.println(arr[i].toUpperCase());
}
}
}

인덱스 변수를 따로 선언해서 써야 하는게 엘러건트하지 않기 때문에, 이터레이터(Iterator)를 쓰기도 한다.

import java.util.*;

class PrintArray {
public static void main(String[] argv) {
Iterator it = Arrays.asList({"mike", "nancy", "john", "cathy"}).iterator();

while (it.hasNext()) {
System.out.println(it.next().toUpperCase());
}
}
}

루비에서는 이렇게 한다.

["mike", "nancy", "john", "cathy"].each {|name| puts name.upcase}

여기서 { |name| puts name.upcase } 부분이 바로 블록이다. 배열의 each라는 메소드에 이 코드를 넘겨주면, each가 배열의 내용물을 차례차례 하나씩 거쳐가면서, 블록을 호출하게 된다. 즉 루비에서는 변수만 인자로 넘겨주는 것이 아니라, 실행할 수 있는 프로그램 코드를 인자로 넘겨주는 것도 가능한 것이다.

블록은 C의 함수 포인터와도 비슷한데 정확히는 클로저라는 개념이다. 이전까지는 Lisp이나 Smalltalk에서 주로 쓰이던 기능이라는 정도만 알아 두자. 그럼 블록을 사용하는 예를 몇 개 더 보도록 하자.

배열의 내용물을 하나씩 처리(문자열을 대문자로 변환)해서, 새로운 배열을 만드는 경우:

c:\> irb --simple-prompt
>> ["mike", "nancy", "john", "cathy"].map {|name| name.upcase}
=> ["MIKE", "NANCY", "JOHN", "CATHY"]

배열의 내용물 중에서 특정 조건(문자열에 "y"가 포함된 경우)을 만족시키는 내용물만 추려내는 경우:

>> ["mike", "nancy", "john", "cathy"].find_all {|name| name.include?("y")}
=> ["nancy", "cathy"]

배열의 내용물 전체가 특정 조건(짝수)을 만족시키는지 테스트하는 경우:

>> [2, 10, 8, 26, 32].all? {|num| num%2 == 0}
=> true

정말 엘러건트하지 않은가. 여기서 다룬 것은 블록의 가장 초보적인 예일 뿐이다. map, find_all, all? 같은 메소드는 모두 루비의 일반 메소드이다. 루비 프로그래머는 얼마든지 블록을 인자로 받는 새로운 메소드를 정의해서 사용할 수 있다.

이제 망설이지 말고 어서 루비를 설치해서 사용해 보자.

관련글: 루비가 쿨한 이유 3 - 해시

 

이 글은 스프링노트에서 작성되었습니다.

'Development' 카테고리의 다른 글

함수형 프로그래밍 1 - 함수 합성  (0) 2008.02.07
루비가 쿨한 이유 3 - 해시  (0) 2008.02.07
루비가 쿨한 이유 1 - irb  (0) 2008.02.07
3. 루비 설치하기  (0) 2008.02.07
2. 다른 언어와의 비교  (0) 2008.02.07