Perl Language
서브 루틴
수색…
비고
서브 루틴은 인수를 @_
이라는 마법 변수에 전달합니다. 압축을 풀 필요가 없지만 가독성을 @_
인수가 참조로 전달 (수정 가능)되어 우발적 인 변경을 방지하기 때문에 권장됩니다.
서브 루틴 만들기
서브 루틴은 sub
키워드 뒤에 중괄호로 묶인 식별자와 코드 블록을 사용하여 생성됩니다.
모든 인수를 배열로 포함하는 특수 변수 @_
를 사용하여 인수에 액세스 할 수 있습니다.
sub function_name {
my ($arg1, $arg2, @more_args) = @_;
# ...
}
함수 shift
기본적으로 서브 루틴 내에서 사용될 때 @_
로 이동하므로 서브 루틴의 시작 부분에서 인수를 순차적으로 로컬 변수로 추출하는 것이 일반적인 패턴입니다.
sub function_name {
my $arg1 = shift;
my $arg2 = shift;
my @more_args = @_;
# ...
}
# emulate named parameters (instead of positional)
sub function_name {
my %args = (arg1 => 'default', @_);
my $arg1 = delete $args{arg1};
my $arg2 = delete $args{arg2};
# ...
}
sub {
my $arg1 = shift;
# ...
}->($arg);
또는 실험적 피쳐 "signatures"
을 매개 변수의 압축을 푸는 데 사용할 수 있습니다. 매개 변수는 값으로 전달됩니다 (참조가 아닌 ).
use feature "signatures";
sub function_name($arg1, $arg2, @more_args) {
# ...
}
매개 변수에 기본값을 사용할 수 있습니다.
use feature "signatures";
sub function_name($arg1=1, $arg2=2) {
# ...
}
어떤 식을 사용하여 다른 매개 변수를 포함하여 매개 변수에 기본값을 제공 할 수 있습니다.
sub function_name($arg1=1, $arg2=$arg1+1) {
# ...
}
현재 매개 변수 다음에 정의 된 매개 변수를 참조 할 수 없으므로 다음 코드는 예상대로 작동하지 않습니다.
sub function_name($arg1=$arg2, $arg2=1) {
print $arg1; # => <nothing>
print $arg2; # => 1
}
서브 루틴 인수는 참조로 전달됩니다 (서명의 경우 제외).
Perl의 서브 루틴 인수는 서명에있는 경우를 제외하고는 참조로 전달됩니다. 즉, 하위 배열의 @_
배열 멤버는 실제 인수에 대한 별칭 일뿐입니다. 다음 예제에서 서브 프로그램 내부의 $_[0]
은 실제로 동일한 변수에 대한 다른 이름이기 때문에 메인 프로그램의 $text
는 서브 루틴 호출 후에 수정 된 채로 남아 있습니다. 두 번째 호출은 문자열 리터럴이 변수가 아니므로 수정할 수 없기 때문에 오류가 발생합니다.
use feature 'say';
sub edit {
$_[0] =~ s/world/sub/;
}
my $text = "Hello, world!";
edit($text);
say $text; # Hello, sub!
edit("Hello, world!"); # Error: Modification of a read-only value attempted
호출자의 변수가 잘리지 않도록하려면 "서브 루틴 만들기"에서 설명한대로 @_
를 로컬 범위 변수 ( my ...
)에 복사하는 것이 중요합니다.
서브 루틴
서브 루틴은 코드를 보유합니다. 달리 명시되지 않는 한, 이들은 전역 적으로 정의됩니다.
# Functions do not (have to) specify their argument list
sub returns_one {
# Functions return the value of the last expression by default
# The return keyword here is unnecessary, but helps readability.
return 1;
}
# Its arguments are available in @_, however
sub sum {
my $ret = 0;
for my $value (@_) {
$ret += $value
}
return $ret;
}
# Perl makes an effort to make parens around argument list optional
say sum 1..3; # 6
# If you treat functions as variables, the & sigil is mandatory.
say defined ∑ # 1
print
또는 say
와 같은 일부 내장 함수는 키워드가 아니라 함수이므로 예를 들어 &say
는 정의되지 않습니다. 또한 정의 할 수 있음을 의미하지만 실제 호출 할 패키지 이름을 지정해야합니다
# This defines the function under the default package, 'main'
sub say {
# This is instead the say keyword
say "I say, @_";
}
# ...so you can call it like this:
main::say('wow'); # I say, wow.
Perl 5.18부터는 비전 역 기능을 사용할 수도 있습니다.
use feature 'lexical_subs';
my $value;
{
# Nasty code ahead
my sub prod {
my $ret = 1;
$ret *= $_ for @_;
$ret;
}
$value = prod 1..6; # 720
say defined ∏ # 1
}
say defined ∏ # 0
5.20부터 명명 된 매개 변수를 사용할 수도 있습니다.
use feature 'signatures';
sub greet($name) {
say "Hello, $name";
}
이것은 프로토 타입과 혼동해서는 안, 펄이있는 시설은 내장 기능처럼 작동 기능을 정의 할 수 있습니다. 함수 프로토 타입은 컴파일 타임에 표시되어야하며 그 효과는 &
sigil을 지정하여 무시할 수 있습니다. 프로토 타입은 일반적으로 가장 잘 사용되는 고급 기능으로 간주됩니다.
# This prototype makes it a compilation error to call this function with anything
# that isn't an array. Additionally, arrays are automatically turned into arrayrefs
sub receives_arrayrefs(\@\@) {
my $x = shift;
my $y = shift;
}
my @a = (1..3);
my @b = (1..4);
receives_arrayrefs(@a, @b); # okay, $x = \@a, $y = \@b, @_ = ();
receives_arrayrefs(\@a, \@b); # compilation error, "Type … must be array …"
BEGIN { receives_arrayrefs(\@a, \@b); }
# Specify the sigil to ignore the prototypes.
&receives_arrayrefs(\@a, \@b); # okay, $x = \@a, $y = \@b, @_ = ();
&receives_arrayrefs(@a, @b); # ok, but $x = 1, $y = 2, @_ = (3,1,2,3,4);