www.perlmania.or.kr에서 본인이 답변한 내용정리
차례대로 정리를 해보면 perl에서 reference를 dereference 할때는 [sigil]{}연산자를
사용합니다. 여기서 sigil은 결과로 어떤 데이터 타입을 가질것인가를 결정하는거죠.
@array = ( "one", "two", "three", "four", [10, 20, 30, 40, 50] );
$arrayref = \@array;
인 상태에서 $arrayref 안의 one을 가져오려면 해당값은 scalar이므로 sigil은 $가 되고
${$arrayref}[0] 이 됩니다.( @array의 첫번째 요소를 나타낼때 $array[0] 이렇게 하는걸 상기 )
여기서 [sigil]{} 에서 {}는 생략가능합니다. 그래서
$$arrayref[0] 가 되고
그리고 [sigil]{}은 ->로 대체가능합니다. 따라서
$arrayref->[0] 이 됩니다.
이제 더 복잡한 익명배열,혹은 레퍼런스를 포함한 자료구조로 가서 위에서
@array안의 익명배열 [10,20,30,40,50]에서 10 을 가져오려면 어떻게 해야 할까요?
일단 @array안의 5번째 요소(여기서는 익명배열레퍼런스)를 가져와야 합니다.
레퍼런스 자체는 scalar이므로 sigil로는 $을 사용해야 하겠죠? 따라서
${$arrayref}[4] 가 익명배열의 레퍼런스가 될겁니다. 이제 이것을 또 dereference해야하고
dereference후 최종적으로 가져올 10이 scalar이니깐 sigil은 $가 사용됩니다.
따라서 ${${$arrayref}[4]}[0]; 이렇게 하면 10을 가져옵니다. 이것을 처음에 말씀드린 규칙을 통해
여러형태로 변경해보면 다음것들이 모두 다 동일한 결과를 가져옵니다.
$$arrayref[4]->[0]
$$arrayref[4][0]
${$$arrayref[4]}[0]
${$arrayref->[4]}[0]
$arrayref->[4]->[0] 여기서 [],{}들사이의 ->는 편의상 생략이 가능합니다. 따라서
$arrayref->[4][0]
이렇게 여러 형태로 사용가능하지만 마지막 형태를 제일 많이쓰죠 제일 깔끔하기도 하고.
여기서 {}를 생략한 형태인 $$$arrayref[4][0] 혹은 $$arrayref->[4][0] 은 왜 안되느냐?
하는 의문이 있을 수 있습니다.
그 이유는 []가 연산자 우선순위가 가장 낮기 때문에 derefernce 대상인 $$arrayref[4] 와
$arrayref->[4] 를 dereference 하지못하고 앞의 sigil들끼리 먼저 결합해버리기 때문입니다.
앞에서 예를든 ${$arrayref}[0] 가 $$arrayref[0] 가 될 수 있는건 [0]이 제일 마지막에
해석되는건 이러나 저러나 변함이 없기 때문이죠 두가지 경우를 꼼꼼히 비교해 보시면
안되는 이유를 더 명확히 아실 수 있을겁니다.
그러면 @array의 5번째 요소인 익명배열을 @b 라는 배열에 넣을려면 어떻게 해야할까요?
지금까지 배운 규칙을 사용해서 하나하나 차근차근 해보면 일단 익명배열의 레퍼런스(scalar값)는
${$arrayref}[4] 가 됩니다. 이제 이 익명배열 레퍼런스를 dereference해서 배열로 하려면
@{}을 사용해서 @{${$arrayref}[4]} 로 하면 최종적으로 배열을 뽑아내게 됩니다. 따라서
@b = @{${$arrayref}[4]}; 이렇게 하면 되겠죠. 그리고 앞에서 배운 규칙에 따라
@b = @{$$arrayref[4]}; 혹은
@b = @{$arrayref->[4]};
이렇게도 됩니다.
여기서 {}을 생략하는 형태인 이것들은 왜 안될까? 하는건
@b = @$$arrayref[4];
@b = @$arrayref->[4];
이미 위에서 예를 들어 얘기했기 때문에 알 수 있을겁니다.
제가 말씀드린 규칙
1. reference를 dereference 할때는 [sigil]{}연산자를 사용
( sigil은 최종적으로 만들어질 타입, reference는 scalar값이다. )
2. [sigil]{} 에서 {}는 생략가능
( 단 생략할때는 연산자 우선순위에 따른 해석 순서에 문제가 없어야 함 )
3. [sigil]{}은 ->로 대체가능
( 여러개일때 [],{}들사이의 ->는 편의상 생략이 가능 )
이것만 잘 기억하고 이해하시면 reference/derefrence는 헷갈릴 일이 전혀 없습니다.
추가 답변
@array = ( "one", "two", "three", "four", [10, 20, 30, 40, 50] );
$array[4][4]는 실제로 다음과 같은 절차를 거친 형태입니다.
1. ${$array[4]}[4]
2. $array[4]->[4]
3. $array[4][4]
$arrayref->[4][4] 는 다음과 같은 절차를 거친 형태이고요.
1. ${${$arrayref}[4]}[4]
2. ${$arrayref->[4]}[4]
3. $arrayref->[4]->[4]
4. $arrayref->[4][4]
다음은 Perl Cookbook에 있는 내용을 발췌 한것입니다.
이 내용에 입각해서 원초적 형태로 돌려 놓고 보면 혼돈의 여지가 없을겁니다.
--------------------------------------------------------------
<원문>
Confusion About Precedence
The expressions involving key lookups might cause some confusion. Do you read $$rarray[1] as ${$rarray[1]} or {$$rarray}[1] or ${$rarray}[1]?
(Pause here to give your eyes time to refocus!)
As it happens, the last one is the correct answer. Perl follows these two simple rules while parsing such expressions: (1) Key or index lookups are done at the end, and (2) the prefix closest to a variable name binds most closely. When Perl sees something like $$rarray[1] or $$rhash{"browns"}, it leaves index lookups ([1] and {"browns"}) to the very end. That leaves $$rarray and $$rhash. It gives preference to the `$' closest to the variable name. So the precedence works out like this: ${$rarray} and ${$rhash}. Another way of visualizing the second rule is that the preference is given to the symbols from right to left (the variable is always to the right of a series of symbols).
<해석>
우선순위에 대한 혼돈
key를 찾는것을 포함하는 표현은 약간의 혼돈을 줄 수 있다. $$rarray[1]을
${$rarray[1]} 또는 {$$rarray}[1] 또는 ${$rarray}[1] 어떤것으로 읽겠는가?
마지막이 맞는답이다. Perl은 그러한 표현을 파싱하는데 있어 다음의 간단한 두 법칙을 따른다:
(1) Key또는 index 찾는건 맨 마지막에 일어난다.
(2) 변수명에 가장 가까운 prefix는 가장 가까이서 결합된다.
Perl이 $$rarray[1] 또는 $$rhash{"browns"}를 볼때 [1]과 {"browns"}같은 index는 맨 마지막으로 제껴두면 $$rarray와 $$rhash가 남는다.
이것은 변수명에 가장가까운 $에 우선순위를 둔다.
그래서 우선순위는 ${$rarray}와 ${$rhash} 와 같이 동작한다.
두번째 법칙을 가시화하는 또 다른 방법은 우선순위는 symbol들에서 오른쪽에서 왼쪽으로 주어진다는것이다.
(변수는 항상 심볼들의 집합에서 항상 오른쪽에 위치한다.)
--------------------------------------------------------
Created
December 31, 2011 00:35
-
-
Save aero/1542213 to your computer and use it in GitHub Desktop.
Perl reference dereference
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment