LazarusCompleteGuide:3.2: Difference between revisions
Onionmixer (talk | contribs) (LCG 3.2 페이지 추가) |
Onionmixer (talk | contribs) (소스코드 수정) |
||
Line 278: | Line 278: | ||
constructor TExample.Create; | constructor TExample.Create; | ||
begin | begin | ||
I <- {the cursor will be placed here ready for you to enter code} | |||
end; | end; | ||
Latest revision as of 15:19, 28 February 2013
IDE에서 이용할 수 있는 프로그래밍 툴
오브젝트 인스펙터
오브젝트 인스펙터는 비주얼 프로그래밍에 중요한 툴이다. 간단한 경우 코드를 쓸 필요 없이 오브젝트 인스펙터를 통한 변경내용만으로도 프로그램을 완료할 수 있다!
소스 코드는 어떠한 내용도 변경되지 않는데 (.pas 또는 .pp 파일) 그렇다면 라자루스는 오브젝트 인스펙터에서 변경된 내용을 어떻게 기억할까? 답은 프로퍼티 변경내용이 폼 클래스에 속하는 .lfm 파일에 (Lazarus form 약자) 저장되기 때문이다. 이는 텍스트 파일로서, 사용자는 라자루스 IDE 외부에서 해당 파일을 쉽게 편집할 수 있다. 하지만 외부에서 파일을 편집하려면 각 항목의 의미를 이해해야 한다. 오브젝트 인스펙터에서 일어난 변경내용은 소스 코드에서 수동으로 코딩될 수 있으므로 광범위한 .lfm 또는 .pas 파일을 선택하는 것은 본인에게 달려 있다. 보통 오브젝트 인스펙터는 소스 에디터 바로 옆에 위치한 화면 좌측에서 찾을 수 있다.
오브젝트 인스펙터의 모양은 Environment ⇒ Options ⇒ Environment ⇒ Object Inspector 에서 설정한 내용의 영향을 받는다. 오브젝트 인스펙터 하단 테두리에 위치한 정보 상자에서 선택 프로퍼티 또는 이벤트에 관한 유용한 정보를 찾을 수 있다.
오브젝트 인스펙터의 최상단 부분은 최근 프로젝트의 오브젝트를 (폼, 데이터 모듈, 컴포넌트) 열거한다. 오브젝트 중 하나를 클릭하면 오브젝트의 프로퍼티와 이벤트를 아래 격자에 표시한다. 격자 모양으로 된 섹션은 4 페이지로 구성된 4개의 탭을 가진다: Properties, Events, Favorites, Restrict. 이용 가능한 공간에 따라 스크롤 하지 않고는 네 가지 탭을 동시에 볼 수 없을지도 모른다. 선택한 위젯 셋에 따라 표시에 차이가 날 수 있다.
Properties 페이지에선 (그림 3.84 참고) published로 선언된 현재 오브젝트의 모든 프로퍼티를 볼 수 있다. Unpublished 프로퍼티는 소스 코드에서 변경되어야 하는데 그 값은 오브젝트 인스펙터에 표시되지 않는다. 격자에 두 열은 헤드(heading)가 없지만 만약 있다면 Property name과 Value일 것이다.
프로퍼티가 컴포넌트의 가시성(visibility)에 영향을 미친다면 오브젝트 인스펙터에서 변경된 내용은 컴포넌트를 포함하는 폼에 즉시 표시될 것이다. 마찬가지로 폼의 변경내용도 오브젝트 인스펙터에 즉시 표시된다. 한 프로젝트에서 변경한 내용이 다른 프로퍼티를 변경시키기도 한다. 폼의 Name 프로퍼티를 변경하였는데 Caption 프로퍼티가 같은 값을 갖는 경우를 예로 들 수 있겠다. 다수의 프로퍼티를 한 번에 변경해야 하는 경우 이러한 의존성을 고려할 필요가 있겠다. 프로퍼티를 변경하려면 특정 값을 클릭해 편집하면 된다. 오브젝트 인스펙터의 변경내용은 Edit ⇒ Undo 로 되돌릴 수 없음을 명심하라. 의심이 갈 때는 이전 값을 기억해둔다.
일부 프로퍼티는 가능한 값의 수가 제한된다. 그러한 프로퍼티들은 Value 열을 클릭하면 그 특성을 표시하며 필드가 콤보상자로 바뀐다. 예를 들어 Boolean 프로퍼티에서는 True 혹은 False 값만 가지는 프로퍼티가 해당되겠다. 이러한 경우 값을 더블 클릭하면 True 에서 False 로, False 에서 True 로 토글한다.
물론 값을 수동으로 덮어쓸 수 있지만 열거형(enumeration)의 경우 원하는 값을 리스트에서 선택하는 편이 더 간단하고 오류가 발생이 덜하다. 단순히 값이 아닌 다른 프로퍼티 또는 긴 문자열을 포함한 문자열도 있다. 그런 경우 사용자는 오브젝트 인스펙터에서 직접 프로퍼티를 변경할 수 없다. 이는 생략부호 [...]가 붙은 버튼의 유무로 인지할 수 있다.
프로퍼티를 변경하기 위해서는 [...] 버튼을 클릭해야 한다. 열리는 에디터는 변경될 프로퍼티의 타입에 따라 다르다.
OK를 클릭하면 사용자가 입력한 문자열이 수락된다.
오브젝트 인스펙터 디스플레이가 화면에서 벗어나지(overcrowded) 않도록 하기 위해 일부 프로퍼티들은 숨김으로 되어 있다. 이러한 프로퍼티들은 프로퍼티 앞에 ▶가 붙어 있는데, 위젯 셋에 따라 ▶ 대신 + 아이콘 등 다른 문자를 이용할 수도 있다.
▶ (또는 +) 기호를 클릭하면 숨은 프로퍼티를 표시한다. 숨김은 여러 개의 중첩 수준으로 펼 수 있다. ▶ (또는 +) 기호를 클릭하고 나면 △ (또는 -) 기호로 바뀌어 아래 프로퍼티들을 접을(collapse) 수 있음을 보여준다. 이러한 프로퍼티들은 약간 들여쓰기가 되어 있어 다른 프로퍼티들로부터 눈에 띄게 구분되어 있다.
Events 페이지는 오브젝트의 모든 이벤트 프로퍼티들을 열거하며, 프로시저가 이미 이벤트에 부착(attach)된 프로퍼티들도 포함한다. 이용 가능한 이벤트는 컴포넌트마다 다양하다.
새 이벤트 프로시저를 생성하거나 기존 프로시저를 이벤트로 부착하는 작업은 매우 쉽다. 이벤트 중 하나를 더블 클릭하면 새 프로시저 본체가 에디터에 생성된다. 예를 들어 TForm1 의 OnClose 이벤트를 더블 클릭하면 폼 유닛의 implementation 섹션에 아래와 같은 프로시저 본체를 쓴다:
procedure TForm1.FormClose(Sender:TObject; var CloseAction:TCloseAction)
begin
end;
당연히 TForm1 의 type 정의에서 메소드 선언 또한 생성된다. 프로그래머는 호출이 올바른지에 대해 전혀 염려할 필요가 없으며 대신 메소드의 내용에 중점을 둘 수 있다. 이번 예제에서 프로그래머는 다음과 같이 자문할 것이다:
"폼이 닫히면 어떤 일이 발생할까?"
Favorites 페이지는 과거에 자주 선택한 Events 와 Properties 를 열거한다. 항목을 다시 변경해야 하는 경우 Favorites 페이지는 Properties 또는 Events 페이지를 검색할 때보다 더 빠르게 목표를 검색하기도 한다.
Restricted 페이지는 다른 위젯 셋마다 다르게 기능하는 프로퍼티들을 열거한다 (예: 위젯 셋마다 다른 제한). 선택된 예제에서는 Mac OS X에서 실행 시 두 가지 프로퍼티를 이용할 수 없다. 라자루스 개발자들은 다양한 위젯 셋의 개발에 영향력이 전혀 없기 때문에 사용자는 앞으로도 그러한 제약이 있을 것으로 추정해야 한다.
소스 코드 에디터
에디터는 IDE의 일부로, 소스 코드 파일이 편집되는 장소이다. 에디터를 생산적으로 사용하기 위해선 에디터의 기능이 방해되는 것이 아니라 도움이 된다는 사실을 사용자들이 발견하는 것이 중요하다 (편집은 소프트웨어 개발에서 중심 업무이므로). 라자루스는 개발을 조장하는 다양한 편집 기능들을 제공할 뿐만 아니라 사용자의 설정(preference)에 일치하도록 트윅(tweak)할 수 있는 무수한 설정들도 제공한다.
에디터는 TSynEdit 컴포넌트를 기반으로 한다 (컴포넌트 팔레트의 SynEdit 페이지에서 찾을 수 있다).
에디터를 오른쪽 마우스로 클릭하여 컨텍스트 메뉴를 표시하거나 Environment ⇒ Options... ⇒ Editor 에서 메뉴를 통해 설정을 변경할 수 있다.
컨텍스트 메뉴 옵션과 메인 메뉴를 통해 접근하는 옵션들 대다수는 중복되므로 사용자는 본인에게 편한 접근 방법을 선택하면 된다.
에디터의 컨텍스트 메뉴
Find Declaration은 소스 코드 내에서 커서에 있는 식별자를 정의하는 장소를 위치시킨다.
Find 는 네 가지 검색 옵션을 제공한다:
- Procedure Jump: 커서는 인터페이스 부에서 현재 프로시저가 정의된 위치로 건너뛴다.
- Find next word occurrence (다음 일치 단어 찾기) 와 Find previous word occurrence (이전 일치 단어 찾기): 이는 이름 자체로 설명이 되겠다.
- Find in files: Find in files 대화창은 커서에 위치한 엔트리를 검색 항목으로 취할 때 열린다.
Insert ToDo 를 이용하면 커서 위치에 ToDo 주석문이 삽입된다. 해당 주석문은 소스 코드 내에서 후에 사용자가 작업을 더 하고자 하는 위치를 표시한다. 의존성 문제를 해결하기 위해 코드를 변경해야 하는 상황을 고려하라. 후에 사용자가 의존성을 변경하고 나면 소스 코드의 해당 부분을 다시 변경해야 한다. ToDo 주석문의 삽입은 사용자가 변경내용을 삭제해야 함을 잊지 않도록 도와준다.
코드에 ToDo 주석문을 삽입하는 것에 더해 Insert ToDo 대화창이 나타나면서 정보를 요청한다. Text 는 주석문의 실제 내용이다.
다른 ToDo들이 다른 우선순위 셋(priorities set)을 가져야 하는 경우, Priority 필드를 이용할 수 있다 (우선순위 표시에 단순한 정수형을 허용하는). 특히 여러 개발자들이 동일한 소스 코드를 작업할 경우 (Owner 필드에) 주석문의 이름을 포함하는 것이 맞다. 사용자는 주석문 또한 분류할 수 있다. 일반적 주석문은 다음과 같은 모양을 할 것이다:
{ TODO 2 -oMichael -cGraphics : Adjust case statement for new compiler version }
자신의 프로젝트에 속하는 ToDo 주석문을 모두 보려면 View ⇒ ToDo List를 선택한다.
Close Page는 현재 유닛을 에디터로부터 제거한다.
Close All Other Pages 는 현재 유닛을 제외하고 에디터의 모든 페이지를 닫는다. 두 종류의 Close 명령 모두 사용자의 작업 영역을 정리한다.
다음 세 가지 옵션은 에디터에 한 번에 하나 이상의 파일을 열 때만 관련된다:
Lock Page, Move to New Window, Clone to New Window.
Lock Page는 해당 에디터가 현재 위치로부터 움직이지 않길 원한다고 라자루스에 알린다. 페이지가 잠긴 상태에서 사용자가 코드 내에 새 위치로 점프를 시도할 경우 (예: 북마크, 선언부 또는 find-in-file 찾기 결과) 라자루스는 목표 위치를 표시하기 위해 동일한 파일의 다른 에디터를 열 것이다. 증분 검색과 단순한 검색/바꾸기 작동은 '점프'로 간주하지 않으므로 '잠긴' 페이지를 스크롤함을 명심하라.
Move to New Window 를 이용하면 열린 소스 코드 파일이 새로 열린 에디터 페이지로 이동한다. 그리고 나면 같은 파일에 대해 두 개의 에디터 페이지를 이용할 수 있다.
Clone to New Window 도 동일한 방식으로 적용되는데 단, 파일은 새로 열린 에디터 창에 복사된다. 이후에 다른 추가 에디터 창을 이용할 수 있는데, 여기서는 원본 에디터에 영향을 미치지 않고 이동 및 크기변경이 가능하다.
여러 개의 에디터 창이 이미 열린 경우 추가 옵션을 이용할 수 있다.
파일은 새 에디터 또는 기존 에디터에서 열 수 있다.
여러 페이지를 열어 두고 열린 유닛의 순서를 분석할 경우, Move Page 를 이용해 현재 유닛의 탭을 좌측이나 우측으로 원하는 위치까지 이동할 수 있다. 탭을 바로 맨 좌측이나 맨 우측 위치로 이동시키는 것도 가능하다. 탭이 수직으로 배열된 경우 '맨 좌측'과 '맨 우측'을 그에 따라 바꿔야 한다.
Open File 은 더 많은 파일을 연다. uses 섹션 내에서 유닛 이름에 커서가 위치한 경우 해당 유닛은 Open file at cursor 로 열 수 있다. 유닛이 패키지의 일부인 경우 Open package<packagename> 옵션이 표시된다. 이를 클릭하면 패키지 파일이 (*.lpk) 패키지 에디터에 열린다.
File Settings는 여러 개의 설정을 포함하는데, 대부분은 에디터 옵션에서 접근할 수 있다:
Read Only: 현재 유닛을 쓰기 보호로 제공한다 (또는 제거한다).
Show Line Numbers: 행 번호를 표시(또는 숨김)한다. 컴파일러는 사용자에게 오류에 행 번호를 매기도록 명령하므로 디버깅 시 시간을 절약해준다.
Unit Information: View→Unit Information을 통해 접근할 때와 동일한 4페이지 대화창을 표시한다.
Highlighter: 여기서는 현재 유닛을 표시하는 데 어떠한 하이라이터를 사용할 것인지 설정할 수 있다 (기본설정: Free Pascal).
Encoding: 문자 인코딩 (기본설정: UTF-8).
문자 인코딩은 소스 코드를 공유하여 다른 컴퓨터에서도 사용해야 하는 경우 특히 중요하다.
Line ending: 행 끝을 자신의 운영체제 기본 값에서 다른 타입으로 변경하도록 해준다.
파일 설정의 변경은 주로 다음 파일 저장 이후에 효과가 나타난다.
컨텍스트 메뉴 훨씬 아래에 보면 전체 파일 또는 텍스트 선택 부분만 인쇄하는 명령이 있다. (인쇄의 작동을 위해선 printers4lazide 패키지를 설치해야 한다)
정보의 자르기, 복사, 붙여넣기를 위한 기본 명령도 있다. 검색 호출(search call)이나 다른 목적을 위해 Copy Filename 을 이용하여 현재 파일의 경로를 클립보드에 위치시킬 수 있다.
물론 북마크를 설정하거나 점프하는 함수들도 이용할 수 있는데, 메인 Search 메뉴에서 찾을 수 있다.
Debug 는 디버거에 대해 6개의 명령을 제공한다:
Toggle breakpoint,
Evaluate/Modify,
Add Watch at Cursor,
Inspect,
Run to Cursor
View Call Stack.
중단점(breakpoint)을 설정하고 나면 한 번의 클릭으로 다시 제거할 수 있다. 디버거는 3.2.5장 디버거 설정에서 상세히 다룬다.
Refactoring을 이용해 소스 코드를 편집하거나 향상시키는 명령을 호출할 수 있다: Complete Code, Enclose Selection, Rename Identifier, Find Identifier Reference, Extract Procedure, Invert Assignment, Show abstract methods (추상 메소드를 발견 시 표시). Show empty methods 는 빈 메소드를 검색하는 대화창을 표시한다. Show unused units 는 사용되지 않은 유닛을 쉽게 제거하는 대화창을 연다. 사용되지 않은 유닛이란 uses 섹션엔 열거되지만 소스 코드 나머지 부분에서 사용되지 않는 유닛을 의미한다.
Options 는 Environment ⇒ Options... ⇒ Editor 를 통해 여는 대화창과 동일한 대화창을 부른다. 해당 대화창의 일부 함수들은 File Settings 에서도 찾을 수 있는데, 행 번호 표시하기/숨기기, 하이라이터 선택을 예로 들 수 있겠다.
에디터에 이용 가능한 옵션들은 선택한 위젯 셋에 따라 어느 정도 다르다. 하지만 문제를 야기할 만큼의 차이는 나지 않는다. 그림 3.95에 예를 소개한다.
페이지 이름의 우측에 위치한 페이지 닫기 [X] 버튼은 Windows에선 이용할 수 없다 (따라서 이 옵션은 Windows에선 소용이 없다). 그렇지만 Windows를 사용하더라도 단축키 ([Ctrl]+[F4]) 또는 컨텍스트 메뉴를 통해 페이지를 닫을 수 있다.
소스 에디터는 'syncron' 편집을 이용해 식별자의 많은 인스턴스를 빠르게 수정할 수 있는 간편한 옵션을 제공한다. 이전에는 식별자를 Search(검색) 하여 Replace (교체) 하는 것이 유일한 방도였다. 소스 코드가 커서 식별자가 자주 사용되는 경우 어느 정도 시간이 소요될 수 있다. 최신 syncron 방법을 이용하면 텍스트의 적절한 부분을 표시한다 ([Ctrl]+[A]로 전체 소스를 선택할 수도 있다). 에디터의 좌측 테두리에는 사용자가 클릭할 수 있는 (또는 [Ctrl]+[J]를 누르는) 작은 아이콘과 함께 펜이 표시된다. 이를 선택하면 syncron 모드를 표시하기 위해 색상을 변경한다. 이후에 마우스 또는 커서를 식별자의 인스턴스로 옮기면 모든 인스턴스를 자동으로 하이라이트 표시한다. 해당 식별자에 대한 모든 변경내용은 자동으로 다른 모든 인스턴스들로 적용된다. 아이콘을 다시 한 번 클릭하면 (또는 [Esc] 키를 누름) syncron 모드가 취소된다.
코드 완성
Edit ⇒ Complete Code 메뉴 옵션 뒤에는 프로그래머들이 엄청난 양의 타이핑 작업하는 수고를 줄이도록 해주는 매우 강력한 라자루스 기능들이 있다. 일부 함수들은 에디터 내 커서 위치에 따라 호출된다.
Class completion
클래스가 쓰인 후 메소드와 프로퍼티가 추가된 경우 Class Completion 기능은 메소드 본체, 프로퍼티 접근 메소드와 변수, private 변수들을 추가할 수 있다. 예를 들어, 아래 새 클래스를 고려해보자:
TExample = class(TObject)
public
constructor Create;
destructor Destroy; override;
end;
이제 커서를 클래스 내 어디든 위치시키고 [Ctrl]+[Shift]+[C]를 누른다. 이는 누락된 메소드 본체를 생성한다. 이제 커서가 첫 메소드 본체로 이동하고 클래스 코드 쓰기가 시작된다. 구현 소스 코드는 아래와 같은 모양일 것이다:
{ TExample }
constructor TExample.Create;
begin
I <- {the cursor will be placed here ready for you to enter code}
end;
destructor TExample.Destroy;
begin
inherited Destroy;
end;
[Ctrl]+[Shift]+[↑]와 [Ctrl]+[Shift]+[↓]를 이용해 메소드의 선언부와 본체 사이로 점프할 수 있다.
inherited Destroy 명령도 라자루스에 추가되었는데, 이 기능은 클래스 정의에서 override 키워드를 찾을 때 항시 실행된다.
여기서 DoSomething 메소드가 추가된다:
TExample = class(TObject)
public
constructor Create;
procedure DoSomething(i: integer);
destructor Destroy; override;
end;
이 때 [Ctrl]+[Shift]+[C] 를 누르면 라자루스는 다음을 추가한다:
procedure TExample.DoSomething(i: Integer);
begin
I <- the cursor will be placed here ready for you to enter code
end;
Create 와 Destroy 사이에 라자루스는 새 메소드 본체를 추가하는데, 클래스 정의에서와 정확히 동일한 순서로 추가된다. 이렇게 메소드 본체들은 개발자가 놓은 순서를 지킨다. 삽입 방법은 Environment ⇒ Options... ⇒ CodeTools ⇒ Code Creation 의 메뉴에서 정의된다.
변수 선언 완성
커서가 identifier, assignment 또는 parameter 위에 있을 때 [Ctrl]+[Shift]+[C] 를 누르면 Identifier :=statement; 명령어에 대한 로컬 변수 정의가 추가된다. 소스 코드에서 아래 프로시저를 찾았다고 가정하자:
procedure TForm1.FormCreate(Sender: TObject);
begin
i := 3;
end;
여기서 커서는 i 위에 또는 바로 뒤에 위치하고, [Ctrl]+[Shift]+[C]를 누른다. 소스 코드는 아래와 같이 바뀔 것이다:
procedure TForm1.FormCreate(Sender: TObject);
var
i: Integer;
begin
i := 3;
end;
Codetools는 식별자 i 가 이미 선언되었는지 테스트한다. 선언되지 않았다면 선언부 var i : Integer; 가 추가된다. 식별자의 타입은 = 기호 뒤의 표현식으로부터 추측된다. 3 과 같은 숫자는 기본 값이 Integer 이다. 또 다른 예제를 들자면 다음과 같다:
type
TWhere = (Behind, Middle, InFront);
procedure TForm1.FormCreate(Sender: TObject);
var
a: array[TWhere] of Char;
begin
for Where := Low(a) to Hi(a) do WriteLn(a[Where]);
end;
커서가 Where 에 위치할 때 [Ctrl]+[Shift]+[C]를 누르면 다음 결과를 얻는다:
procedure TForm1.FormCreate(Sender: TObject);
var
a: array[TWhere] of Char;
Where: TWhere;
begin
for Where := Low(a) to Hi(a) do WriteLn(a[Where]);
end;
아래에 파라미터 완성 예를 들어보겠다:
procedure TForm1.FormPaint(Sender: TObject);
begin
with Canvas do begin
Line(x1, y1, x2, y2);
end;
end;
커서가 x1 에 위치할 때 [Ctrl]+[Shift]+[C]를 누르면, 결과는 다음과 같다:
procedure TForm1.FormPaint(Sender: TObject);
var
x1: integer;
begin
with Canvas do begin
Line(x1, y1, x2, y2);
end;
end
완전히는 아니지만 어느 정도 타이핑을 줄였을 것이다.
프로시저 호출 완성
Source code completion은 프로시저 호출로부터 새 프로시저를 생성하도록 해준다. DoSomething(Width); 명령어를 막 썼다고 가정하자:
procedure SomeProcedure;
var
Width: integer;
begin
Width := 3;
DoSomething(Width);
end;
이제 커서를 DoSomething 위에 위치시키고 [Ctrl]+[Shift]+[C]를 누른다. 결과는 아래와 같은 코드를 추가한다:
procedure DoSomething(aWidth: LongInt);
begin
end;
procedure SomeProcedure;
var
Width: integer;
begin
Width := 3;
DoSomething(Width);
end;
메시지 컴포저
메시지 컴포저(Message Composer)는 메시지를 빠르고 간단하게 생성하도록 돕는 툴이다. 대화창을 수동으로 프로그래밍할 경우 사용자가 올바르지 않은 파라미터를 얻거나 잊어버리는 경우가 종종 있다. 이런 일이 발생하면 매우 번거롭고 대화창 파라미터를 살펴보는 데 또 시간이 소요된다. 메시지 컴포저는 이러한 일이 발생하지 않도록 미연에 방지한다.
라자루스 IDE에서 해당 툴을 이용하기 위해선 messagecomposerpkg 패키지를 설치할 필요가 있다. 아직 설치하지 않았다면 Package ⇒ Install/Uninstall packages... 를 이용한다. 대화창에서 Do not install 리스트를 스크롤하여 messagecomposerpkg 를 위치시킨 후 클릭하면 Install selection button 이 생긴다.
버튼을 클릭 후 Save and rebuild IDE 버튼을 클릭한다. 승인 대화창에서 Continue 버튼을 클릭하여 재빌드된 IDE에 확실히 패키지를 추가할 것이다. 사용자는 Edit ⇒ Message Composer 를 이용하거나 [Ctrl]+[M] 단축키를 이용해 메시지 컴포저를 열 수 있다. 해당 옵션으로 새로 생성된 메시지 대화창은 사용자의 에디터 코드 내에 커서 위치로 삽입된다.
이용 가능한 옵션들은 대부분 이름으로 그 기능을 알 수 있다. 일부 필드들은 특정 대화창 타입을 사용 시에만 가능하므로 필요 없을 땐 비활성화 되어 있다. 최상단 콤보상자는 원하는 대화창 타입을 선택하도록 해주고, 그 다음은 표시하고자 하는 메시지 텍스트, 포함시킬 버튼, (원한다면) 도움말 파일을 위한 엔트리를 선택할 수 있다. Test 버튼을 클릭하면 방금 디자인한 대화창을 미리 볼 수 있다.
원하는 대로 설정되지 않았다면 하나 또는 두 개의 설정을 쉽게 변경하여 변경 효과를 미리보기 한다. OK 버튼을 클릭하면 대화창이 닫히고 올바르게 생성된 코드가 커서에 삽입된다. 마음이 바뀌어 대화창 코드를 삽입하고 싶지 않다면 Cancel 버튼을 선택한다.
그림 3.96의 예제는 (모두 기본설정을 수락 시) 아래와 같은 코드를 생성한다:
if MessageDlg('MsgLabel', mtWarning, [mbOK, mbCancel],0) = mrOK then
디버거 설정
본격적인 개발 환경은 오류의 검사와 제거를 위한 디버거를 필요로 한다. 현재 라자루스는 GNU 디버거, gdb 에 의존한다. 외부 프로그램이기 때문에 모든 플랫폼에 대해 동일한 기능이나 신뢰성을 제공하진 못한다. 중.장기간 사용하다보면 라자루스 내부 디버거도 개발되어 IDE의 잠재력을 최대한 발휘할 것이다.
본 장에서는 라자루스의 다양한 디버거 설정에 관해 설명하고자 한다. 라자루스 위키와 위키에서 참조한 문서들은 디버거를 사용하는 방법을 충분히 설명하고 있으므로 여기서 따로 다루지 않겠다.
프리 파스칼 컴파일러가 gdb에 대해 생성한 정보는 모두 소문자로 되어 있다. 변수를 모니터링할 때 사용자는 이 점을 유념해야 하는데, 보통 파스칼은 변수 이름에 대문자와 소문자를 병행하여 사용하기 때문이다.
GNU 디버거 gdb는 C 프로그래밍의 세계에서 비롯되었기 때문에 string 타입을 이해하지 못한다. 따라서 파스칼 문자열은 두 개의 필드를 가진 레코드로 변환된다: 한 필드는 길이를 포함하고 나머지 필드는 문자의 배열을 포함한다.
또 유념해야 할 한 가지 한계점은 사용자 스스로 작성하는 예외 처리 코드와 관련이 있다. IDE 내에서 프로젝트를 실행할 경우 (디버거와 작업하기 위해) 디버거는 사용자의 예외 처리 코드를 방해한다. 그러한 루틴을 테스트하려면 IDE 외부에서 프로젝트를 시작해야 한다.
IDE의 디버거 구성 설정은 Environment ⇒ Options... 메뉴를 통해 접근한 IDE Options 의 Debugger 섹션에서 찾을 수 있다. 해당 설정은 4 페이지로 구성된다:
General, Event Log, Language Exceptions, OS Exceptions.
General 페이지
General 페이지는 Debugger type and path 섹션으로 시작하며, 작업할 디버거와 그 디버거의 위치를 명시하도록 해주는데, 현재로선 gdb가 해당되겠다. 디버거 타입 콤보상자에는 3가지 옵션이 있다:
- (none): 활성화된 디버거가 없다. Run→Run 을 클릭하면 디버거 없이 현재 프로그램이 실행된다.
- GNU debugger: 기본 설정. gdb 는 라자루스의 외부에 위치하므로 개발자가 알아서 설치해야 한다. 윈도우 인스톨러를 이용하면 gdb가 자동으로 라자루스 설치의 mingw 하위디렉터리에 설치된다. 유닉스 gdb는 보통 구분된 패키지로 이용 가능하다. 라자루스 설치 이전에 gdb가 설치된 경우, IDE는 gdb의 경로를 인식할 것이다. 그렇지 않다면 경로를 수동으로 입력해야 한다.
- GNU debugger through SSH (gdb): 원격 디버깅을 위한 설정이다. SSH 연결에 걸쳐 gdb를 다른 컴퓨터상에서 실행할 수 있다. 이를 위해선 비밀번호 접근이 없는 SSH 연결이 필요하다.
사용자는 Additional search path 필드에서 실행 파일에 의해 디버깅 정보가 저장되는 디렉터리를 더 많이 입력하여 소스 파일을 검색할 수 있다.
해당 설정은 모든 프로젝트에서 유효하다.
프로그램이 중단될 때 메시지를 표시하길 원한다면 이를 Debugger general options 에서 설정 가능하다.
Debugger specific options (depends on type of debugger). 현재 gdb가 유일하게 사용되는 디버거이므로 흥미로운 옵션이 소수에 불과하다. 특히 FPC로 작업 시에는 한 가지 옵션만 있다: OverrideRTLCallingconvention.
위는 기본 값 ccDefault 에서 유지되는 내부 플래그이다. 소프트웨어 예외를 처리하기 위해 라자루스는 이러한 예외들이 트리거되는 장소에서 몇 가지 내부 중지 지점(stop point)를 설정한다. 실행 파일을 완전한 디버그 정보로 컴파일하면 (그리고 RTL도 완전한 디버그 정보로 컴파일되었다면), 사용자는 이러한 예외 루틴으로 전달된 파라미터를 검색(retrieve)할 수 있다. 하지만 일반적인 방법은 아니므로 라자루스가 Call Stack과 Registers를 테스트할 수 있는 내적 가능성이 있다.
이러한 인수(argument)를 올바르게 해석하기 위해선 이러한 루틴들이 필요로 하는 내부 호출 규칙을 이해할 필요가 있다. FPC 1.9x 이전에는 인수들이 스택에 위치한 반면 최신 버전들은 레지스터 내에 인수들이 위치한다. FPC 버전 인식 루틴이 올바르지 않은 결과를 제공하면 사용자는 여기에 호출 규칙을 오버라이딩할 기회를 가진다.
이벤트 로그 페이지
Event Log 페이지는 현재 부분적 기능만 이용할 수 있으며, 곧 기본 기능들이 개발될 것이다.
어찌되었건 결국 IDE에도 Event Log 창이 생길 것인데, 그 전까지는 로그 정보가 Debug output 창에 표시되고, 이는 View→Debug windows→Debug output 에서 접근한다.
Clear log on run 확인상자를 활성화하면 프로그램이 실행될 때마다 로그를 강제로 비운다.
Limit line count to 확인상자를 활성화하면 IDE가 디버거 출력의 최대 행 수를 넘기지 않고 보관하도록 한다. 최대 행 수는 확인상자 아래 spin edit 필드에서 설정된다.
Message 섹션은 이벤트 로그에 열거할 (그리고 열거하지 않을) 메시지 정의를 목적으로 한다. 사용자의 라자루스 버전에 이 기능이 있을지 모르나 라자루스를 쓸 당시엔 구현되지 않은 기능이다.
Language Exceptions 페이지
Language Exceptions 페이지는 프로그래밍 언어 내에서 예외를 어떻게 처리하는지를 제어한다. 예를 들어, 프로그램이 파일을 읽을 수 없다면 예외가 트리거된다. 해당 페이지는 그러한 예외에 대해서 디버거를 중단해야 할 것인지 아닌지를 선택하도록 해준다. 디버거는 Ignore these exceptions 에 열거된 예외는 무시할 것이다. Add 버튼을 이용하면 디버거가 무시하길 원하는 예외 이름을 타이핑하여 예외를 추가시키는 간단한 대화창이 뜬다.
예를 들어 디버거가 EDivByZero 예외를 무시하길 원하는 사용자가 있을지도 모른다.
한 리스트에서 예외를 제거하려면 무시할 예외 리스트에서 해당 항목을 선택한 후 Remove 버튼을 누를 경우, 예외가 내던지면 (thrown) 디버거가 실행을 중단한다.
디버거가 어떠한 예외에서도 중단하지 않길 원한다면 Notify on Lazarus Exceptions 옵션도 비활성화시켜야 한다.
OS Exceptions 페이지
OS Exceptions 페이지는 운영체제의 예외를 어떻게 처리할 것인지를 조정한다. Signals 섹션은 쓰기 당시에 구현되지 않았다. 해당 페이지는 디버거가 신호를 처리할 것인지 아니면 다른 프로그램이 처리할 것인지 정의한다. 예를 들어, 0으로 나누기(division by zero)는 운영체제에 의해 신호가 전달되고, RTL에 의해 EDivByZero 예외로 해석된다. 디버거가 신호를 처리한다면 RTL가 메시지를 해석하기 전에 프로그램은 중단된다. 현재는 디버거가 항상 신호를 중단한다.
라자루스에서는 현재 8개의 디버그 창을 제공하는데 View→Debug windows 메뉴 또는 단축키를 이용해 접근한다. 창이란 Watches, Breakpoints, Local variable, Registers, Call Stack, Assembler, Event Log, Debug output을 가리킨다.
델파이와 그 디버거에 익숙하다면 gdb의 행위에 매우 당황할 것이다. 따라서 아래 절에는 라자루스와 델파이 (버전 7) 간에 주의해야 할 중요한 디버거 차이를 강조하겠다:
Local variables: 차이 없음.
Watches:
모니터링한 표현식을 (Watches) 편집 가능하지만 라자루스는 표현식의 변경, 활성화, 비활성화만 가능하다. 델파이 디버거는 모니터링된 표현식과 같이 함수를 열거하며 디스플레이 스타일을 포맷팅할 수 있다. 델파이에서는 반복 계수기(repeat counter)를 설정할 수도 있다 (배열로 취급되는 변수). 이러한 점들은 라자루스에선 비활성화되어 있다.
Formatting expressions:
Modify 와 Inspect 는 아직 구현되지 않지만 라자루스 로드맵(Roadmap)에는 기능이 표시된다. 라자루스에서는 (Watch/Display 스타일에서와 같이) 포맷 식별자를 이용해 값에 대한 디스플레이 타입을 변경하는 것이 불가능하다.
델파이에서는 somevalue,p 와 같은 표현식을 분석하여 값을 포인트로 표시하거나 somevalue,x 를 분석해 16진 값을 표시할 수 있다.
Showing variables:
포인터와 클래스 변수와 관련해, 델파이는 포인터나 클래스 타입은 표시하지 않고 주소만 표시한다.
라자루스의 경우 값이 타입으로 이어진다.
라자루스에선 클래스가 종종 TSomething 으로 표시되기도 하고, ^TSomething 으로 보이기도 한다. gdb와 관련해 디버거 포맷에 제약이 있다. 이유는 파스칼 클래스가 Pascal 오브젝트와 동일한 C-class로 매핑(mapping)된다. dwarf3-debugger 명세(specification)는 파스칼 스타일로 된 클래스를 인지하며, FPC는 그 클래스를 쓸 수 있지만 gdb는 그 클래스를 표시할 수 없다.
라자루스에서 동적 배열은 포인터로만 표시되지만 델파이에선 내용을 표시한다. 이는 디버거 포맷에 의해 결정되는데 그 이유는 C 에 따라 타입을 향한 포인터로 쓰이는 반면 dwarf3은 동적 배열을 알기 때문이다.
Breakpoints:
중단점의 설정 및 활성화는 (거의) 동일하다. 라자루스에선 소스 코드 중단점만 분석된다.
반대로 델파이에선 주소, 데이터, 모듈 로드 중단점을 이용할 수 있다. 현재 라자루스에선 구현되지 않는 기능들인데, 로드맵엔 존재한다. 중단점은 라자루스에서 편집할 수 없다. 즉, 그룹을 변경, 활성화, 또는 비활성화할 수 없고, 중단점에서 중단(halt) 이외의 모든 액션은 불가능함을 의미한다. 기능을 이용할 수는 있으며, 현재로선 적절한 대화창이 구현되길 기다릴 뿐이다.
Call Stack:
이는 델파이 콜 백(call stack)의 확장 버전이다. 스택 길이는 제한되어 깊은 재귀 함수의 디버깅을 수월하게 해준다. 점프는 전방향과 후방향으로 실행 가능하다. 현재 범위는 변경 가능한데, 즉, 호출 프로시저의 변수를 테스트 및 고려할 수 있음을 의미한다.
스택은 클립보드로 복사할 수 있다. 델파이도 이를 실행할 수 있지만 메뉴나 툴 버튼으로 제공되진 않으므로 [Ctrl]+[C]를 눌러야 한다.
Debugger output:
디버거의 내부 상태를 보여준다.
Run ⇒ Stop:
Run ⇒ Stop 은 디버깅 프로세스를 중단시킬 것이다. [Ctrl]+[F2]를 이용해 디버깅을 중단 시 IDE이 응답하지 않는 경우가 발생하기도 한다. 이는 디버거가 아직 실행 중이며 디버깅된 프로세스가 이미 중단되었음을 의미한다.
델파이를 이용 시 유일한 해결방법은 델파이를 중단하고 재시작하는 것이다.
데이터베이스 애플리케이션에서도 비슷한 일이 발생한다. 데이터베이스 접근 시 예외가 발생하여 오류 메시지를 클릭함으로써 애플리케이션을 중단하면, 디버거가 여전히 실행되고 있을지도 모른다. 오류로부터 복구하여 애플리케이션을 재시작하려면 (실제로 오류를 수정했는지 테스트하려면), 디버거를 먼저 중단해야 한다.
Threads / Module / CPU / FPU:
해당 기능들은 아직 구현되진 않았지만 로드맵엔 표시되어 있다.
디버거가 문제를 찾으면 그에 관한 정보가 여러 개의 창에 표시된다. 델파이에선 View ⇒ Debug Windows 에서 찾을 수 있다. 사용자는 필요할 것이라 생각하는 창을 디버깅 전에 또는 오류가 처음 발생했을 때 열 수 있다.
변수의 타이핑이 엄격한 오브젝트 파스칼은 많은 프로그래밍 언어들만큼 자주 디버거를 호출하지는 않을 것이라는 관점이 일반적이다. 오브젝트 파스칼을 이용한 컴파일러에서 이미 다양한 비일관성이 차단되는데, 차단되지 않았더라면 디버거의 기능을 필요로 할 것이다. 컴파일러의 오류 메시지는 꽤 명확하다.