Perl에서 모든 함수는 호출된 컨텍스트(스칼라, 리스트 또는 void)를 정의할 수 있습니다. operator wantarray는 컨텍스트를 결정하는 데 사용됩니다.
예:
sub foo { if (wantarray) { return (1, 2, 3); # 리스트 } else { return 42; # 스칼라 } } my @a = foo(); # (1, 2, 3) my $b = foo(); # 42 foo(); # Void context
특징: wantarray를 제대로 사용하지 않으면 예상치 못한 값을 반환할 수 있습니다.
컨텍스트에 따라 배열과 스칼라를 반환하는 함수가 void 컨텍스트에서 호출되면 무엇을 반환합니까?
답변: void 컨텍스트에서는 반환 값이 무시되지만, wantarray에 따른 분기 실행 코드 자체는 남아 있습니다. 따라서 함수가 부작용을 발생시킬 경우 별도의 처리를 고려해야 합니다. 예:
sub noisy { if (wantarray) { print "리스트 컨텍스트에서 호출됨"; return (1,2,3); } elsif (defined wantarray) { print "스칼라에서 호출됨"; return 42; } else { print "Void!"; return; } }
이야기 1
한 프로젝트에서 한 엔지니어는 컨텍스트의 차이를 잊고 있었습니다. 파일 이름 목록을 반환하는 함수가 때때로 파일 수(스칼라 컨텍스트)만 반환하고 실제 이름을 반환하지 않았습니다. 이는 다른 결과와의 연결 시 데이터 손실로 이어졌습니다.
이야기 2
헤더 파싱을 위한 API를 개발하는 동안, 함수는 명시적으로 왼쪽에 배열이 있을 경우에만 리스트를 반환했습니다(
my @headers = parse_headers()), 그리고if (parse_headers())와 같이 호출되었을 경우에는 첫 번째 헤더만 반환되었습니다. 버그는 즉시 발견되지 않았으며, 처리 방식이 논리적으로 보였으나 프로젝트의 여러 부분에서 동작이 달랐습니다.
이야기 3
파일에서 일치를 찾는 함수는 컨텍스트에 따라 다른 수의 결과를 반환했습니다. 결과적으로 map이나 grep에 전달할 경우 예상치 못한 오류가 발생했습니다: map은 리스트를 예상했지만 undef를 받았습니다 - 그리고 스칼라 컨텍스트에서는 발견된 일치의 수만 계산되었습니다. 문제는 여러 릴리스 후에야 발견되었습니다.