2016-12-18 5 views
2

저는 맨손 단어를 인용 연산자 (q //, qq //), 해시 키 등에서 문자열로 사용할 수 있다는 것을 알고 있습니다. 나는 정신적 기대를 극복 할 수 없어 개인적으로 너무 흥분하지 않았습니다. 리터럴 문자열은 C, C++ 에서처럼 인용해야합니다. 그러나 따옴표로 묶은 문자열과 벌거 벗어진 단어를 혼용하여 사용하려는 경우 런타임시 실수로 단어가 올바르게 작동하지 않는 발에서 나를 실수로 쏘지 않도록해야합니다.Perl에서 맨손으로 단어를 사용하는 데있어서 함정은 무엇입니까?

'use strict'가 컴파일 타임에 오류로 간주되는 사용 사례는 제외하십시오. 나는 항상 '엄격한'모드를 사용하므로 이러한 경우는 걱정하지 않습니다. 예상대로 해시 키에 대하여, 베어 말은 행동하는 것이

$ ./bare_word.pl 
constant SIZE:const_size 
1. $href->{size}:1 
1a. $href->{size()}:2 
2. $href->{getsize}:2 
3. $href->{SIZE}:LARGE 
3a. $href->{(SIZE)}:CONST_SIZE 

그것은 나타납니다

#!/usr/bin/perl 

use strict; 

use constant SIZE => "const_size"; 

sub size { 
    return "getsize"; 
} 

my $href = { 
    size => 1, 
    getsize => 2, 
    const_size => "CONST_SIZE", 
    SIZE => "LARGE", 
}; 

print "constant SIZE:", SIZE, "\n"; 
print "1. \$href->{size}:", $href->{size}, "\n"; 
print "1a. \$href->{size()}:", $href->{size()}, "\n"; 
print "2. \$href->{getsize}:", $href->{getsize}, "\n"; 
print "3. \$href->{SIZE}:", $href->{SIZE}, "\n"; 
print "3a. \$href->{(SIZE)}:", $href->{(SIZE)}, "\n"; 

출력은 : 아래

제공에 대한 답변과 의견에 따라 코드 그림입니다 모든 경우. 동작을 재정의하려면 명시 적으로 모호성을 제거해야합니다.

+12

'q' 또는'qq' 안에 있다면 * 따옴표로 묶어서 bareword라고 부를 수 없습니다. ('q'는 작은 따옴표와 정확히 같고,'qq'는 정확히 따옴표와 같습니다). – ThisSuitIsBlackNot

+0

@ThisSuitIsBlack 아니, 나는 그것의 외관 때문에 q를 맨손으로 부른다. 그리고 예, 런타임 오류에 대해 묻습니다. – Ltf4an

+1

또 다른 예는 [per-are-per-constants-by-their-values]에 나와 있습니다 (http://stackoverflow.com/questions/41094827/where-are-perl-constants-replaced-by-their- 값/41094880 # 41094880). – zdim

답변

6

Please exclude use cases where 'use strict' would catch them as errors at compile time.

use strict; 완전히 barewords의 사용을 방지 할 수 있습니다. barewords를 허용하면 오타가 매우 조용하게 및/또는 미묘하게 실패 할 수 있습니다.

소문자 barewords는 다음 버전의 Perl에서 함수 호출로 오해 될 수 있지만 그 사실은 아닙니다. 새로운 기능을 say처럼 활성화해야합니다.


그렇긴해도 실제로 자동 인용 해시 키에 대해 이야기하는 것이 좋습니다. $hash{foo()}과 같을 것으로 예상하여 $hash{foo}이라고 쓰면 혼동 될 가능성이 있습니다. 하지만 foo (foo()과 반대)뿐만 아니라 처음에는 서브를 호출하는 이상한 방법이없고 아무도 $hash{foo()}을 처음부터 쓰고 싶지 않습니다. (인수가 반드시 필요합니다.) 코드가 극히 작은 것으로 잘못 해석 될 가능성을 방지하는 유일한 방법은 상수를 해시 키로 사용할 가능성입니다. $hash{CONSTANT}이 실패합니다. 하나는 $hash{(CONSTANT)}, $hash{+CONSTANT} 또는 다른 형태의 모호성 제거를 사용해야합니다.

5

예, 일을 제대로 인용하지 않음으로써 스스로 발을 쏠 수 :

$ perl -MData::Dumper -e' 
    my %h; 
    $h{"foo-bar"} = 1; 
    print Dumper \%h 
' 
$VAR1 = { 
      'foo-bar' => 1 
     }; 

$ perl -MData::Dumper -e' 
    my %h; 
    $h{foo-bar} = 1; 
    print Dumper \%h 
' 
$VAR1 = { 
      '0' => 1 # oops! 
     }; 

그러나, 엄격 모드는 구문 오류로 캐치되지 않는 논리 오류에서이 바뀝니다 :

$ perl -Mstrict -MData::Dumper -e' 
    my %h; 
    $h{foo-bar} = 1; 
    print Dumper \%h 
' 
Bareword "foo" not allowed while "strict subs" in use at -e line 1. 
Bareword "bar" not allowed while "strict subs" in use at -e line 1. 
Execution of -e aborted due to compilation errors. 

합니다. ..unless :

$ perl -Mstrict -MData::Dumper -e' 
    sub foo { 1 } 
    sub bar { 1 } 

    my %h; 
    $h{foo-bar} = 1; 
    print Dumper \%h 
' 
Ambiguous use of -bar resolved as -&bar() at -e line 1. 
$VAR1 = { 
      '1' => 1 # oops! 
     }; 

도덕적 인 이야기? 항상 use strict;이고 항상 identifiers이 아닌 해시 키를 인용하십시오. 식별자에는 문자, 숫자 및 밑줄 만 포함되며 첫 번째 문자는 숫자가 될 수 없습니다.

+0

위의 코드를 실행하면 "모호한 -bar"를 사용하지 않습니다. 내 Perl의 버전은 다음과 같습니다. 이것은 cygwin-thread-multi 용으로 만들어진 perl 5, version 22, subversion 2 (v5.22.2)입니다. 그리고 (% h {foo-bar})의 예는 제가 찾고있는 유스 케이스입니다. 다른 경우가 있습니까? – Ltf4an

+1

@ Ltf4an 경고가 가짜이므로 [5.22.0에서 제거되었습니다] (http://perldoc.perl.org/perl5220delta.html#Diagnostic-Removals). 그것은 중요한 부분은 아니지만. – ThisSuitIsBlackNot

+1

@ Ltf4an 그렇습니다. 뚱뚱한 쉼표 연산자와 비슷한 함정이 있습니다 :'perl -Mstrict -MData :: Dumper -e'sub foo {1} 부 바 {1} my % h = (foo.bar => 1); Dumper \ % h'' – ThisSuitIsBlackNot