엄격 및 경고를 사용하는 이유는 무엇입니까?


104

사람들이 다음을 사용하면 Perl 태그의 많은 질문을 해결할 수있는 것 같습니다.

use strict;
use warnings;

어떤 사람들은 이것이 훈련 휠이나 불필요한 합병증과 비슷하다고 생각한다고 생각합니다. 이는 매우 숙련 된 Perl 프로그래머조차도 사용하기 때문입니다.

Perl에 능숙한 대부분의 사람들은 항상이 두 가지 pragma를 사용하는 반면,이를 사용하여 가장 많은 혜택을받는 사람들은 거의 사용하지 않는 것 같습니다. 그래서 사람들을 use strict,에 격려 할 때 링크 할 질문이 있으면 좋겠다고 생각했습니다 warnings.

그럼, 왜해야 펄 개발자 use strictwarnings?


14
나는 항상 이것과 같은 것들에 대해 궁금해합니다. 왜 그들이 그것을 기본값으로 만들지 않고 개발자가 실제로 물건을 적극적으로 느슨하게해야하는 이유는 무엇입니까use loose;
Paul Tyng

12
많은 멋지고 유용한 것들처럼 Perl은 그것을 발명 한 사람을위한 도구로서 해킹으로 시작했습니다. 나중에 그것은 더 인기를 얻었고 점점 더 많은 수의 비 숙련자들이 그것을 사용하기 시작했습니다. 이것은 use strict좋은 생각이라고 생각하기 시작했지만 이전 버전과의 호환성은 이미 당신에게 진정한 문제가되었습니다 .- (
Daniel Böhmer

14
@JB Nizet, @Paul T., Actually use strict;는 Perl 5.12 (또는 그 이상) 언어를 요청할 때 기본적으로 켜져 있습니다. 시도해보십시오 perl -e"use v5.012; $x=123;". no strict;실제로 그것을 끕니다.
ikegami 2011

1
결국 당신의 요점은 사실이지만, 우리가 더 많이 말할수록 더 많은 사람들이들을 것입니다. 최근에 더 많은 / 더 나은 / 현대적인 Perl 튜토리얼을 사용하기 위해 약간의 소란 스러움이 있었고 확실히 엄격한 / 경고가 이들 각각의 상단에있을 것입니다. 제 경우에는 모든 스 니펫의 상단에 소프트웨어를 추가하여 모든 초보자가 매번 볼 수 있도록 할 계획입니다
Joel Berger 2011

5
@JoelBerger 아니요, 실제로는 그것과 전혀 다릅니다. 내가 말했듯이 제목에 비슷한 단어 만 있습니다. 이전 버전과의 호환성을위한 것입니다. 받아 들인 대답의 첫 번째 문장이 내 질문에 어떻게 적용됩니까?
TLP 2011

답변:


83

우선, use strict;(그리고 조금 적게, use warnings;) 변수 이름에 오타를 찾을 수 있습니다. 경험 많은 프로그래머조차도 그러한 오류를 범합니다. 일반적인 경우는 코드를 정리하거나 리팩토링 할 때 변수 인스턴스의 이름을 바꾸는 것을 잊는 것입니다.

를 사용하면 use strict; use warnings;그렇지 않은 경우 발견되는 것보다 더 빨리 많은 오류를 발견하므로 오류의 근본 원인을 쉽게 찾을 수 있습니다. 근본 원인은 오류 또는 유효성 검사가 필요하기 때문일 수 있으며 이는 프로그래머의 기술에 관계없이 발생할 수 있습니다.

Perl 경고의 장점은 거의 가짜가 아니므로 사용하는 데 비용이 거의 들지 않는다는 것입니다.


관련 자료 : 왜 사용 my합니까?


2
@TLP, 나는 그것이 얼마나 도움이되는지 정량화하기 위해 연구를하지 않을 것입니다. 무조건 돕고 있다고 말하는 것으로 충분합니다.
ikegami 2011

1
왜 그렇게 많은 이점이 있다면 선택 사항으로 만들까요? (위에 언급 한 사람처럼) 기본적으로 활성화하지 않는 이유는 무엇입니까? 호환성 이유 때문입니까?
Jean

4
@Jean, 이전 버전과의 호환성. 참고 use strict;이 버전 5.12 또는 언어의 새로운를 사용하는 경우 기본적으로 활성화되어 있습니다 ( use 5.012;).
ikegami 2013 년

간단한 스크립트를 작성하는 경우 @Jean 당신은 정말 파일 핸들러 이름에 대한 또는 :-)를 사용하기 전에 변수를 선언하지 않는 경고로 경고를받을 싶지 않아
user2676847

