openlang

경로 하나만 돌려줄 함수가 배열을 돌려준다

이번엔 남의 걸 들여다보는 게 아니라 PowerShell 함수를 처음부터 직접 짜 봤는데, 설명이 안 되는 방식으로 말을 안 들어요. 경로 하나만 돌려주면 되는 함수인데 배열이 돌아와요.

function Get-ReportPath {
    $names = [System.Collections.ArrayList]::new()
    foreach ($f in Get-ChildItem -Filter *.xlsx) {
        $names.Add($f.Name)
    }
    Write-Verbose "found $($names.Count) workbooks"
    Join-Path $PWD 'report.xlsx'
}

$path = Get-ReportPath
$path.GetType().Name   # Object[]

폴더에 통합 문서가 세 개 있으면 $path에 값이 네 개 들어 있어요. 마지막이 제가 원한 경로고, 앞의 세 개는 0, 1, 2예요(쓴 적도 없는 카운터처럼 보여서 한참을 쳐다봤어요). 이 숫자들은 어디서 나오는 거고, 함수 안에서 쓰는 보조 리스트가 결과로 새어 나가지 않게 하려면 보통 어떻게 하나요?

영어에서 번역원문 보기

이어지는 대화 4

서로의 근거를 따라
  1. 고유 링크

    맨 표현식은 전부 출력으로 나가니까 명시적으로 써. return (Join-Path $PWD 'report.xlsx')로 쓰면 그게 결과가 되고 앞에서 새어 나온 출력은 버려져.

    영어에서 번역원문 보기
  2. 고유 링크

    아쉽지만 아니에요. 이건 누구나 한 번은 놀라는 부분이에요. PowerShell의 return은 값을 내보내고 함수를 빠져나갈 뿐이고, 이미 출력으로 나간 건 그대로 남아요. 새는 곳은 ArrayList.Add예요. 이 메서드는 새 항목의 인덱스를 돌려주는데, 아무도 받지 않은 반환값은 다른 값과 똑같이 출력이 돼요. 0, 1, 2가 거기서 나온 거예요.

    호출하는 자리에서 인덱스를 버리면 돼요. 아래 셋 중 아무거나 괜찮아요.

    [void]$names.Add($f.Name)
    $null = $names.Add($f.Name)
    $names.Add($f.Name) | Out-Null

    (about_Return 도움말에도 거의 같은 예제가 있어요. "Please wait" 문자열이 결과와 함께 변수에 들어가 버리는 예제요.) return은 읽기 좋으라고 남겨 둬도 괜찮아요. 다만 뭘 치워 주지는 않아요.

    영어에서 번역원문 보기
  3. 고유 링크

    호출하는 자리에서 고쳐야 한다는 데는 반대다. 루프 세 개에 캐스트 세 개를 달아 두면 네 번째에서 누군가 빠뜨린다. 이 함수 하나만 놓고 보면 [void]가 제일 손쉬운 땜질이라는 건 인정한다. 그래도 진짜 문제는 리스트 타입이다. [System.Collections.Generic.List[string]]::new()의 Add는 아무것도 돌려주지 않으니 샐 인덱스가 애초에 없다.

    영어에서 번역원문 보기
  4. 고유 링크

    그거였어요, 두 분 다 고마워요. 제네릭 List[string]으로 바꿨더니 $path가 다시 문자열 하나예요(Test-Path가 답을 한 줄로 줄줄이 내놓던 것도 멈췄어요. 그동안 모른 척하고 있었거든요).

    영어에서 번역원문 보기

같은 질문의 다른 갈래

  1. 멈춘 테스트는 print보다 덤프로 읽는 게 낫다

    예전에는 테스트가 멈추면 fmt.Println을 여기저기 넣고 다시 돌렸어요. 요즘은 다르게 해요. 타임아웃을 짧게 걸어 두면, 시간이 다 됐을 때 testing 패키지가 패닉을 내면서 모든 고루틴의 스택을 찍어 줘요. go…

    답글 9go
  2. init의 setq가 fill-column을 버퍼 하나에서만 바꿨다

    init에 (setq fill-column 72)를 오래전부터 넣어 뒀는데, 새 버퍼에서 M-q를 누르면 여전히 70에서 줄이 바뀐다는 걸 이제야 알았어요. (*scratch*에서는 72에서 바뀌어서 그동안 스스로를 속였어요…

  3. SilentlyContinue는 철자만 나아진 On Error Resume Next

    물려받은 워크북에서 물려받은 PowerShell 스크립트로 넘어왔더니 옛 친구가 새 옷을 입고 있네요. cmdlet 호출 절반에는 -ErrorAction SilentlyContinue, 나머지에는 2>$null이 붙어 있어요…