# 서브루틴

```perl
sub do_something {
    print "Hello.\n";
}

&do_something; # 또는 do_something();
```

## 매개변수 전달과 결과값의 반환

서브루틴의 매개변수는 `@_`라는 특수 변수를 통해서 전달됩니다.

그리고, `return` 키워드를 통해서 서브루틴의 결과 값을 반환합니다. 만일, 서브루틴에 return 키워드가 없다면 마지막 줄이 반환값이 됩니다.

```perl
print &do_something('Charlie', 100)."\n";
sub do_something {
    return "Hello, $_[0]. Your number is $_[1].";
    # 또는, "Hello, $_[0]. Your number is $_[1].";
}
```

`@_`는 참조에 의한 전달이므로 서브루틴 내에서 배열의 값을 변경하면, 서브루틴 외부에서도 변경된 상태가 됩니다. 전달된 매개변수의 값이 변경되지 않도록 하려면 별도의 지역 변수에 값을 복사해서 사용해야 합니다.

```perl
my @var = (1..5);
&do_something(@var);

print "@var\n";

sub do_something {
    for (@_){
        $_ += 2;
    }
}
```

서브루틴은 연산이 실패한 경우 등에 `undef`를 반환할 수 있습니다. 그리고, `defined`를 통해서 변수에 값이 할당되었는지를 판별할 수 있습니다.

```perl
my $max = &max(3..5);
if (defined $max){
    print "$max\n";
} else {
    print "Oops.\n";
}

sub max{
    return undef unless defined $_[0];
    my $val = $_[0];
    for (@_){
        $val = $_ if $val < $_;
    }
    return $val;
}
```

서브루틴의 매개변수로 배열이나 해시를 전달하려면 참조를 사용하면 됩니다.

```perl
my @var1 = (1..5);
my @var2 = (6..10);
&do_something(\@var1, \@var2);

sub do_something {
    my $ref1 = $_[0];
    my $ref2 = $_[1];

    $ref1->[0] = 0;

    my @ret = ();
    return @ret;
}
```