DATA 전문가로 가는 길

[Perl] 서브루틴 본문

Programming/Perl

[Perl] 서브루틴

EstenPark 2009. 4. 7. 20:33

서브루틴이란?
인수를 받아서 처리하고 출력 하는 방법을 말할 수 있습니다.
보통 언어를 하다보면 개별적으로 움직여야 할 경우가 발생 될 것입니다.
사람도 여러가지 일을 처리 해줄 수 있는 것처럼 서부루틴도 그와 같이 여러가지 작업에 대해 처리하고 출력을 해줍니다.

보통 반환하는 값을 줄것인지 아니면 서브루틴에서 자체적으로 처리해여 결과를 보여줄 것인지는 상황에 따라 다를 것입니다.

자세한 사항은 아래 링크에서 확인 해보시면 보다 ? 많은 정보를 얻을수 있을 것입니다.
http://perldoc.perl.org/perlsub.html

use strict;
use warnings;

sub_return();

sub sub_return {
        print "I Love Perl \n";
}
결과 :
I Love Perl 

sub_return() 함수를 호출 하여 각각의 처리를 거쳐 출력을 하는 간단한 부분이며,
함수는 별도의 이름을 가지고 있기 때문에 다른 렉시컬 변수, 배열, 해쉬등과 혼용해도 문제는 없습니다. 또한 변수처럼 대소문자를 구분합니다.

인수에는 3종류가 있는데요.
$_, shift, @_  각각 어떻게 사용되는지 알아 보도록 하겠습니다.

[ $_ ] 사용
use strict;
use warnings;


my  $num1  =  1  ;
my  $num2  =  2  ;
my  $num3  =  3  ;

my $result = sub_num1($num1);
print "RESULT : $result \n";

sub sub_num1 {
        my $sum = $_[0] + 10;
        return $sum;
}

결과 :
RESULT : 11 
어떠한 인자 값을 넘기면 10을 더해서 결과를 출력 하는 간단한 소스입니다.
인수는 리스트로서 $_[0] 첫번째 첨자를 받아와서 10을 더하는 부분입니다.
반환값은 10이 되고 인자를 넘긴 값은 1이 되며 서브루틴에서 사용하려한 첨자는 첫번째가 됩니다.

[ shift ] 사용

use strict;
use warnings;


my  $num1  =  1234  ;
my  $num2  =  2  ;
my  $num3  =  3  ;

my $result = sub_num1($num1);
print "RESULT : $result \n";

sub sub_num1 {
        my @sum = split '',shift;
        my $total = 0;
        foreach my $i ( @sum ) {
                print "$i \n";
                $total += $i;
        }
        return $total;
}
결과 :
1
2
3
4
RESULT : 10
shift를 이용하여 한개의 문자를 가지고 오게 됩니다.
$num1  =  1234  를 인자값으로 넘기게 되면 split '',shift 즉 문자와 문자 사이를 자르고 그것을 배열에 넣게 됩니다.
최종적으로 배열에 넣은 1:2:3:4를 합하는 소스입니다. 결과를 반환 하는 값은 10이 되게 됩니다.
shift 함수는 @_의 배열에 있는 값을 자르게 됩니다.
보통 리스트 대입 할때 많이 사용하며, 특히 인수가 하나일 경우 shift 함수를 이용하면 보다 간편하게 프로그램을 만들 수 있습니다.


[ @_ ] 사용
use strict;
use warnings;


my  $num1  =  1  ;
my  $num2  =  2  ;
my  $num3  =  3  ;

my $result = sub_num1($num1, $num2, $num3);
print "RESULT : $result \n";

sub sub_num1 {
        my @sum = @_;
        my $total = 0;
        foreach my $i ( @sum ) {
                print "$i \n";
                $total += $i;
        }
        return $total;
}
결과 :
1 
2 
3 
RESULT : 6 
shift 함수와는 다르게 인자를 보낸 모든 첨자를 받아 처리 하는 방법 입니다.
$result = sub_num1($num1, $num2, $num3); 인자 1, 2 , 3을 보내면 @sum = @_;에서 각각의 인수를 배열에 대입하게 되고 그것을 모두 더하여 최종 값을 반환 하게 됩니다.
그렇다면 넘어온 인자가 몇개고 각각 분리하여 사용할 수 있기 때문에 주어진 값을 때때로 처리 할 수 있어 유용 하다고 생각 합니다.