28

분명히 use strict(필수)는이 선언을 강제 할 수있는 제대로 코드에 힘 펄을 할 때 문자열과 잠수정에 명시되고, 사용할 수는 barewords을 즉 또는주의 심판을 사용한다. 참고 : 오류가있는 경우 strict를 사용하면 사용되는 경우 실행이 중단됩니다.

use warnings;세미콜론을 놓친 것과 같은 프로그램에서 입력 실수를 찾는 데 도움이 되지만 'elsif'가 아닌 'elseif'를 사용했습니다. 사용되지 않는 구문이나 함수를 사용하고 있습니다. 참고 : 경고 사용은 경고 만 제공하고 실행을 계속합니다. 즉, 실행을 중단하지 않습니다.

어쨌든 아래에서 자세히 설명하는 것이 더 나을 것입니다.

에서 perl.com (내가 좋아하는) :

엄격한 'vars'를 사용하십시오.

즉, 변수를 사용하기 전에 항상 변수를 선언해야합니다.

선언하지 않으면 선언되지 않은 변수에 대한 오류 메시지가 표시됩니다.

전역 기호 "$ variablename"에는 scriptname.pl 행 3에 명시적인 패키지 이름이 필요합니다.

이 경고는 Perl이 변수의 범위에 대해 정확히 명확하지 않다는 것을 의미합니다. 따라서 변수에 대해 명시해야합니다. 즉, 변수를 선언 my하여 현재 블록으로 제한하거나 정규화 된 이름 (예 : $ MAIN :: variablename)으로 참조해야합니다.

따라서 다음 기준 중 하나 이상을 충족하지 않는 변수에 액세스하려고하면 컴파일 타임 오류가 트리거됩니다.

  • @ARGV, % ENV와 같은 Perl 자체 및 $와 같은 모든 전역 구두점 변수에 의해 미리 정의됩니다. 또는 $ _.

  • our (글로벌 용) 또는 my (어휘 용)로 선언되었습니다.

  • 다른 패키지에서 가져 왔습니다. (사용 vars pragma는 가져 오기를 위조하지만 대신 사용합니다.)

  • 패키지 이름과 이중 콜론 패키지 구분 기호를 사용하여 정규화되었습니다.

엄격한 '구독자'를 사용하십시오.

두 가지 프로그램 고려

# prog 1
   $a = test_value;
   print "First program: ", $a, "\n";
   sub test_value { return "test passed"; }
 Output: First program's result: test_value

# prog 2
   sub test_value { return "test passed"; }
   $a = test_value;
   print "Second program: ", $a, "\n";
 Output: Second program's result: test passed

두 경우 모두 test_value () 하위가 있고 그 결과를 $ a에 넣고 싶습니다. 그러나 두 프로그램을 실행하면 두 가지 다른 결과가 나타납니다.

첫 번째 프로그램에서 우리가에 도달하는 시점 $a = test_value;에서 Perl은 test_value () 하위를 알지 못하며 test_value는 문자열 'test_value'로 해석됩니다. 두 번째 프로그램에서 test_value ()의 정의는 $a = test_value;줄 앞에옵니다 . Perl은 test_value를 하위 호출로 생각합니다.

