2014-01-11 2 views
4

나는 문맥을 호출하는 것에 달려있는 함수를 가지고 있는데이 함수를 다른 함수의 인자로 사용하고 싶었다. 놀랍게도이 second 함수가 목록 컨텍스트에서 호출되었음을 발견했습니다. +()과 강제 스칼라 컨텍스트를 시도했지만 예상대로 작동하지 않습니다. 따라서 암시 적으로 scalar으로 호출하는 것이 유일한 방법입니다.함수 인수가 목록 컨텍스트를 유도하는 이유는 무엇입니까?

use 5.010; 

say first(1, second('y')); 
say first(1, +(second('y'))); 
say first(1, scalar second('y')); 

sub first { 
    my $x = shift; 
    my $y = shift; 

    return "$x + $y"; 
} 

sub second { 
    my $y = shift; 

    if (wantarray) { 
    qw/ array array /; 
    } else { 
    'scalar'; 
    } 
} 
__END__ 
1 + array 
1 + array 
1 + scalar 

함수의 인수는 목록으로 취급되지만 해당 목록의 모든 인수도 목록 컨텍스트를 의미합니까? 그렇다면 왜?

그리고, scalar의 작품을 사용하지만 다른 방법으로 나는 중간 변수가없는 스칼라 컨텍스트에서이 함수를 호출해야합니까?

답변

4

왜 함수 인수가 목록 컨텍스트를 유도합니까?

서브 루틴은 가변 개수의 스칼라를 인수로 허용합니다.다른 선택의 여지가 있습니까?

함수의 인수는 목록으로 취급되지만 해당 목록의 모든 인수도 목록 컨텍스트를 의미합니까? 그렇다면 왜?

예. 해시 및 배열의 ​​내용에서 목록을 작성할 수 있기를 원하기 때문입니다. 그게 왜 유용한 지 수많은 이유가 있습니다.

%h = (%h, ...); # Add to a hash 
f($x, @opts); # Composing argument lists 
etc 

scalar 작품을 사용하지만, 다른 한 가지 난 (중간 변수없는) 스칼라 문맥이 함수를 호출해야?

킨다.

say first(1, "".second('y')); # Side-effect: stringification 
say first(1, 0+.second('y')); # Side-effect: numificatiion 
say first(1, !!second('y'));  # Side-effect: conversion to boolean 

Subrountine 프로토 타입은 스칼라 문맥을 적용 할 수 있지만, 일반적으로 바로 그 이유 때문에 나쁜 볼 수 있습니다.

+0

내 대답에 추가되었습니다. – ikegami

+0

물론 목록의 모든 구성원도 목록 일 수 있으므로 선택의 여지가 많지 않습니다. 생각하지 않았어. 고맙습니다! –

7

그것은 인수가리스트 문맥에서 평가하는 기능을 의미합니다 : 펄에서

  • 을, 모든 서브 루틴은 목록에 목록을 매핑합니다.

  • 하위가 목록을 취하는 경우 목록 컨텍스트에서 모든 인수를 평가하면 의 조합을으로 만들 수 있습니다. map 고려 : 우리는 목록 1, 2, 3을 반환하고자 할 때

    map { ... } 1, 2, 3; # makes sense 
    map { ... } foo(); # can we "return 1, 2, 3" for the same effect? 
    

    foo() 스칼라 문맥에서 호출해야

    ,이 return 3에 해당 될 것이다. 리스트 컨텍스트를 사용하면 많은 명시 적 루프없이리스트 변환을 작성할 수 있습니다. 같은 스칼라 문맥을 강제 식을 사용

    • :

      my @sorted = 
          map { $_->[1] } 
          sort { $a->[0] <=> $b->[0] } 
          map { [make_key($_), $_] } 
          @input; 
      

    목록 문맥에 인수를 평가하는 두 가지 방법이 다음과 같습니다 찌언 변환이의 좋은 예입니다 scalar 또는 스칼라 연산

  • 프로토 타입($)과 같이 사용하십시오. 이것은 함수의 조합 가능성을 파괴하고, 서브 루틴을 미리 선언하고, 혼동하는 의미를 가질 수 있으며,에서 액션을 수행해야합니다. 따라서 프로토 타입을 피해야합니다.

귀하의 +(...)단항 플러스는 컨텍스트를 부과하지 않기 때문에 스칼라 문맥을 강제하지 않았다. 이것은 기능 애플리케이션 (예 : 응용 프로그램)에서 괄호 (예 : 우선 순위에 사용됨)를 모호하게하는 데 일반적으로 사용됩니다. map +($_ => 2*$_), 1, 2, 3.

단항 플러스는 피연산자에 스칼라 컨텍스트를 적용하고 숫자에 강제 변환하는 산술 연산자 인 이진 플러스와 구별됩니다.

관련 문제