2009-08-31 3 views
12

@a = @b || @c 할당의 회선 변형을 수행하고 비어 있지 않은 경우 @b을 취하려고합니다 (따라서 부울 감각으로는 true). 그렇지 않은 경우 @c입니다. 설명서에 명시 적으로 내가 할 수 없다고 알려줍니다. (그리고 너무, 바로 사실에 관하여!)@b ||를 할당 할 수없는 이유는 무엇입니까? @c에서 @a로 Perl로?

은 "||", "//"와 "& &"연산자 ( 을 평가 마지막 값을 반환 C의 "||"와 "& & 달리 ", 0 또는 1을 반환).

가 [...] 특히

, 이것은 당신이 과제에 대한 둘 사이의 집계를 선택하는이를 사용하지 말아야한다는 것을 의미 : 불행하게도

@a = @b || @c;    # this is wrong 
@a = scalar(@b) || @c;  # really meant this 
@a = @b ? @b : @c;   # this works fine, though 

은 정말하지 않습니다 이유를 말해줘.

  • @a = 오른쪽에리스트 문맥을 유도, 배열 할당입니다 : 나는 일어날 것 예상 무엇

    이 있었다.

  • @b || @c은 목록 컨텍스트에서 평가되는 오른쪽입니다.
  • ||은 C 스타일의 단락 논리 또는. 왼쪽에서 오른쪽으로 (필요한 경우) 평가하고 컨텍스트를 전파합니다.
  • @b은 목록 컨텍스트에서 평가됩니다. true (즉,, 비어 있지 않은 경우)가 반환됩니다.
  • 그렇지 않은 경우 @c도 목록 컨텍스트에서 평가되고 반환됩니다.

명백하게 말하면, 나의 어미에서 두 번째 나오는 말은 틀립니다. 왜? 더 중요한 것은 문서 또는 소스의 어느 부분이이 동작을 설명 하는가?

추 신 : 문제의 범위에서 벗어난 이유는 설명서의 삼항 연산자 사용에 대한 제안이 내 @b이 실제로 임시 (함수 호출 결과)라는 것입니다.

+2

"정말로 이것을 의미합니다"라는 줄은 이유를 알려줍니다. –

+0

그게 왜 나보다. 하지만 편견이 있어요. –

+1

나는이 주석이 "정말로 이것을 의미한다"는 것을 "정말로 이것을 의미한다"라고 바꾸어야한다고 생각한다. 그것이 그렇듯이 저는 스칼라()가 @a를 @b와 같게 만들려고합니다. 즉 저자가 정말로 사용하는 것으로 보이는 것입니다. 분명히 그렇지 않습니다. 대신 첫 번째 줄은 실제로 두 번째 줄을 의미합니다. 둘 다 원하는 결과를 얻지 만 원하는 답변은 아닙니다. – Rini

답변

7

논리 연산자 ("||")는 스칼라 컨텍스트에서 왼쪽 인수를 계산합니다.

이렇게하는 이유는 인수가 true인지 확인하는 것입니다. 부울 컨텍스트는 스칼라 컨텍스트의 특수한 경우로서이를 스칼라 컨텍스트로 강제합니다.


perldoc perlop"C-style-Logical-Or"

이진수 "||"는 논리 OR 연산 단락을 행한다. 즉, 왼쪽 피연산자가 인 경우이면 오른쪽 피연산자는 평가되지 않습니다. ...


"Scalar values"perldoc perldata에서 :

.... 부울 컨텍스트 문자열이나 숫자로 변환하는 변환 이제까지 수행되지 않습니다 스칼라 컨텍스트의 단지 특별한 종류이다.

 
Binary "||" performs a short-circuit logical OR operation. That is, 
if the left operand is true, the right operand is not even evaluated. 
Scalar or list context propagates down to the right operand if it is 
evaluated. 

이 명시 적으로 나열하는 컨텍스트는 왼쪽 피연산자에 전파되지 않는 상태하지 않지만, perlop 국가의 최고 : perlop에서

+0

당신은 내가 찾고있는 해답을 알고 있습니다. 나는 perldata에서 이것을 발견했습니다 : "Boolean 컨텍스트는 문자열이나 숫자로의 변환이 수행되지 않는 스칼라 컨텍스트의 특별한 종류입니다." 이유 ("그것이 사실인지"를 알아야 할 필요가 있음)는 다소 나에게 모호한 것처럼 보입니다. –

+0

값은 true 또는 false 일 수 있지만 집계는 할 수 없습니다. 집합체의 경우 "true"는 일반적으로 "비어 있지 않은"것을 의미합니다. 스칼라 컨텍스트에서 집계를 평가할 때 집계가 비어 있으면 false이고 그렇지 않으면 false가됩니다. –

+0

@Michael : 당신이 말한 것은 모두 주변의 설명과 일치하지만, 진실/허위에 관한 펄신의 단락에 다소 마법적이고 (즉, 설명 할 수없는) 모순되는 것처럼 보입니다. "빈 목록은 거짓이고, 무엇이든 else is true "입니다. 사실을 받아 들일 필요가있는 관련 정보는 Brad에 의해 "스칼라에 대한 부울 평가 강제"로 나타났습니다. 펄린 (Perlsyn)으로부터의 단순한 공제, IMO. –

7

, 몇 단락 섹션 전에 인용 :

 
With very few exceptions, these all operate on scalar values 
only, not array values. 

그래서 우리는 오른쪽 피연산자에 규칙에 예외가되는 전파 그 목록의 컨텍스트 및 왼쪽의 상황에 대한 진술의 부족을 가정 할 수있다 피연산자는 일반 규칙이 적용됨을 의미합니다.

2

왜냐하면 || ? :의 테스트 인수와 마찬가지로 스칼라 컨텍스트에서 왼쪽을 평가합니다. 직접 조건 연산자를 사용할 수없는 경우

sub or_array (\@\@) { 
    return @{$_[0]} if (scalar @{$_[0]}); 
    return @{$_[1]}; 
} 

@a = or_array(@b, @c); 
+0

의심의 여지가 perl6에 돌보는 연산자가 있습니다. :) – Ether

0

, 쉽게 약간-덜 간결 사용할 수 있습니다 :

my $ref_b = [ @b ]; # Ideally, just return an arrayref from your function 
my @a = @$ref_b ? @$ref_b : @c; 

당신이 원을 사용할 수 없습니다 경우, 함수를 사용 위의 대답에 따르면 ||의 왼쪽이 평가되는 논리적 컨텍스트가 스칼라 컨텍스트이므로 @b이 실제로 scalar(@b)이되고 그 결과가 @a으로 할당되므로 코드가 작동하지 않습니다.

관련 문제