subs 일 수 있고 컨텍스트에 따라 문자열 일 수있는 test_value와 같은 격리 된 단어의 기술 용어는 bareword 입니다. Perl의 베어 워드 처리는 혼란 스러울 수 있으며 프로그램에서 버그를 유발할 수 있습니다.

버그는 우리가 첫 번째 프로그램에서 만난 것입니다. Perl은 찾을 것을 기대하지 않을 것입니다 test_value(). 따라서 아직 test_value ()를 보지 못했기 때문에 문자열을 원한다고 가정합니다. 따라서이 use strict subs;프로그램은 오류와 함께 종료됩니다.

Bareword "test_value"는 ./a6-strictsubs.pl 행 3에서 "strict subs"를 사용하는 동안 허용되지 않습니다.

이 오류에 대한 해결책은
1입니다. 괄호를 사용하여 하위를 호출하고 있음을 명확히합니다. Perl에 $ a = test_value ();가 표시되면
2. 처음 사용하기 전에 하위를 선언합니다.

use strict;
sub test_value;  # Declares that there's a test_value() coming later ...
my $a = test_value;  # ...so Perl will know this line is okay.
.......
sub test_value { return "test_passed"; }

3. 그리고 그것을 문자열로 사용하려는 경우 인용하십시오.

따라서 이러한 제한으로 인해 Perl은 모든 베어 워드를 구문 오류로 취급합니다. * 베어 워드 는 컨텍스트에 의해 강제되는 다른 해석이없는 이름 또는 식별자입니다. (컨텍스트는 종종 근처의 키워드 나 토큰 또는 해당 단어의 사전 선언에 의해 강제됩니다.) * 따라서 문자열로 사용하려는 경우 인용하고 함수 호출로 사용하려는 경우 사전 선언 또는 괄호를 사용하십시오.

베어 워드는 이러한 예측할 수없는 동작으로 인해 위험합니다. use strict; (or use strict 'subs';)미래에 이상한 동작을 유발할 수있는 베어 워드는 프로그램이 혼란을 일으키기 전에 죽게 할 것이기 때문입니다.

엄격한 구독을 켰을 때도 베어 워드를 사용해도 괜찮은 곳이 있습니다 : 해시 키를 할당 할 때입니다.

$hash{sample} = 6;   # Same as $hash{'sample'} = 6
%other_hash = ( pie => 'apple' );

해시 키의 베어 워드는 항상 문자열로 해석되므로 모호성이 없습니다.

엄격한 'refs'를 사용하십시오.

의도적 으로든 아니든 기호 참조를 사용하면 런타임 오류가 발생합니다. 하드 참조가 아닌 값은 기호 참조 로 처리됩니다 . 즉, 참조는 전역 변수의 이름을 나타내는 문자열로 해석됩니다.

use strict 'refs';

$ref = \$foo;       # Store "real" (hard) reference.
print $$ref;        # Dereferencing is ok.

$ref = "foo";       # Store name of global (package) variable.
print $$ref;        # WRONG, run-time error under strict refs.

경고를 사용하십시오.

이 어휘 범위의 pragma를 사용하면 Perl의 내장 경고 (컴파일러와 런타임 시스템의 경고 모두)를 유연하게 제어 할 수 있습니다.

에서 perldiag:

따라서 아래 분류, 즉 W, D & S의 대부분의 경고 메시지는 warningspragma를 사용하여 제어 할 수 있습니다 .

(W) 경고 (선택 사항)
(D) 사용 중단 (기본적으로 활성화 됨)
(S) 심각한 경고 (기본적으로 활성화 됨)

자주 발생하는 경고 메시지를 분류별로 아래에 나열했습니다. 이들 및 기타 메시지에 대한 자세한 정보는 perldiag 를 참조하십시오.

(W) 경고 (선택 사항) :

% s에
인수가 없습니다.-% c에 인수가 없습니다
(대신 & % s을
(를) 의미 했습니까 ?) ( "our"대신 "local"
을 의미 했습니까 ?) (% 대신 $ 또는 @를 의미 했습니까?)
'% s '은 코드 기준 아니다
%의 사용 길이 ()
숫자 _가 잘못된

