Perl의 특수한 + unary operator(단항연산자)
! $x # a unary operator (단항연산자)
$x + $y # a binary operator (이항연산자)
$x ? $y : $z # a trinary operator (삼항연산자)
print $x, $y, $z # a list operator (리스트연산자)
그런데 Perl에서 두 값을 더하는 +는 이항연산자로 쓰이는 것 외에 단항연산자로 쓰이는 특별한 경우가 있다.
print (1+3),5; 의결과는 어떻게 될까?
print
4,5;는 4와 5가 모두 찍히는 데 반해 4만 찍힌다. 이 둘이 어떻게 다른 것인지를 알려면 일단 Perl에서 함수가 작동하는
방식을 이해할 필요가 있다. Perl에서 함수를 호출할 때는 print(1,2);처럼 인자를 ()로 싸서 호출할 수도 있고
print 1,2; 처럼 ()를 싸지 않고 호출할 수 있는데 Perldoc의 perlop문서를 보면 알겠지만 Perl에서는 가장 높은 연산자우선순위를 가지는 것은 Terms 과 리스트연산자(좌측)이며 TERM은
변수, 인용, 유사인용 연산자를 포함하며, 괄호안의 수식, 인자를 괄호로 묶은 함수를 포함한다. 실제적으로 이런 의미에서는 함수란
없으며 단지 함수처럼 쓰이는 리스트 연산자와 단항 연산자가 있을 뿐이기 때문에 이 둘 사이는 차이점이 없다.
예를 든 print 함수는 여기서 문법상 정의가 print LIST;로 LIST를 받는 리스트연산자로 작동하며 다른 예로 배열에서
하나의 요소를 꺼내는 pop은 문법상 정의가 pop ARRAY; 이며 ARRAY 하나를 받는 단항연산자처럼 작동한다.
함수명 바로 다음에 (가 나오면 함수는 )가 나올 때 까지를 인자로 인식하기 때문에 print (1+3),5;에서 print는
1+3=4 하나를 인자로 인식하고 4만 찍고 끝내버리고 ,5 는 void context(결과가 어디에도 저장되지 않고 어떤 다른
용도로도 사용되지 않는 문맥)로 무시된다. 이것은 use warnings; pragma를 쓰면 경고를 해준다.
이런 문제를 해결하려면 명시적으로 ()로 묶어서 print( (1+3),5 ); 이렇게 호출하면 된다. 여기서 또 다르게 함수명
다음에 처음 만나는 (가 함수의 인자를 묶는 괄호가 아니라는 의미로 + 단항연산자를 사용하여 print +(1+3),5; 이렇게
해도 4와 5가 모두 찍힌다. 여기서 +는 아무런 부가동작도 하지 않으며 단지 의미상으로 단지 함수가 받는 인자(들)중 하나의
표현식을 묶는 괄호임을 얘기해주는 것이다. 다른 예를 들면 @ans = sort +(5 + 5)*10, -4; 이런 식으로도
사용가능하다.
그리고 + 단항연산자는 문법적으로 혼돈의 여지가 있을 때 {}가 코드블럭이 아니라 익명해쉬를 뜻하는 것이라는것을 명시적으로 나타내는데도 다음과 같은 용도들로 쓰인다.
my @expect=map +{ key => $_, dirty => 0, },1..5;
return +{ name=>'Tom', number=>1 };
그러면 함수를 호출할 때 어떨 때 ()를 묶어서 호출하고 어떨 땐 없이 호출해야 할까?
Perl 코딩규약을 다루는 책인 Perl Best Practices에서는 다음과 같은 가이드라인을 제시하고 있다.
Perl
builtins(내장함수)나 honorary(Carp,List::Util 등 Core module에 포함된 함수 - 언어 자체에
포함되어야 할 것 같은 함수인데 모듈로서 지원하는 것들)를 호출 할 때는 기본적으로 필요없는 괄호를 붙이지 않고 사용하여
이것들과 여타 모듈함수들 및 서브루틴호출(은 명시적으로 괄호를 묶어서 호출)이 시각적으로 구분되게 하고 위에서 예를 든 print같은 경우처럼
해석상에 혼돈이 있을경우 명시적으로 ()를 붙여주긴 하는데 for, while 같은 control keyword 같이 보이지
않도록 함수명과 (사이는 공백없이 붙여써라.
print ($value1 + $value2), " is the sum of $value1 and $value2 \n"; # 원하는 결과가 안나옴
print +($value1 + $value2), " is the sum of $value1 and $value2 \n"; # +단항연산자로 해결
print( ($value1 + $value2), " is the sum of $value1 and $value2 \n"); # 명시적으로 괄호를 묶어 해결(권고사항)
print ( ($value1 + $value2), " is the sum of $value1 and $value2 \n"); # 권하지 않는 형태
0 TrackBacks
Listed below are links to blogs that reference this entry: Perl의 특수한 + unary operator(단항연산자).
TrackBack URL for this entry: http://aero.sarang.net/cgi-bin/mt/mt-tb.cgi/52
잘 읽었습니다 ^^ 저거 볼 때마다 헷갈리는 문제이긴 하더군요.