프로그래밍풀 스택 Perl 개발자

Perl에서 서브프로그램에 인수를 전달하는 방법에는 어떤 것이 있으며, 참조에 의한 전달은 어떻게 구성하나요? @_의 작업에 대한 세부 사항은 무엇이며 참조로 전달이 필요한 경우는 언제인가요?

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

답변

Perl에서 함수의 인수 전달은 배열 @_를 통해 이루어집니다. 서브프로그램을 호출할 때 전달된 모든 매개변수가 이 배열 안에 들어가며, 원래는 리스트이고 복사가 아닌, 즉 $_[0]를 변경하면 원본을 수정하는 것입니다.

값에 의한 전달:

sub foo { my ($arg1, $arg2) = @_; $arg1 = 10; # 로컬 변수만 변경됩니다. }

참조에 의한 전달:

sub bar { my ($array_ref) = @_; push @$array_ref, 42; } my @data = (1,2,3); bar(\@data); # @data는 이제 (1,2,3,42)가 됩니다.

세부 사항:

  • 원본 배열이나 해시를 변경하고 싶다면 _참조_를 전달하세요.
  • @_ 내부의 일반 변수($foo, $bar)는 원본 인수의 별칭이지만, my ($a, $b) = @_를 통해 언팩할 경우 복사가 생성됩니다.
  • 배열과 해시는 일반 전달 시 그 내용이 리스트로 펼쳐지며, 경계를 잃게 됩니다: 참조를 전달하거나 시프트를 사용할 필요가 있습니다.

함정 질문

Perl에서 함수를 이렇게 호출하면: myfunc(@arr)로 배열을 전달하고, 함수 내부에서 $_[0]에 접근하면 무엇이 있나요?

정답: 그곳에는 배열의 중 첫 번째 요소가 있으며, 배열 전체에 대한 참조가 아닙니다! 배열을 전체 객체로 전달하기 위해서는 참조를 사용하세요: myfunc(\@arr).

예:

sub print_first { print $_[0], " "; } my @a = qw/foo bar baz/; print_first(@a); # 'foo'를 출력합니다. 배열 참조가 아닙니다. print_first(\@a); # ARRAY(0x...) — 배열 전체에 대한 참조를 출력합니다.

역사

어느 프로젝트에서 전역 해시를 수정하기 위해 함수를 이렇게 호출했습니다: update_hash(%global). 내부에서 $_[0]를 수정했습니다. 결과적으로 로컬 인수 배열의 슬라이스만 변경되고 원래의 전역 해시는 수정되지 않았습니다. 올바른 해결책은 참조를 전달하는 것이었습니다: update_hash(\%global).

역사

API 프레임워크를 작성하는 도중 여러 개의 명명된 인수를 사용하여 함수에 전달했으며, 해시를 이용했습니다. 가끔 배열을 전달했지만(참조가 아니라!) 인수가 "뒤섞였으며", 이는 혼란으로 이어졌습니다: myfunc(@arr, %opts). 해시의 일부 키가 배열 값으로 대체된 것으로 나타났으며, 오류를 발견하기가 어려웠습니다.

역사

재귀적으로 트리를 탐색하는 작업을 구현할 때 내부 요소를 변경하고자 했습니다. 배열을 "그대로" 전달했으며, 참조가 아니었습니다. 그들은 복사가 생성되어 수정이 외부 상황에 영향을 미치지 않았습니다. 문제는 참조 스타일로 변경하여 해결되었습니다.