자바스크립트를 활성화 해주세요

p063 Powershell 로 Class 사용하기

 ·  ☕ 3 min read

powershell에서 class사용하는 방법은 없나요?
있습니다.

회사의 한 동료는 Repository 패턴을 powershell로 구현해 주었습니다. business logic을 담당하는 함수 안에서 sql에 관한 처리를 확 줄여버리니 29세기의 프로그램에서 탈피하는 것과 같은 시원함을 느낄 수 있었습니다.

다른 모듈에서 사용하는 방법을 모르고 있는 것 같아서, 생성자를 함수로 한 번 감싸서 그걸 공개하면 되는 방법을 알려주었습니다.

생각난 김에 class를 사용하는 방법을 정리해 봤습니다. 기본적인 클래스의 정의 방법을 알고 계신다면, 적응하기는 어렵지 않습니다.

class 기본1

1
class car {}

네 이것이 전부입니다.

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

공유하기

tkim
글쓴이
tkim
Software Engineer