Perl Count 인수 만들기

8507 단어 perl
많은 프로그래밍 언어와 달리 Perl은 함수가 올바른 수의 인수로 호출되는지 확인하지 않습니다. 이는 Perl 서브루틴이 기본적으로 가변적이어서 많은 프로그래밍 작업을 정말 쉽게 만들기 때문입니다. 단점은 많은 시간 함수가 특정 수의 인수로 호출되는 경우에만 의미가 있다는 것입니다.

대부분의 경우 잘못된 수의 인수로 서브루틴이 호출되는 경우는 프로그래머가 단순한 오타를 범했기 때문입니다. 프로그래머로서 우리의 삶을 더 쉽게 하기 위해, 우리가 이 상황을 감지하고 무엇이 잘못되었는지에 대한 명확한 오류 메시지를 줄 수 있다면 좋을 것입니다.

우리는 이 문제에 대한 해결책을 모색할 것입니다.

경고: 이 문서의 예제는 명령줄에서 Perl을 호출합니다. Perl 명령줄 구문을 이해하지 못하는 경우 -E 다음에 나오는 내용에만 주의하십시오.

예를 살펴보겠습니다.

package T;

sub num_diff {
    my $n1 = shift;
    my $n2 = shift;
    return abs($n1 - $n2);
}

1;


두 개의 인수로 호출하면 함수가 예상대로 작동합니다.

$ perl -W -I. -MT -E 'say T::num_diff(7, 17)'
10

하지만 두 개 이상의 인수로 num_diff를 호출하면 어떻게 될까요?

$ perl -W -I. -MT -E 'say T::num_diff(23, 21, 48)'
2

Perl은 3개의 인수로 이 함수를 호출하는 경우 문제가 없으며 처음 두 인수 간의 차이를 기쁘게 반환합니다. 이것은 나쁘다! 세 숫자의 차이는 처음 두 숫자의 차이가 아닙니다.

이 문제를 처리하는 좋은 방법은 서브루틴 인수 선언을 위한 구문을 제공하는 signatures 을 사용하는 것입니다. 서명을 사용하여 num_diff를 다시 작성해 보겠습니다.

package T;

use v5.20;
use feature 'signatures';

sub num_diff($n1, $n2) {
    return abs($n1 - $n2);
}

1;


3개 이상의 인수로 num_diff를 호출하면 어떤 일이 발생하는지 살펴보겠습니다.

$ perl -I. -MT -E 'say T::num_diff(22, 33, 8)'
Too many arguments for subroutine 'T::num_diff' (got 3; expected 2) at -e line 1.

굉장합니다. 문제가 해결되었습니다! 서명을 사용하여 Perl은 서브루틴 인수를 계산할 수 있고 실수할 때 오류 진단을 제공할 수 있습니다.

불행히도 서명에는 몇 가지 단점이 있습니다. 첫 번째 서명은 Perl 버전 5.20까지는 존재하지 않았으므로 이전 Perl 서명을 사용하는 경우 옵션이 아닙니다. 다른 단점은 서명이 Perl 버전 5.36까지 실험적이어서 use feature 'signatures' 문이 필요한 이유입니다.

저는 Perl 버전 5.16.3을 사용하는 Perl 프로젝트에서 작업 중이므로 서명을 사용할 수 없습니다. 인수를 계산하기 위해 올바른 수의 인수를 받지 못한 경우 프로그램을 종료하는 서브루틴의 첫 번째 명령문으로 호출하는 함수를 작성했습니다.

use Carp 'confess';

sub arg_count_or_die {

    # Carp::Confess unless $num_args is in range $lower-$upper

    my $lower    = shift;
    my $upper    = shift;
    my $num_args = @_;

    ($lower, $upper) = ($upper, $lower) if $lower > $upper;

    unless ($lower <= $num_args && $num_args <= $upper) {
        my $caller = ( caller(1) )[3];
        my $expected_plural = $lower == 1 ? '': 's';
        my $got_plural = $num_args == 1 ? '' : 's';
        my $arg_range_msg = $lower == $upper ? "$lower arg$expected_plural" : "$lower-$upper args";
        confess("yabsm: internal error: called '$caller' with $num_args arg$got_plural but it expects $arg_range_msg");
    }


    return 1;
}


이 함수를 사용하기 위해 다시 작성해 보겠습니다num_diff.

sub num_diff {

    arg_count_or_die(2, 2, @_);

    my $n1 = shift;
    my $n2 = shift;

    return abs($n1 - $n2);
}


다시, 2개 이상의 인수를 사용하여 num_diff를 호출합니다.

$ perl -I. -MT -E 'say T::num_diff(22, 33, 8)'
my-program: internal error: call to 'T::num_diff' passed 3 args but expects 2 args at T.pm line 19.
        T::arg_count_or_die(2, 2, 22, 33, 8) called at T.pm line 27
        T::num_diff(22, 33, 8) called at -e line 1

Carp::Confess를 사용하면 erroneus 서브루틴 호출로 이어지는 호출 스택을 보여주는 훌륭한 오류 메시지를 얻을 수 있습니다. 오류 메시지에 my-program: internal error 접두사를 붙여 이 오류가 발생하면 사용자는 버그를 발견했음을 알고 디버깅에 매우 유용한 스택 추적을 보낼 수 있습니다.

좋은 웹페이지 즐겨찾기