사용 — 헬퍼 메서드의 범위와 uses 절
사용 — 헬퍼 메서드의 범위와 uses 절
헬퍼 클래스가 정의되면, 그 헬퍼 클래스가 범위 안에 있을 때마다 그 메서드를 사용할 수 있어요. 즉 별도의 유닛에 정의했다면, 헬퍼 클래스의 메서드를 사용하는 곳마다 그 유닛이 uses 절에 있어야 해요.
본문
다음 유닛을 보세요.
{$mode objfpc}
{$h+}
unit oha;
interface
Type
TObjectHelper = class helper for TObject
function AsString(const aFormat: String): String;
end;
implementation
uses sysutils;
function TObjectHelper.AsString(const aFormat: String): String;
begin
Result := Format(aFormat, [ToString]);
end;
end.
그러면 다음은 컴파일돼요.
Program Example113;
uses oha;
{ Program to demonstrate the class helper scope. }
Var
o : TObject;
begin
O:=TObject.Create;
Writeln(O.AsString('O as a string : %s'));
end.
하지만 두 번째 유닛(ohb)을 만들면:
{$mode objfpc}
{$h+}
unit ohb;
interface
Type
TAObjectHelper = class helper for TObject
function MemoryLocation: String;
end;
implementation
uses sysutils;
function TAObjectHelper.MemoryLocation: String;
begin
Result := format('%p',[pointer(Self)]);
end;
end.
그리고 이 유닛을 uses 절의 첫 번째 유닛 뒤에 추가하면:
Program Example113;
uses oha,ohb;
{ Program to demonstrate the class helper scope. }
Var
o : TObject;
begin
O:=TObject.Create;
Writeln(O.AsString('O as a string : %s'));
Writeln(O.MemoryLocation);
end.
컴파일러는 "AsString" 메서드를 모른다고 불평할 거예요. 컴파일러는 첫 번째 클래스 헬퍼를 만나는 즉시 클래스 헬퍼를 찾는 것을 멈추기 때문이에요. ohb 유닛이 uses 절에서 마지막에 오므로 컴파일러는 TAObjectHelper만 클래스 헬퍼로 사용해요.
해결책은 유닛 ohb를 재구현하는 거예요.
{$mode objfpc}
{$h+}
unit ohc;
interface
uses oha;
Type
TAObjectHelper = class helper(TObjectHelper) for TObject
function MemoryLocation: String;
end;
implementation
uses sysutils;
function TAObjectHelper.MemoryLocation: String;
begin
Result := format('%p',[pointer(Self)]);
end;
end.
그리고 유닛 ohb를 ohc로 교체하면 예제 프로그램은 예상대로 컴파일되고 동작해요.
클래스 헬퍼가 있는 유닛을 프로젝트에 한 번 포함하는 것만으로는 충분하지 않다는 점을 주의하세요. 클래스 헬퍼가 필요할 때마다 그 유닛을 포함해야 해요.
핵심은 컴파일러가 uses 절에서 마지막 클래스 헬퍼 하나만 사용한다는 거예요. 두 헬퍼를 함께 쓰고 싶으면 첫 번째 헬퍼에서 파생시켜 하나로 합쳐야 해요.
더 알아보기
- 헬퍼 상속은 Inheritance에서 다뤄요
- 헬퍼의 기본 개념은 Definition을 참고하세요