2012-02-06 4 views
7

Perl에서 단일 변수를 큰 따옴표 (연결 없음)로 캡슐화 할 이유가 있습니까?perl은 단일 변수를 큰 따옴표로 묶습니다.

나는 종종 (여기서 일하지 않는 사람들이 10 년 전 writen 이상) 내가 작업하고있는 프로그램의 소스에서 이것을 발견 : 지금까지 내가 거기에 알고

my $sql_host = "something"; 
my $sql_user = "somethingelse"; 

# a few lines down 
my $db = sub_for_sql_conection("$sql_host", "$sql_user", "$sql_pass", "$sql_db"); 

은 이유 없다 이것을하기 위해. 예전 스크립트에서 작업 할 때 나는 일반적으로 따옴표를 지우지 않으므로 편집자가 텍스트가 아니라 변수로 표시됩니다.

나는 어딘가에서 이것을보고 생각이 왜곡 된 스타일을 복사했다고 생각합니다. 내가 놓친 게 있니?

감사합니다.

+2

답변이 여기에 표시하기 때문에 좋은 질문입니다 만 예전의 코드를 다시 인수 분해 할 때 어떻게해야 조심 - 처음에는 나쁜 스타일로 보일만한 좋은 이유가있을 수 있습니다. – tangent

답변

7

이 모든 것은 명시 적으로 변수를 문자열 화합니다. 99.9 %의 경우, 그것은 일종의 초보자 오류입니다.여기

my $foo = "1234"; 
sub bar { $_[0] =~ s/2/two/ } 
print "Foo is $foo\n"; 
bar("$foo"); 
print "Foo is $foo\n"; 
bar($foo); 
print "Foo is $foo\n"; 

는 문자열 화 (stringification)는 복사본을 생성하고, 서브 루틴, 참조 시멘틱스에 의해 펄의 패스를 우회하는 것을 통과 :

이 호출 스타일의 부작용으로 발생할 수 있습니다 일이 있습니다. 변수를 호출하는 것은 일반적으로 나쁜 매너로 간주되므로 괜찮을 것입니다.

여기에서 개체 또는 다른 값을 문자열로 지정할 수도 있습니다. 예를 들어 undef은 빈 문자열로 문자열을 나타냅니다. 객체는 문자열 화 될 때 실행할 임의의 코드를 지정할 수 있습니다. 별개의 수치 및 문자열 값을 갖는 이중 값 스칼라를 가질 수 있습니다. 이것은 문자열 형식을 지정하는 방법입니다.

계속 진행될 수있는 깊은 유령 같은 일도 있습니다. 함수에 대한 스칼라 인수에 설정된 플래그를 보는 XS 코드로 작업하는 경우 스칼라를 문자열로 변환하는 것은 perl에 "스트레스가있는 플래그만으로 멋진 새 문자열 값을 만듭니다" 숫자 플래그가 없습니다.

99.9 % 규칙에 대한 다른 예외가 있다고 확신합니다. 이것들은 몇 가지입니다. 따옴표를 제거하기 전에 잠시 시간을내어 이상한 똥을 확인하십시오. 합법적 인 사용법에 따라 일이 생기면, 따옴표를 실행 가능한 kludge로 식별하는 주석을 추가하고 그 이유를 제시하십시오.

+0

Re "함수에 대한 스칼라 인수에 설정된 플래그를 보는 XS 코드로 작업하는 경우"이전에 Pure Perl 예제를 보여 줬습니다. 'ref()'를 사용하는 것으로 충분할 것이다. – ikegami

6

큰 따옴표는 필요하지 않습니다. 또한 원본 문자열을 복사 할 때 비효율적입니다.

그러나 때때로이 스타일을 사용하여 개체를 "문자열 화"할 수 있습니다. 예를 들어, URI ojects는 문자열 화 (stringification) 지원 : 나는 이유를 알고하지 않습니다

my $uri = URI->new("http://www.perl.com"); 
my $str = "$uri"; 
+0

