프로그래밍백엔드 Perl 개발자

Perl에서 서브프로그램(함수/서브루틴)의 구현에서 매개변수 전달, 반환 값, 그리고 @_의 사용에 대한 특성은 무엇인가요?

Hintsage AI 어시스턴트로 면접 통과

답변.

질문 이력:

Perl에서는 서브프로그램이 처음부터 매우 유연하게 구현되었습니다: 서브프로그램 호출은 무제한의 매개변수를 받을 수 있으며, 이들은 배열 @_에 저장됩니다. 이러한 접근 방식은 다양한 난이도의 작업에 적합하며 Perl의 동적성을 지원합니다.

문제점:

많은 개발자, 특히 초보자는 @_와 작업할 때 혼란을 겪습니다 — 매개변수의 잘못된 구조 분해, 입력 데이터의 우연한 수정(변수가 값에 의해 전달되고, 복잡한 구조는 참조에 의해 전달되기 때문에), 인수의 개수와 유형의 불일치 문제가 발생합니다. 다양한 유형의 데이터를 반환할 때와 함수 프로토타입을 구현하려고 할 때 문제가 발생합니다.

해결책:

인수를 받으려면 서브프로그램에서 배열 @_에서 명시적으로 구조 분해해야 합니다. 반환 값은 return 연산자에 의해 이루어지며, 동작은 문맥(스칼라 또는 리스트)에 따라 다릅니다. 부작용을 피하기 위해 매개변수는 종종 복사로 또는 수정이 필요한 경우 참조로 받아들여집니다. 복잡한 구조의 경우 참조로 전달하는 방법을 사용합니다.

코드 예:

sub add { my ($a, $b) = @_; return $a + $b; } sub change_array { my ($arr_ref) = @_; push @$arr_ref, 100; } my @nums = (1, 2, 3); my $sum = add(5, 10); change_array(\@nums); print join(", ", @nums); # 1, 2, 3, 100

주요 특징:

  • 배열 @_를 통해 매개변수를 타입 없이 전달
  • 호출 컨텍스트에 따라 다양한 유형 반환
  • 원본 데이터를 변경하기 위한 참조 전달

트릭 질문.

스칼라에 대해 함수가 전달된 매개변수를 변경하나요?

아니요, 스칼라는 전달될 때 복사되며, 그 변경 사항은 원본에 영향을 주지 않습니다. 그러나 인수가 참조인 경우, 원본 데이터는 변경될 수 있습니다.

다른 언어처럼 서브프로그램에 기본 값 매개변수를 설정할 수 있나요?

직접적으로는 안 됩니다. Perl에서는 함수 본문 내에서 기본 값 처리를 직접 구현해야 하며, 이를 위해 defined 체크 또는 매개변수 개수를 사용해야 합니다.

코드 예:

sub foo { my ($arg1, $arg2) = @_; $arg2 //= 10; print "$arg1 $arg2 "; } foo(5); # 5 10

$_[0]에 대한 직접 접근 시 @를 복사하지 않았을 때 무슨 일이 발생하나요 — 예: $a = $[0]?

이런 할당은 별칭을 생성합니다: $a의 변경은 $_[0]를 변경하며, 그 반대도 마찬가지입니다. 예기치 않은 변경을 피하기 위해 my ($a) = @_를 통해 복사를 생성하는 것이 좋습니다.

일반적인 오류 및 안티 패턴

  • 함수 내부에서 @_를 직접 조작
  • return 시 스칼라 또는 리스트 컨텍스트에 대한 불주목
  • 참조로 전달하지 않고 입력 데이터 변형하기

실제 사례

**부정적인 사례

배열을 처리하는 함수에서 @_의 매개변수를 지역 변수로 복사하는 것을 잊었습니다. 결과적으로 지역 변수의 변경이 원본 배열을 변경하여 프로그램의 다른 부분에서 버그를 발생시켰습니다.

장점:

  • 간결한 코드

단점:

  • 부작용 추적이 어렵다
  • 코드 읽기가 어려워진다

**긍정적인 사례

팀에서는 각 서브프로그램의 시작 부분에서 반드시 @_의 구조 분해를 실행하는 관행을 도입하였으며, 큰 객체는 참조로만 전달합니다.

장점:

  • 안전한 동작
  • 쉬운 유지보수 및 확장성

단점:

  • 약간 더 많은 템플릿 코드(불필요한 복사 줄)이 추가된다.