powershell에서 class사용하는 방법은 없나요?
있습니다.
회사의 한 동료는 Repository 패턴을 powershell로 구현해 주었습니다. business logic을 담당하는 함수 안에서 sql에 관한 처리를 확 줄여버리니 29세기의 프로그램에서 탈피하는 것과 같은 시원함을 느낄 수 있었습니다.
다른 모듈에서 사용하는 방법을 모르고 있는 것 같아서, 생성자를 함수로 한 번 감싸서 그걸 공개하면 되는 방법을 알려주었습니다.
생각난 김에 class를 사용하는 방법을 정리해 봤습니다. 기본적인 클래스의 정의 방법을 알고 계신다면, 적응하기는 어렵지 않습니다.
class 기본1
네 이것이 전부입니다.
class 기본2
멤버 변수를 정의해 볼까요. 멤버 변수, 또는 Property라고도 합니다.
변수이름은 한글로도 작성할 수 있으니, 멤버 변수도 한글로 작성할 수도 있습니다.
1
2
3
4
5
6
| class car {
[string] $이름
static [int] $numberOfDoors = 4
[datetime] $생산년도
hidden [string] $serialnumber
}
|
- static 은 class 변수를 의미하는 키워드입니다.
- hidden 은 내부적으로 사용하는 번수를 의미하는 키워드입니다.
1
2
3
4
5
6
7
8
9
10
11
| PS C:\> class car {
>> [string] $이름
>> static [int] $numberOfDoors = 4
>> [datetime] $생산년도
>> hidden [string] $serialnumber
>> }
PS C:\> new-object car
이름 생산년도
---- --------
0001/01/01 0:00:00
|
인스턴스 생성하기
다음 두가지 방법이 있습니다.
$myCar = [Car]::new()
$myCar = New-Object Car
class 기본3 생성자와 메서드
생성자는 리턴값이 없는, 클래스 이름과 같은 이름을 사용하는 함수입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
| class Glass
{
# Properties
[int]$Size
[int]$CurrentAmount
# Constructors
Glass ([int]$Size, [int]$Amount)
{
$this.Size = $Size
$this.CurrentAmount = $Amount
}
}
|
생성자가 있는 경우는 인스턴스를 만들 때 각각 다음과 같이 사용합니다.
- New-Object -TypeName Tree -ArgumentList ‘Mimosa’, 10
- [Tree]::New(‘Mimosa’, 10)
클래스 상속 받기
powershell에서 class 는 상속도 받을 수 있습니다. 상속받으려면 몇가지 제한이 있습니다.
- 디폴트 생성자를 명시적으로 정의해야 합니다.
- sealed 키워드를 가지고 만들어진 dotnet 객체는 상속받을 수 없습니다.
1
2
3
4
5
6
7
8
9
10
| PS C:\> class 자동차 {}
PS C:\> class 트럭 : 자동차 {}
PS C:\> [트럭]::new()
트럭
PS C:\> $a = [트럭]::new()
PS C:\> $a.gettype()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True False 트럭 자동차
|
클래스 공개하기
다른 모듈에서 import-module해서 사용할 수 없나요?
모듈에서 export하는 멤버는 Export-ModuleMember
라는 함수를 통해서 공개합니다.
그런데 문제가 있습니다. Export-ModuleMember 는 함수만을 받아들입니다. 그 얘기는 class export하도록 전달할 수가 없다는 얘기입니다. 즉, class를 선언한 함수 내에서만 사용할 수 있도록 되어 있는 구성입니다.
그렇다면 클래스를 만들어 리턴하는 함수를 작성해서 전달하면 어떨까요?
그렇다면 할 수 있을까요?
1
2
3
4
5
6
7
8
9
10
11
12
| New-Module {
class abc {
abc() {}
[string] hello() { return "hello world" }
}
function new-abc{ [abc]::new() }
Export-ModuleMember new-abc
} -name TestModule | Import-Module
$a = new-abc
$a.hello()
|
결과는, 잘 출력합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| PS C:\> New-Module {
>> class abc {
>> abc() {}
>> [string] hello() { return "hello world" }
>> }
>> function new-abc{ [abc]::new() }
>> Export-ModuleMember new-abc
>>
>> } -name TestModule | Import-Module
>>
>> $a = new-abc
>> $a.hello()
hello world
PS C:\>
|
ref