2022년 3월 14일 월요일

[Perl programming] 배열(array)과 목록(list)은 다르다!

Perl에서 배열(array)과 목록(list)은 종종 같은 것으로 취급된다.  그러나 아주 엄밀하게 말하자면 두 가지는 다른다. Perl에서 배열은 데이터 구조의 일종이다. 즉 스케일러(스칼라? scalar), 배열(array), 그리고 해시(hash)라는 세 가지 데이터 구조 중 하나를 의미한다.

목록은 말 그대로 목록이지 데이터 구조가 아니다. 이는 단순히 스케일러들의 '나열'된 형태를 의미한다. 따라서 전체 목록에 대하여 어떤 변수를 할당한 뒤 인덱스나 키 값에 의하여 그중의 일부를 접근하거나 조작할 수는 없다. 즉 $var = (10, 20, 30);과 같이 쓸 수는 없다.

[GeeksforGeeks] Perl - Arrays vs Lists 

리스트에 변수를 할당할 수는 없지만, 그 자체로서 인덱스/루프/레인지 관련 작업은 가능하다. 얼핏 보기에 기괴하지 않은가? 변수로 할당되지 않은 상태에서 이런 일을 할 수 있다는 것은... 위에서 소개한 GeeksforGeeks에 실린 코드를 살펴보자. 어디에도 변수명 같은 것은 없지만, 이 코드는 잘 돌아간다.

#!/usr/bin/perl

print("Accessing element at index 2: ");
print((10, 20, 30, 40, 50)[2]);
print("\n\n");

print("Range function on list\n");
print join(' ', 1..6);
print("\n\n");

Perl 프로그램에서 괄호와 관련한 다른 궁금증을 해결해 보기로 하였다. 바로 'my'에 관한 것이다. my는 함수인가? 'man perlfunc'(Perl builtin function에 대한 매뉴얼)를 실행하면 다음과 같이 my에 대한 설명이 나오는 것으로 보아서 함수는 맞는 것 같다.

그러나 이 문서의 앞부분('Perl Functions by Category')을 잘 살펴보면 perlfunc 매뉴얼은 Perl에서 함수 또는 '함수처럼 보이는 것'(keyword 및 named unary operator)까지 포함하여 설명함을 알 수 있다. my는 named unary operator의 하나이며(참조) 변수의 범위 설정과 관련한 keyword의 하나이기도 하다. 함수인가, 연산자인가? Perl에서는 그 경계가 모호한 것 같다. 'man perlop'를 입력하여 나오는 매뉴얼의 'Terms and List Operators (Leftward)'를 살펴보면 머릿속은 더 복잡해진다. 마치 경전을 읽듯이, 머릿속을 비우고 깨끗한 마음으로 몇 번을 읽어야 오묘한 진리를 터득하게 될 것 같다. 냉정한 0과 1의 세계를 다루는 프로그래밍 언어에서 이런 모호함이라니? 그래서 Perl이 점점 설 자리를 잃는지도 모르겠으나 - 이는 Perl의 철학인 'there's more than one way to do it'과 일맥상통하는 면이 있음 - 그래서 더 재미가 있는 것 아니겠는가?

다음의 두 웹문서를 읽어보기를 권한다.

그렇게 쉽게 읽히지는 않는, 좀 난해한 내용을 담고 있다. 차라리 StackOverflow 웹사이트에 실렸던 질문과 답을 살펴보면 Perl 프로그래머가 현실적으로 직면하는 궁금증이 무엇인지 더 쉽게 파악할 수 있다. 


질문자의 궁금증은 이러하다. my ($var) =  blah...라는 코드를 종종 보게 되는데, 왜 하나의 변수를 괄호로 둘러싸는지 이해하기 어렵다는 것이다. my ($var1, $var2, $var3) = blah...가 올바른 표현이 아닌지를 묻는 것이다. 둘 다 문법적으로 잘못된 것이 아니다. 다만 문맥에 따라서 해석이 달라지는 것에 유의해야 한다. 프로그램 작성자의 의도를 제대로 반영하도록 코드를 짜는 것이 중요하다. 가장 간단한 사례, 즉 my 뒤에 하나의 변수가 오는 경우만 알아보자.
  • '= 배열;' my $variable이라 적으면 $variable 변수는 배열의 크기를 갖게 된다. my ($variable)로 적으면  배열의 첫 번째 원소를 갖는다.
  • '= 목록;' my $variable이라 적으면 목록의 마지막 원소를, my ($variable)로 적으면 목록의 첫 번째 원소를 갖는다.
와, 이거 도무지 헷갈려서 외우기 참 어렵다. 어떤 경우이든 my 뒤에 오는 하나의 변수를 괄호로 둘러싸면 우변에 있는 자료의 첫 번째 것만을 할당한다는 것을 알았다. 아래의 코드를 마치 부적처럼 계속 바라보고 있으면 원리를 꿰뚫게 될 것이다.

@array = ('A', 'B', 'C');
my ($x) = @array;
print $x, "\n";
# A
my $y = @array;
print $y, "\n";
# 3
my ($w) = qw/ a b c d /;
print $w, "\n";
# a 
my $z = ('a', 'b', 'c', 'd');
print $z, "\n";
# d

댓글 없음: