제가 IDL과 관련하여 자주 들어가보는 웹사이트들 중, IDL의 본사인 EXELIS의 스탭들 중 한 명인 Mark Piper의 블로그가 있습니다. 괜찮은 팁들이 종종 올라오는 편이라 항상 눈여겨보는데 최근에 올라왔던 내용들 중 여러분과 공유하면 좋을 것 같은 내용이 눈에 띄어서 제가 대충 각색하여 여기도 올려봅니다.
외부 IDL 라이브러리의 코드들을 받아서 사용하다보면 코드의 맨 앞부분에 COMPILE_OPT라는 명령이 사용된 경우들이 간혹 보이는 경우가 있습니다. 도대체 무슨 목적으로 사용되는 명령인지 궁금한 경우가 저도 많았는데, 사실 이 명령은 IDL이 프로시저나 함수들을 컴파일하는데 있어서 가정하는 몇몇 기본적인 설정들을 인위적으로 변경하는 역할을 합니다. 이렇게만 표현하면 좀 어렵게 느껴질 수도 있는데 내막을 들여다보면 그리 거창한 것은 아닙니다. 일단 이 명령의 사용문법은 다음과 같이 명령 바로 뒤에 최소 한 개의 인자들이 붙습니다.
COMPILE_OPT opt1, [opt2, opt3, ...]
IDL 도움말에서 찾아보면 인자들이 어떤 것들이 가능한지 목록이 나옵니다. 여기서는 가장 흔하게 쓰이는 두 가지 인자만 살펴보겠습니다. 첫번째는 DEFINT32라는 인자입니다. 즉 다음과 같이 선언하는 경우입니다.
COMPILE_OPT DEFINT32
이러한 문구를 특정 프로시저나 함수의 맨 앞부분에 명시해주기도 하고, 그냥 커맨드 입력창에서 사용할 수도 있습니다. 어쨌든 이러한 명령을 실행해주게 되면, 그 뒤부터는 어떤 정수든 무조건 4바이트의 Long Integer로 인식합니다. 원래는 2바이트의 일반 Integer로 인식하는 것이 IDL의 기본설정인데, 이를 바꾸는 것입니다. 그래서 이러한 명령을 실행하기 전 IDL의 기본설정을 따르는 경우라면 30000+10000이라는 정수연산의 결과는 다음과 같이 나옵니다.
IDL> PRINT, 30000+10000
-25536
그래서 32767이 넘어가는 정수를 다룰 경우에는 반드시 L이라는 문자를 숫자뒤에 붙여서 Long Integer로 인식을 시켜줘야만 했죠.
IDL> PRINT, 30000L+10000L
40000
하지만 COMPILE_OPT를 위와 같이 실행한 후에는 굳이 L을 붙여서 Long Integer임을 일일이 명시할 필요가 없습니다.
IDL> COMPILE_OPT DEFINT32
IDL> PRINT, 30000+10000
40000
DEFINT32라는 것이 정수(Integer)를 무조건 32비트(4바이트)로 인식하라는 뜻입니다. 그래서 어떤 프로그램 코드내에서 이러한 선언을 앞부분에서 해주면, 그 프로그램내에서는 정수값들을 무조건 4바이트로 인식하게 됩니다. 코딩을 하는데 있어서 이러한 설정이 꽤 편하게 느껴질 부분이 분명 있을겁니다.
그리고 두번째로 설명할 인자는 STRICTARR입니다. 이러한 인자를 사용하여 다음과 같이 COMPILE_OPT를 실행합니다.
COMPILE_OPT STRICTARR
이러한 명령이 실행된 후에는 어떤 배열의 인덱스를 명시하는데 있어서 ()를 사용할 수 없게 됩니다. 원래 IDL에서 배열의 인덱스를 명시할 때에는 (), []가 모두 사용 가능합니다. 즉 원래는 다음과 같이 됩니다.
IDL> a = INDGEN(100)
IDL> PRINT, a[50]
50
IDL> PRINT, a(50)
50
그런데 위와 같은 COMPILE_OPT 명령이 실행된 후에는 []는 여전히 사용 가능하지만, ()는 사용 불가가 됩니다.
IDL> a = INDGEN(100)
IDL> PRINT, a[50]
50
IDL> PRINT, a(50)
% Attempt to call undefined procedure/function: 'A'
즉, 이와 같이 ()를 사용하면 에러가 납니다. 정확히 얘기하면 'a'를 배열로 인식하지않고 함수로만 인식하려고 하게 됩니다. 사실 IDL의 기본설정상으로는 함수(Function)를 사용할 때 인자들은 모두 ()안에 들어가게 되어 있습니다. 그런데 배열의 인덱스를 명시할 때에도 ()를 사용할 수 있게 되어있기 때문에 이러한 부분이 혼동을 일으킬 여지가 종종 있습니다. 원래 IDL은 이와 같은 상황이 올 경우, 먼저 'a'라는 이름의 함수가 존재하는가를 먼저 체크합니다. 만약 존재한다면 ()의 숫자를 그 함수의 인자로 인식하게 됩니다. 그러한 함수가 존재하지 않을 경우에만 'a'를 배열을 간주하고 작업을 진행합니다. 따라서 우연치않게 동일한 이름의 배열과 함수가 함께 존재할 경우, 전혀 의도하지않던 결과가 나올 위험성이 있습니다.
이러한 이유로 저같은 경우도 꽤 오래전부터 배열의 인덱스를 명시할 때에는 ()를 안쓰고 무조건 []을 써오고 있습니다. 하지만, 이 STRICARR 옵션은 굳이 저처럼 습관화된 프로그래머가 아니더라도 배열의 인덱스를 ()로 사용하지 못하게끔 강제해주는 역할을 합니다. 이러한 옵션이 활성화된 상태라면 IDL은 ()를 만날 때 'a'를 무조건 함수로만 간주합니다. 배열일 가능성은 아예 배제해버리는 것이죠. 코딩에 있어서 쓸데없는 혼란의 가능성을 사전에 없애버리는 역할을 합니다.
그래서 COMPILE_OPT에서 가장 일반적으로 많이 사용되는 두가지 옵션인자를 이와 같이 소개해 보았습니다. 두 인자를 모두 사용하려면 다음과 같이 두 인자를 차례로 써주면 됩니다.
COMPILE_OPT DEFINT32, STRICTARR
하지만 다음과 같이 IDL2라는 인자를 사용하면 위의 두 인자를 모두 쓴 것과 같습니다.
COMPILE_OPT IDL2
그래서 이와 같이 사용하는 경우가 더 많습니다. 아마 이러한 문구는 외부의 루틴들을 받아서 사용하는 경우가 많은 IDL 유저들은 그 루틴안에서 종종 보게 될 것입니다. 이러한 문구에 이러한 의미가 있었다는 것을 알아두면 그 루틴의 내용을 해석하는데 있어 나름 도움이 되리라 생각됩니다.
좀 더 관심있으신 분들은 Mark Piper의 블로그에 있는 원문을 보시거나(여기), IDL 도움말에서 COMPILE_OPT로 검색하셔서 그 내용도 한번 들여다 보시기 바랍니다.
'IDL > Programming' 카테고리의 다른 글
| 누적에 의한 배열 생성법 (0) | 2012.07.08 |
|---|---|
| 배열 합치기 (0) | 2012.05.04 |
| 키워드(keyword)와 인자(argument)에 관하여 (0) | 2012.01.13 |
| _EXTRA라는 키워드에 관하여 (0) | 2012.01.09 |
| 날짜 기반의 파일명 다루기 (0) | 2011.09.20 |