(D) 지원 중단 (기본적으로 활성화 됨) :

defined (@array) is deprecated
defined (% hash) is deprecated
my () in false conditional
$ # is no longer supported

(S) 심각한 경고 (기본적으로 활성화 됨)

elseif는
연산자가 예상 한 위치에서 elsif % s을 (를) 찾았습니다
(% s 앞에 연산자가 없습니까?)
(이전 줄에 세미콜론이 없습니까?)
% s이 (가 ) % s
전에 연산자 또는 세미콜론이 누락 됨
우선 순위 문제 : 열려있는 % s가 열려 있어야합니다 (% s).
프로토 타입 불일치 : % s 대 % s
경고 : 괄호없이 "% s"를 사용하는 것은 모호합니다
. % s을 (를) 열 수 없습니다. % s


10

이 두 pragma는 코드의 버그를 자동으로 식별 할 수 있습니다.

나는 항상 내 코드에서 이것을 사용합니다.

use strict;
use warnings FATAL => 'all';

FATAL경고로 인해 코드가 죽도록 만듭니다 strict.

추가 정보는 다음을 참조하십시오. 사용 경고로 더 엄격하게하기 FATAL => 'all';

또한 ... Seuss에 따르면 협착


실제로, 컴파일러 FATAL => "all"에 할당 $SIG{__WARN__} = sub { croak "fatalized warning @_" };하거나 필요한 것을 알려 주려고하는 컴파일러를 망쳐 서 런타임까지 지연 시켜야합니다.
tchrist

6
@tchrist : 이것은 항상 저에게있는 그대로 그리고 문서화 된대로 일했습니다. 문서화 된대로 작동하지 않는 경우를 발견 한 경우를 사용하여 문서를 패치하십시오 perlbug.
toolic 2011


3

출처 :: 다른 블로그

Use는 모듈 import () 함수를 호출하여 함수와 변수 이름을 기본 네임 스페이스로 내 보냅니다.

pragma는 컴파일 시간 또는 perl의 런타임 동작에 영향을 미치는 모듈입니다 .Pragma는 컴파일러에 힌트를 제공합니다.

경고 사용-한 번만 사용 된 변수에 대한 펄 불만, 문자열을 숫자로 부적절하게 변환, 열지 않은 파일에 쓰려고하면 컴파일 타임에 발생합니다. 경고를 제어하는 ​​데 사용됩니다.

엄격한 사용-변수 범위를 선언합니다. 스크립트에서 어떤 종류의 규율을 설정하는 데 사용됩니다. 코드에서 베어 워드를 사용하면 해석됩니다. 모든 변수에는 my, our 또는 local과 같은 범위가 지정되어야합니다.


1

"use strict"지시문은 Perl에게 코드를 컴파일하는 동안 추가 검사를 수행하도록 지시합니다. 이 지시문을 사용하면 다른 방법으로 간과 할 수있는 일반적인 코딩 버그를 찾아 내기 때문에 Perl 코드 디버깅 시간을 절약 할 수 있습니다.


0

엄격한 경고는 변수가 전역 적이 지 않은지 확인합니다.

각각의 모든 변수 이름을 추적 할 필요없이 개별 메서드에 대해 고유 한 변수를 가질 수있는 것이 훨씬 더 깔끔합니다.

$ _ 또는 특정 함수에 대한 변수 없음은보다 간결한 코드를 더 빨리 작성하는 데 유용 할 수 있습니다.

그러나 엄격 및 경고를 사용하지 않으면 $ _이 전역이됩니다!


0
use strict;
use warnings;

엄격함과 경고는 perl 프로그램의 모드입니다. 사용자가 코드를보다 자유롭게 입력 할 수있게하여 그 이상으로 펄 코드가 형식적으로 보이고 코딩 표준이 효과적 일 것입니다.

경고 -w는 perl shebang 라인 과 같은 의미 이므로 perl 프로그램에서 생성 된 경고를 제공하고 터미널에 표시합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.