2015-01-06 4 views
2

입력으로리스트를 가져 오는 Perl 서브 루틴 first을 작성하고 목록의 첫 번째 요소를 리턴하고 목록에서 첫 번째 요소를 제거합니다.서브 루틴 매개 변수 수정 (Perl)

sub first(@) { 
    return shift @_; 
} 

내가 얻을 것은 :

print first(@list); // 1 
print @list; // 123 

스택 변수는 @_ 내가 기대하는 방식을 변경

@list = (1,2,3); 
print first(@list); // 1 
print @list; // 23 

이 매우 작동하지 않습니다 : 이것처럼

to (처음에는 (1, 2, 3)이고, 그 값은 (2, 3)입니다.) 그러나 입력으로주는 목록 (@list)은 변경되지 않습니다. 스택 변수가 참조하는 변수에 대한 참조를 저장한다고 생각했습니다.

나는 서브 루틴에서 목록 요소를 변경하면 그것은 또한 @list에 뭔가를 변경하지만 나는 서브 루틴에서 내가 쓸 수 있다면 내가하고 싶은 일,하지만 그래서 하나 + 1 :

@_[0] = "X"; 

그리고 서브 루틴 인쇄 @list을 실행 한 후에는 2X6이됩니다.

+1

이것을 달성하기 위해 'shift'를 사용하지 않는 이유는 무엇입니까? –

+0

그게 서브 루틴에서 내가하고있는 것입니다 – d9h

+2

하지만 왜 서브 루틴을 쓰고 싶습니까? 언제 'shift'를 사용하면 될까요? –

답변

2

배열 참조를 얻으려면 @ 프로토 타입 앞에 슬래시를 넣고 참조를 수정해야합니다. @을 사용하는 경우 서브 루틴에 배열 @list 사본을 얻을 수 있습니다 (따라서 부모의 배열은 수정되지 않습니다). http://perldoc.perl.org/perlsub.html#Prototypes :

역 슬래시 프로토 타입 문자는 특별한 의미가 있습니다. 모든 백 슬래시 @ 또는 %는 나머지 모든 인수를 취하고 목록 을 강제 실행합니다.

그래서 당신은 쓸 수 :

use strict; 
use warnings; 

sub first (\@) { 
    my $a = shift; 
    return shift @$a; 
} 

my @list = (1,2,3); 
print first(@list) . "\n"; 
print "@list" . "\n"; 

출력 : 당신이 목록이없는

1 
2 3 
1

, 당신은 배열을 가지고 있습니다. 배열과리스트는 Perl과 다릅니다 (great blog post 설명). 배열이 @list이라면 자신을 혼란스럽게 할뿐입니다 (앞으로 코드를 유지하는 사람).