문제 1 리스트를 활용한 합계 구하기
 
  • mysub 함수로 12345 의 인자값을 넘길시에 12+22+32+42+52 의 값을 구해주는 코드를 작성하여라.

    ( 인자값을 각각의 숫자를 나눈 뒤 뒤쪽에 숫자 2를 덧붙인 수들의 합 구하기)


use strict;

use warnings;

print mysub(12345);


          sub mysub{


         # 여기에 코드를 작성해주세요

          }  


   출력 : 160
위에 글을 보면 알수 있듯이 인수 한개를 넘어 오게 됩니다.
그렇다면 인수의 총 5개를 각각 문자로 분리하고 모두 2를 붙이고 그에 대한 합을 출력 하는 문제 입니다.
아마 저는 이문제 때문에 위에서 설명한 부분을 차례대로 풀어 보고 답은 이미 나와서 풀어 보지 않았습니다.
생각해보면 쉽지만 문법을 모르는 상태에서 해당 문제를 풀려고 하면 다소 엉뚱한 방향으로 전이되기도 합니다.

자 그럼 하나 하나 풀어 보도록 하겠습니다.
use strict;
use warnings;

print mysub(12345);

sub mysub {        
        my @num = split '', shift;
        my $sum
;
        foreach my $i ( @num ) {
                $sum += $i.2;
                print "LIST : $sum \n";
        }
        return $sum;
}
결과 :
LIST : 12 
LIST : 34 
LIST : 66 
LIST : 108 
LIST : 160 
160
앞서 말한 것 처럼 split와 shift를 사용하여 배열에 넣고 모든 요소에 2를 붙여서 최종 합을 구하는 방법입니다.
$sum += $i.2; 이부분에서 $i.2 (콤마 : 문자를 이여주는 방법입니다.) 2를 붙여주고 값을 계속 더합니다.
그후 최종 결과를 반환하면 되겠죠.

그럼 perl의 강한 면모를 활요하여 map를 사용 해서 풀이 해보도록 하겠습니다.
map, grep는 아래 문서를 보시면 조금 이해가? 되실거라고 생각 합니다.
저는 지금봐도 조금 헷갈리는 부분이 많습니다.
http://aero.springnote.com/pages/994336

 
use strict;
use warnings;
print mysub(12345); sub mysub { my $sum; map { $sum += $_ > 0 ? ($_.2) : $_ } split '', shift; return $sum; } 결과 :
160
map { $sum += $_ > 0 ? ($_.2) : $_ } split '', shift;
이게 펄의 힘이라고 말하고 싶습니다. 쉽게 말해 foreach 를 여러번 돌려서 할 필요가 전혀 없다는 말입니다.
음 map을 이용해서 차례로 넘어온느 대상에 대해서 어떤 조건을 걸면 결과로 만들어진 값을 새로운 리스트로 받아 들이기 되기때문에 값을 바로 출력 할 수 있는 것입니다.

그럼 아래는 더 간단하게 더 심도있게 문제를 풀어주신 소미님과 GoldBio님의 답안지도 같이 보면 좋을 것 같습니다.
 
GoldBio

sub mysub{
my $sum;
map{ $sum+=$_*10+2 } split '',shift;
return $sum;
}


소미

sub mysub {
eval join '2+', split //, shift()."0";
}


생각해보면 어떻게 조건을 줄것인가? 또 어떤 방법으로 문제를 풀어 볼 것인가에 대해서 차례대로 풀어 보면 어떤 결과에 만족 할 수 있는 답이 나올 거라고 생각 합니다.
다만, 중요한 것은 perl 스럽게 풀어보는 것이 하나의 과제일 것입니다.


참고 자료
================================================================================
             사이트                                                      이름
================================================================================

http://aero.springnote.com/                                                       (aero님)
http://perldoc.perl.org/perlsub.html                                        (만능펄 DOC)
http://doc.perl.kr/twiki/bin/view/Wiki/HowToStartPerl                  (펄덕펄덕)
http://cafe.naver.com/perlstudy.cafe                                 (대한민국Perl커뮤니티)
================================================================================
















Comments