수색…


비고

서브 루틴은 인수를 @_ 이라는 마법 변수에 전달합니다. 압축을 풀 필요가 없지만 가독성을 @_ 인수가 참조로 전달 (수정 가능)되어 우발적 인 변경을 방지하기 때문에 권장됩니다.

서브 루틴 만들기

서브 루틴은 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);
5.20.0

또는 실험적 피쳐 "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 &sum; # 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.
5.18.0

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 &prod; # 1
}
say defined &prod; # 0
5.20.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);


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow