Perl-서브 루틴
Perl 서브 루틴 또는 함수는 함께 작업을 수행하는 명령문 그룹입니다. 코드를 별도의 서브 루틴으로 나눌 수 있습니다. 코드를 여러 서브 루틴으로 나누는 방법은 사용자에게 달려 있지만 논리적으로 나누는 것은 일반적으로 각 함수가 특정 작업을 수행하도록하는 것입니다.
Perl은 서브 루틴, 방법 및 기능이라는 용어를 같은 의미로 사용합니다.
서브 루틴 정의 및 호출
Perl 프로그래밍 언어에서 서브 루틴 정의의 일반적인 형식은 다음과 같습니다.
sub subroutine_name {
body of the subroutine
}
Perl 서브 루틴을 호출하는 일반적인 방법은 다음과 같습니다.
subroutine_name( list of arguments );
5.0 이전의 Perl 버전에서는 서브 루틴을 호출하는 구문이 아래와 같이 약간 달랐습니다. 이것은 Perl의 최신 버전에서 여전히 작동하지만 서브 루틴 프로토 타입을 우회하므로 권장되지 않습니다.
&subroutine_name( list of arguments );
간단한 함수를 정의한 다음 호출하는 다음 예제를 살펴 보겠습니다. Perl은 프로그램을 실행하기 전에 컴파일하기 때문에 서브 루틴을 선언하는 위치는 중요하지 않습니다.
#!/usr/bin/perl
# Function definition
sub Hello {
print "Hello, World!\n";
}
# Function call
Hello();
위의 프로그램이 실행되면 다음과 같은 결과가 나옵니다.
Hello, World!
서브 루틴에 인수 전달
다른 프로그래밍 언어 에서처럼 다양한 인수를 서브 루틴에 전달할 수 있으며 특수 배열 @_를 사용하여 함수 내에서 액세스 할 수 있습니다. 따라서 함수의 첫 번째 인수는 $ _ [0]에 있고 두 번째 인수는 $ _ [1]에있는 식입니다.
모든 스칼라와 같은 인수로 배열과 해시를 전달할 수 있지만 둘 이상의 배열 또는 해시를 전달하면 일반적으로 개별 ID가 손실됩니다. 따라서 참조 (다음 장에서 설명)를 사용하여 배열이나 해시를 전달합니다.
숫자 목록을 가져온 다음 평균을 인쇄하는 다음 예제를 시도해 봅시다.
#!/usr/bin/perl
# Function definition
sub Average {
# get total number of arguments passed.
$n = scalar(@_);
$sum = 0;
foreach $item (@_) {
$sum += $item;
}
$average = $sum / $n;
print "Average for the given numbers : $average\n";
}
# Function call
Average(10, 20, 30);
위의 프로그램이 실행되면 다음과 같은 결과가 나옵니다.
Average for the given numbers : 20
목록을 서브 루틴으로 전달
@_ 변수는 배열이기 때문에 서브 루틴에 목록을 제공하는 데 사용할 수 있습니다. 그러나 Perl이 목록과 배열을 받아들이고 구문 분석하는 방식 때문에 @_에서 개별 요소를 추출하기가 어려울 수 있습니다. 다른 스칼라 인수와 함께 목록을 전달해야하는 경우 다음과 같이 목록을 마지막 인수로 만듭니다.
#!/usr/bin/perl
# Function definition
sub PrintList {
my @list = @_;
print "Given list is @list\n";
}
$a = 10;
@b = (1, 2, 3, 4);
# Function call with list parameter
PrintList($a, @b);
위의 프로그램이 실행되면 다음과 같은 결과가 나옵니다.
Given list is 10 1 2 3 4
서브 루틴에 해시 전달
목록을 수락하는 서브 루틴 또는 연산자에 해시를 제공하면 해시가 자동으로 키 / 값 쌍 목록으로 변환됩니다. 예를 들면-
#!/usr/bin/perl
# Function definition
sub PrintHash {
my (%hash) = @_;
foreach my $key ( keys %hash ) {
my $value = $hash{$key};
print "$key : $value\n";
}
}
%hash = ('name' => 'Tom', 'age' => 19);
# Function call with hash parameter
PrintHash(%hash);
위의 프로그램이 실행되면 다음과 같은 결과가 나옵니다.
name : Tom
age : 19
서브 루틴에서 값 반환
다른 프로그래밍 언어 에서처럼 서브 루틴에서 값을 반환 할 수 있습니다. 서브 루틴에서 값을 반환하지 않는 경우 서브 루틴에서 마지막으로 수행 된 계산이 자동으로 반환 값이됩니다.
다른 스칼라처럼 서브 루틴에서 배열과 해시를 반환 할 수 있지만 둘 이상의 배열 또는 해시를 반환하면 일반적으로 개별 ID가 손실됩니다. 따라서 함수에서 배열이나 해시를 반환하기 위해 참조 (다음 장에서 설명)를 사용할 것입니다.
숫자 목록을 가져온 다음 평균을 반환하는 다음 예제를 시도해 보겠습니다.
#!/usr/bin/perl
# Function definition
sub Average {
# get total number of arguments passed.
$n = scalar(@_);
$sum = 0;
foreach $item (@_) {
$sum += $item;
}
$average = $sum / $n;
return $average;
}
# Function call
$num = Average(10, 20, 30);
print "Average for the given numbers : $num\n";
위의 프로그램이 실행되면 다음과 같은 결과가 나옵니다.
Average for the given numbers : 20
서브 루틴의 전용 변수
기본적으로 Perl의 모든 변수는 전역 변수이므로 프로그램의 어느 곳에서나 액세스 할 수 있습니다. 그러나 당신은 만들 수 있습니다private 호출 된 변수 lexical variables 언제든지 my 운영자.
그만큼 my연산자는 변수를 사용하고 액세스 할 수있는 특정 코드 영역으로 제한합니다. 해당 지역 외부에서는이 변수를 사용하거나 액세스 할 수 없습니다. 이 영역을 범위라고합니다. 어휘 범위는 일반적으로 서브 루틴의 본문을 정의하거나 if, while, for, foreach 및 eval 문의 코드 블록을 표시하는 것과 같이 그 주위에 중괄호가있는 코드 블록입니다 .
다음은 사용하여 단일 또는 여러 개인 변수를 정의하는 방법을 보여주는 예입니다. my 연산자-
sub somefunc {
my $variable; # $variable is invisible outside somefunc()
my ($another, @an_array, %a_hash); # declaring many variables at once
}
전역 변수와 개인 변수를 구별하기 위해 다음 예제를 확인하십시오.
#!/usr/bin/perl
# Global variable
$string = "Hello, World!";
# Function definition
sub PrintHello {
# Private variable for PrintHello function
my $string;
$string = "Hello, Perl!";
print "Inside the function $string\n";
}
# Function call
PrintHello();
print "Outside the function $string\n";
위의 프로그램이 실행되면 다음과 같은 결과가 나옵니다.
Inside the function Hello, Perl!
Outside the function Hello, World!
local ()을 통한 임시 값
그만큼 local변수의 현재 값이 호출 된 서브 루틴에 표시되어야 할 때 주로 사용됩니다. 로컬은 전역 (의미 패키지) 변수에 임시 값을 제공합니다. 이를 동적 범위 지정이라고 합니다. 어휘 범위 지정은 my에서 수행되며 C의 자동 선언과 더 비슷합니다.
둘 이상의 변수 또는 표현식이 로컬에 제공되는 경우 괄호로 묶어야합니다. 이 연산자는 해당 변수의 현재 값을 숨겨진 스택의 인수 목록에 저장하고 블록, 서브 루틴 또는 평가를 종료 할 때 복원하는 방식으로 작동합니다.
전역 변수와 지역 변수를 구별하기 위해 다음 예제를 확인해 봅시다.
#!/usr/bin/perl
# Global variable
$string = "Hello, World!";
sub PrintHello {
# Private variable for PrintHello function
local $string;
$string = "Hello, Perl!";
PrintMe();
print "Inside the function PrintHello $string\n";
}
sub PrintMe {
print "Inside the function PrintMe $string\n";
}
# Function call
PrintHello();
print "Outside the function $string\n";
위의 프로그램이 실행되면 다음과 같은 결과가 나옵니다.
Inside the function PrintMe Hello, Perl!
Inside the function PrintHello Hello, Perl!
Outside the function Hello, World!
state ()를 통한 상태 변수
또 다른 유형의 어휘 변수가 있는데, 개인 변수와 유사하지만 상태를 유지하고 서브 루틴을 여러 번 호출 할 때 다시 초기화되지 않습니다. 이러한 변수는state 연산자이며 Perl 5.9.4부터 사용할 수 있습니다.
다음 예제를 확인하여 state 변수-
#!/usr/bin/perl
use feature 'state';
sub PrintCount {
state $count = 0; # initial value
print "Value of counter is $count\n";
$count++;
}
for (1..5) {
PrintCount();
}
위의 프로그램이 실행되면 다음과 같은 결과가 나옵니다.
Value of counter is 0
Value of counter is 1
Value of counter is 2
Value of counter is 3
Value of counter is 4
Perl 5.10 이전에는 다음과 같이 작성해야합니다.
#!/usr/bin/perl
{
my $count = 0; # initial value
sub PrintCount {
print "Value of counter is $count\n";
$count++;
}
}
for (1..5) {
PrintCount();
}
서브 루틴 호출 컨텍스트
서브 루틴 또는 문의 컨텍스트는 예상되는 반환 값의 유형으로 정의됩니다. 이를 통해 사용자가받을 것으로 기대하는 것에 따라 다른 값을 반환하는 단일 함수를 사용할 수 있습니다. 예를 들어 다음 localtime ()은 스칼라 컨텍스트에서 호출되면 문자열을 반환하지만 목록 컨텍스트에서 호출되면 목록을 반환합니다.
my $datestring = localtime( time );
이 예에서 $ timestr의 값은 현재 날짜와 시간으로 구성된 문자열입니다 (예 : Thu Nov 30 15:21:33 2000). 반대로-
($sec,$min,$hour,$mday,$mon, $year,$wday,$yday,$isdst) = localtime(time);
이제 개별 변수에는 localtime () 서브 루틴에서 반환 된 해당 값이 포함됩니다.