경고가 활성화되어 있지 않으면 조용히 'undef'를 빈 문자열로 바꿉니다. 그렇지 않습니까? 그래도 유효한 사용이라고는하지는 않겠지 만, 경고 없이는 아무 것도 고려하지 않았을 것입니다. –

+0

@mu가 너무 짧습니다 : yes, undef는 (경고가 활성화되었는지 여부에 관계없이) ""'가됩니다. –

+0

경고와 함께 조용히 가지 않으므로 "초기화되지 않은 값의 연결"불만 사항이 표시됩니다 . –

6

을하지만, 일반적으로 펄에 이민자에 의해 사용되는 패턴입니다. 일반적으로 낭비입니다 (게시 한 스 니펫에 있음).하지만 두 가지 용도를 생각해 볼 수 있습니다.


매우 희귀 한 상황에서 유용 할 수있는 원본과 동일한 값으로 새 문자열을 만드는 효과가 있습니다.

다음 예에서는 하위가 인수를 수정하기 때문에 $ x가 하위에서 수정되지 않도록 명시 적으로 복사가 수행됩니다. 문자열의 복사본을 만드는 미덕으로

$ perl -E' 
    sub f { $_[0] =~ tr/a/A/; say $_[0]; } 
    my $x = "abc"; 
    f($x); 
    say $x; 
' 
Abc 
Abc 

$ perl -E' 
    sub f { $_[0] =~ tr/a/A/; say $_[0]; } 
    my $x = "abc"; 
    f("$x"); 
    say $x; 
' 
Abc 
abc 

, 그것은 개체를 stringifies. 이는 인수가 참조인지 여부에 따라 동작을 변경하는 코드를 처리 할 때 유용 할 수 있습니다.

다음 예제에서는 require@INC에서 문자열과 다르게 참조를 처리하기 때문에 명시적인 문자열이 수행되었습니다.

$ perl -MPath::Class=file -E' 
    BEGIN { $lib = file($0)->dir; } 
    use lib $lib; 
    use DBI; 
    say "ok"; 
' 
Can't locate object method "INC" via package "Path::Class::Dir" at -e line 4. 
BEGIN failed--compilation aborted at -e line 4. 

$ perl -MPath::Class=file -E' 
    BEGIN { $lib = file($0)->dir; } 
    use lib "$lib"; 
    use DBI; 
    say "ok"; 
' 
ok 
+0

첫 번째 경우는 "명시 적 복사로 해결 방법 @_ 별칭"으로 설명 할 수 있습니다. 그런 일을하는 코드에 주석을 추가 할 것을 권장합니다. – dolmen

+0

@dolmen, 예제에 대한 설명이 추가되었습니다. – ikegami

0

저의 이론은 항상 나쁜 습관을 가진 다른 언어에서 사람들이 왔습니다. 그들은 "나는 항상 큰 따옴표를 사용하겠다"고 생각하는 것은 아니지만, 그들은 생각하지 않고있다.

저는 솔직히 말해서 자바에서 펄에 왔기 때문에 저는이 함정에 빠져있었습니다. 그래서 근육 기억이 있었고, 계속 사격을했습니다.

PerlCritic은 마침내 나를 버렸습니다!

확실히 코드를 효율적으로 만들지 만 문자열을 보간 할 것인지 여부를 생각하지 않는다면 어리석은 실수를 범할 가능성이 높습니다. 그래서 나는 더 멀리 가서 위험하다고 말합니다.

2

귀하의 경우 따옴표는 완전히 쓸모가 없습니다. 다른 사람들이 썼 듯이 이것이 관용적이지 않기 때문에 우리는 그것이 잘못되었다고 말할 수 있습니다.

그러나 변수를 인용 할 필요가있을 수 있습니다. 변수의 문자열을 명시 적으로 트리거합니다. 문자열 화가 값이 이중 병인 경우 또는 축복 값인 경우 overload ed stringification을 사용하면 일부 값에 대해 다른 결과가 나올 수 있습니다.

여기

듀얼 바르와 예입니다

use 5.010; 
use strict; 
use Scalar::Util 'dualvar'; 

my $x = dualvar 1, "2"; 
say 0+$x; 
say 0+"$x"; 

출력 :

1 
2 
관련 문제