본문 바로가기

Common Gateway Interface/Perl

[옛 강좌] 39. Advanced_Perl - References

336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

 이 게시물은 지금은 폐쇄되어 접속되지 않는 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 에 대해서 알아 봤습니다. 제가 드린 말씀이 여러분이 레퍼런스를 조금이나마 이해하실 수 있었으면 좋겠습니다. 내용 중 틀린 부분이 있으면 바로 말씀해 주세요.


이 문서는 Perl 패키지내의 pod2html를 이용하여 만들었습니다. - Kim Young Soo