서브루틴이란 스크립트 내부를 모듈화(부품화) 하는 것을 말합니다. 이른바 자신으로 함수를 작성, 정의하는 방법입니다. 이러하듯 서브루틴은 [유저 함수]라고도 불리고 있습니다.
스크립트를 작성할 때에 서브루틴을 사용하는 것으로의 장점으로는 다음 2가지가 있습니다.
서브루틴 정의 및 호출
1. CGI 스크립트 안에서, 어떠한 처리를 몇 번을 반복 사용하고 싶은 경우에, 그 처리 부분을 모듈화해서 호출하는 것으로 효율적인 프로그램을 작성할 수 있다.
2. CGI 스크립트 소스가 길어지게 되면 일반적으로 스크립트 전체의 흐름을 이해하기 어려어 지기 때문에, 전체적인 처리 흐름을 기술하는 부분(서브루틴 호출)과 각각 상세하게 처리하는 부분(서브루틴 내부)로 나누어서 전체 흐름을 보다 쉽게 보이게 할 수 있다.
서브루틴의 작성법은 다음과 같습니다.
서브루틴 정의 |
sub 서브루틴명 { 처리 } |
서브루틴의 이름을 정하는 방법은 변수명과 동일합니다.
그리고 서브루틴 정의 부분은 스크립트 내의 어디에 두어도 괜찮습니다.
일반적으로는 제일 밑에 둡니다.
서브루틴을 호출하는 방법은 다음과 같습니다.
서브루틴 호출 |
&서브루틴명 |
호출하게 되면 호출한 곳에서 정의된 서브루틴이 실행 됩니다.
코드 예
$x = 80;
$y = 55;
$z = 75;
&answer;
sub answer {
$total = $x + $y + $z;
$mean = $total / 3;
print "총점은 $total점, 평균은 $mean점 입니다. \n";
}
결과
> 총점은 210점, 평균은 70점 입니다.
인수와 반환값
서브루틴은 사용자가 자유롭게 정의할 수 있는 함수이기 때문에, 서브루틴에 인수를 건네거나 서브루틴 실행 후 반환값을 반환할 수 있습니다.
인수는 배열 @_에 저장되어 보내집니다.
인수 보내는법 | $abc(@list); |
인수 @list를 보내는 경우 | |
인수 취득방법 | @_ |
건내받은 인수는 배열 @_로 취득 |
코드 예
&answer(80, 55, 75);
sub answer {
# 인수를 @_로 취득
($x, $y, $z) = @_;
$total = $x + $y + $z;
$mean = $total / 3;
print "총점은 $total점, 평균은 $mean점 입니다. \n";
}
결과
> 총점은 210점, 평균은 70점 입니다.
서브루틴 반환값은 return을 사용해서 반환합니다.
반환값 반환방법 sub abc {
실행
return @result;
}
반환값 취득방법 @list = &abc;
($total, $mean) = &answer(80, 55, 75);
print "총점은 $total점, 평균은 $mean점 입니다. \n";
sub answer {
# 인수를 @_로 취득
($x, $y, $z) = @_;
$total = $x + $y + $z;
$mean = $total / 3;
# 배열 형태로 반환값을 반환
return ($total, $mean);
}
결과
> 총점은 210점, 평균은 70점 입니다.
국소화 (글로벌 변수 와 로컬 변수)
프로그램이 수천 행, 수만 행의 규모가 큰 소스는 사용하는 변수가 중복될 때도 있습니다.
그리고 중복을 회피하기 위해서 매번 다른 변수를 할당하는 것에도 정도가 있고, 복잡하고 오류를 범하기도 하고, 방대한 프로그램에서 어느 정도 변수의 수를 줄이는 것이 메모리 절약이 됩니다.
변수를 서브루틴 등의 블록 안에서만 사용하도록 하는 것이 가능 합니다.
그것을 국소화라고 합니다.
국소화의 특성은 2개로 나눌 수 있습니다.
프로그램(스크립트) 전체에서 참조 가능한 변수를 글로벌 변수라고 하며, 서브루틴 등 블록 안에서만 이용 가능한 변수를 로컬 변수라고 합니다.
변수는 초기값에 의해 글로벌 변수가 되기 때문에 특별히 아무것도 정의 안한 변수는 글로벌 변수로 간주됩니다.
변수를 로컬 변수로 정의하고 싶은 경우는 local 또는 my를 사용합니다.
우선 다음의 예를 보도록 하겠습니다.
$word = "사과"; #글로벌 변수
&foo;
print "이것은 $word입니다.";
sub foo {
$word = "바나나"; #글로벌 변수
}
결과
> 이것은 바나나입니다.
1행에 변수 $word에 [사과]를 대입하지만 2행의 foo서브루틴이 실행되면서 $word에 “바나나”가 대입되기 때문에 3행의 $word는 [바나나]로 출력 돼버립니다.
이것은 변수가 중복되었기 때문에 기대 안 한 결과가 되어 버린 예입니다.
다음에는 서브루틴 안의 변수를 로컬 변수로 지정해서 국소화해보겠습니다.
$word = "사과"; #글로벌 변수
&foo;
print "이것은 $word입니다.";
sub foo {
my $word = "바나나"; #글로벌 변수
}
결과
> 이것은 사과입니다.
서브루틴 안에서 my를 사용해 변수 $word를 국소화 했기 때문에 6행에서 대입된 [바나나]는 서브루틴을 빠져나온 순간 소멸되어 버렸습니다.
따라서 3행의 변수 $word는 기대했던 대로 [바나나]가 출력 되었습니다.
참고로 위의 코드 예에서는 my 대신에 local를 사용해도 결과는 같습니다.
local과 my의 차이
로컬 변수 | Perl 버전 | 특성 |
---|---|---|
local | Perl5 | 선언된 서브루틴에서 호출된 서브루틴까지는 참조 가능 |
my | Perl4, Perl5 | 완전히 국소화가 되기 때문에 local처럼 서브루틴에서 호출한 서브 루딘까지 참조가 불가능. |
코드 예 -1(local변수)
$word = "사과"; #글로벌 변수
&foo;
sub foo {
local $word = "바나나"; # local함수로 정의
&update;
}
sub update {
print "이것은 $word입니다."; # 5행의 $word를 참조
}
결과
> 이것은 바나나입니다.
코드 예 -2(my변수)
$word = "사과"; #글로벌 변수
&foo;
sub foo {
my $word = "바나나"; # local함수로 정의
&update;
}
sub update {
print "이것은 $word입니다."; # 5행의 $word를 참조 불가
}
결과
> 이것은 사과입니다.
댓글