이 게시물은 지금은 폐쇄되어 접속되지 않는 Kim Young Soo(http://hours.interpia98.net/~unisoo/)님의 웹 사이트에 2001년경 게시된 내용을 바탕으로 오늘날 웹 환경에 맞게 내용을 덧붙였습니다.
Advanced_Perl - References
Description
References - 펄의 레퍼런스에 대한 이야기 입니다.
References
복잡하게 생각하면 복잡해지니깐요, 그냥 간단히 생각해요.
레퍼런스란 어떤 변수(스칼라, 배열, 해쉬)가 있다면, 그 변수의 레퍼런스라는건, 그 변수를 가리키는 값이라고 생각하시면 됩니다. C에서는 포인터라는 것이 있죠. 이것과 비교를 많이 하는데, C를 모르시는 분들이 있기에, 이와 비교는 하지 않겠습니다. 펄은 펄..... C는 C.... (영수 생각 ^^;)
그럼.. 일단 그런거구나 하고 넘어가시구요, 다음의 예제들을 보시면 금방 이해하실 겁니다. 레퍼런스도 또 하나의 스칼라다..... 라고 하더군요.
스칼라의 레퍼런스
$a = 2; # 이와 같이 스칼라 $a를 정의. $ra = \$a; # $a 의 레퍼런스 $ra의 생성. print $a; print $$ra; # 출력결과는 같습니다.
또한 원하시는 작업 예를 들어,
$$ra += 2; # 가능합니다.
스칼라의 레퍼런스이기에 $ra
의 직접적인 값은 $$ra
가 됩니다.
만약 print $ra
를 하시게 되면, SCALAR(0xca87f4)
- 시스템마다 달라요 - 라고 출력이 될 겁니다.
이건, $ra
의 값은 $a
의 값을 가리키는 값이죠. 이 가리키는(pointing) 실제 값으로 접근하기 위해서는 $$ra
라고 해야 됩니다.
배열의 레퍼런스
@array = ('1', '2', '3'); # 배열 생성 $rarray = \@array; # 배열에 대한 레퍼런스 생성
그렇담 출력할 때?
print $$rarray[0]; # 이런식으로 하셔두 됩니다. @$가 아니에요. 각 원소는 하나의 스칼라이기 때문에..
다른 방법도 있지만, 이건 해쉬를 설명한 후에 하겠습니다. 물론,
push (@$array, "a", "b", "c");
하실 수 있습니다. 이 땐 배열자체니깐, @$가 됩니다. print $rarray;
하면.... 결과 : ARRAY(.....)
이렇게 나옵니다.
해쉬의 레퍼런스
$rhash = \%hash; # 위와 다른 거 없죠? print $hash{"key1"}; print $$rhash{"key1"};
이렇게 할수 있어요.
@slice = @$rhash{'key1', 'key2'};
와 같이 쓰일수도 있습니다.
해쉬의 값을 나타낼때, %$rhash{'key1'}
이 아닙니다. @$rhash{'key1'};
과 같이 하셔야 합니다.
레퍼런스의 사용(Use References)
스칼라의 레퍼런스는 별 문제가 없어요. 그러나 배열, 해쉬의 레퍼런스일 경우 각 요소의 값을 불러오는 데에는 몇 가지 방법이 있습니다. 이 중 가장 편하고, 많이 쓰이는 것만 볼게요.
화살 연산자? (Arrow Notation)
펄은 배열, 해쉬의 레퍼런스 값을 참조할수 있도록, -> (화살 연산자?) 를 제공합니다. $rarray = \@array;
라고 했다면, 이 레퍼런스의 첫 번째 원소는 $rarray->[0];
이 됩니다.
해쉬 참조시 $rhash = \%hash;
라고 한다면, $rhash->{'key1'};
과 같이 표현하시면 됩니다.
서브루틴에서의 사용(Subroutines)
기존의 소스들을 보면 배열, 해쉬의 값을 넘길 때 타입 글로브(*)를 사용했었습니다. 이젠 그러실 필요 없습니다. 배열이든 해쉬든, 레퍼런스로 서브루틴으로 넘기고, 또 서브루틴에서 값을 가져오시기만 하면 됩니다. 간단한 예제로 보겠습니다.
@array = (1, 2, 3); PrintArray(\@array); sub PrintArray { my ($rarray) = @_; for ($i=0; $i<3; $i++) { print "array[$i] = $rarray->[$i]\n"; } }
직접 해보세요. 출력 결과는 우리가 예상한 대로 나옵니다.
참고 : 서브루틴을 부르실 때 앞에 & 를 붙이지 않으셔도 됩니다. 그냥 "()"만 해 주셔도 됩니다. :-)
또 서브루틴으로부터 어떤 배열을 만들었다면, 예를 들어...
sub GetFile { open (FILE, "..."); @body = <FILE>; close (FILE); return \@body; }
이렇게 있다면, 받을 때
$rbody = GetFile();
하시면, 서브루틴에서 정의된 배열 내용을 그대로 사용하실 수 있습니다.
다중 데이터 구조(Complex Data)
여기서는 평범한 다중 데이터의 구성에 대해서 말씀 드리겠습니다. 이런 데이터가 있다고 가정해 보고, 부모인 sue에는 자식이 두명 있어요. 이름은 john, peggy.
그리고 이 데이터에는 name, age의 값을 가지고 있구요.. 그렇담 우리는 여기서, "sue의 john의 나이는? 또는 sue의 두번째 아이의 이름은?" 이라는 질문에 답할 수 있도록, 데이터를 만들어 보겠습니다.
%sue = ('name' => 'sue', 'age' => '45'); # 부모인 sue의 자료 구조. %john = ('name' => 'john', 'age' => '20'); %peggy = ('name' => 'peggy', 'age' => '16'); # 자식의 자료 구조.
이제 위의 john, peggy의 데이터를 sue의 children에다 추가합니다.
$sue{'children'} = [\%john, \%peggy]; or @children = (\%john, \%peggy); $sue{'children'} = \@children;
위의 %sue 구조가 어떻게 됐는지 이해가 되세요?
%sue = ( 'name' => 'sue', 'age' => '45', 'children' => [{ 'name' => 'john', 'age' => '20' }, { 'name' => 'peggy', 'age' => '16' }]; );
이렇게 돼요.
우리가 원하는 데이터를 얻기 위해서, john의 나이?
print $sue{'children'}->[0]->{age}; print $sue{children}[0]{age};
와 같이 표현할수 있습니다.
위의 자료 구조는 해쉬 안에 배열이 있고, 이 배열 안에 다시 해쉬가 있는거죠. 우리는 이와 같은 표현을 써서 좀 더 복잡한 자료형을 만들 수 있습니다.
NOTES
지금까지 Perl 의 References 에 대해서 알아 봤습니다. 제가 드린 말씀이 여러분이 레퍼런스를 조금이나마 이해하실 수 있었으면 좋겠습니다. 내용 중 틀린 부분이 있으면 바로 말씀해 주세요.
'Common Gateway Interface > Perl' 카테고리의 다른 글
[옛 강좌] 41. Advanced_Perl - Typeglobs and Symbol Tables (0) | 2015.04.29 |
---|---|
[옛 강좌] 40. Advanced_Perl - my() & local() 함수 (0) | 2015.04.29 |
[옛 강좌] 38. IPC의 기본적 이해 (0) | 2015.04.29 |
[옛 강좌] 37. Perlprog - Bookmark Program (0) | 2015.04.29 |
[옛 강좌] 36. Perlprog - Bookmark Program (0) | 2015.04.29 |