IBM®
메인 컨텐츠로 가기
    Korea [국가변경]    이용약관
 
 
   
        제품    서비스 & 솔루션    고객지원 & 다운로드    회원 서비스    
메인 컨텐츠로 가기

한국 developerWorks  >  리눅스  >

보다 나은 프로그래밍으로 가는 길: 2장

주석달기

developerWorks
문서 옵션

JavaScript가 필요한 문서 옵션은 디스플레이되지 않습니다.


난이도 : 초급

Teodor Zlatanov, 프로그래머, Gold Software Systems

2001 년 11 월 01 일

펄 프로그래밍 발전 방안들을 제시하고 있다. 두 번째 시리즈에서는 코드의 주석을 분석한다. 프로그램 코드의 주석은 실제 코드 만큼이나 소프트웨어 팀에 있어서는 중요하다.

충분한 문서 보다 좋은 게 없다. 명확해 지려면 때로는 여러 번의 반복이 필요하다. 코드를 다른 사람들에게 주어야 한다고 생각해 보라. 이 세상에는 많은 사람들이 있다. 불필요하다고 생각한 한 개의 주석이 다른 사람을 기쁘게 할 수 있다. 새로운 기능을 추가할 때 본인에게도 기쁨이 될 수 있다.

주석의 기초

프로그램을 작성할 때 계획을 세밀히 준비하라. 미리 앞서서 세부사항을 결정할 필요는 없지만 프로그램을 컴포넌트 부분으로 나누고 그 사이를 메우기 위해 주석을 사용해야 한다.

다음은 나만의 코딩 방법이다. 여러분이 좋아하지 않을 수도 있지만 객관적인 입장에서 살펴보길 바란다. 여러분과 여러분의 팀에게 유용한 방법이 있을 수 있다.

일단 무엇보다도 주석을 참조 할 사람들을 생각하라. 제 삼자도 따라올 수 있도록 주석을 명료하게 하라. 코드가 복잡해 질수록 의도를 분명히 하기 위해서 더 많은 주석을 달아야 한다. 문제, 솔루션, 주석, 그런 다음 디버깅이다. 특히 중요한 것은 디버깅 전에 주석을 만드는 것이다. 주석은 보다 빠르고 정확하게 디버깅 할 수 있도록 도와준다.

문제에 대한 솔루션은 물론이고 문제 자체도 적어놓는 것이 유용할 때가 있다. 다음 예제를 보자:


Listing 1

# function: do_hosts
#
# purpose: to process every host in the /etc/hosts table and see if it
# resolves to a valid IP
#
# solution: read the list of hosts as keys in a hash, then go through
# the list of keys (hosts) and store the IP address for each host as
# the value for that key, or undef() if it doesn't resolve properly.
# Return a reference to the hash, or undef if the /etc/hosts file was
# not accessible.

간략한 것을 좋아하는 사람이 있을 수도 있다:


Listing 2

# function: do_hosts:  process every host in the /etc/hosts table and
 see if it
# resolves to a valid IP; return a reference to the hash (key=host,
# value=IP or undef), or undef if the /etc/hosts file was not
 accessible. 

다른 방법도 있다:


Listing 3

# do_hosts: returns a ref to hash of hosts (key=host, value=IP/undef)
# from /etc/hosts 

do_hosts()의 복잡성 정도에 따라서 위 세 개의 방법들이 사용될 수 있다. 만일 함수가 두 라인이라면 세 단락이나 되는 주석을 작성하느라 귀중한 시간을 낭비할 필요는 없다. 만일 여러 페이지라면 충분한 설명을 하는 것이 좋다.




위로


프로그램 시작에 주석 달기

프로그램은 목적을 간단하게 설명하는 것으로 시작해야 한다. 무엇을 하고 있는지 파악하기 위해 스크롤바를 굴리지 않도록 하라. CVS 같은 버전 제어 시스템을 사용하고 있다면, Id 헤더 처럼 파일의 시작부분에 적절한 헤더를 두도록 한다. 간결함을 유지하도록 하라. 프로그램을 간략히 설명하기에는 두 줄에서 네 줄 정도면 충분하다. 이름, 이메일 주소, 전화번호 등 연락처를 기재하도록 한다.


Listing 4

#!/usr/bin/perl -w
# whodunit.pl: A script to solve a murder mystery
# by joe@shmoe.com $Id: whodunit.pl,v 1.92 2000/08/08 19:08:50 joe Exp 
$ 

첫 번째 줄은 스크립트가 실행될 때 어떤 프로그램이 실행되는지를 설명하기 위한 것으로, 대부분의 유닉스 시스템에서 사용하는 표준 방식이다. ('!' 다음에 나오는 모든 것들은 인터프리터 이름이다). -w 플래그는 경고를 발효한다는 표시이다. 권장할 만한 방식이다.

두 번째 줄은 프로그램과 목적을 간단하게 설명한 것이다. 세 번째 줄은 작성자의 이름과 파일의 배포일과 버전을 구분하는 Id 헤더이다. RCS와 CVS는 Id 헤더를 사용한다. RCS와 CVS에 대해서는 참고자료 에 자세하게 설명되어있다.




위로


초기화 섹션에 주석달기

추가적인 주석이나 파일의 시작에 존재하는 점에서 볼 때, 초기화 섹션(initialization section)은 논리적으로나 물리적으로나 프로그램의 시작과는 분리되어야 한다. 초기화 섹션은 프로그램이 시작될 때 실행되는 실제 코드를 포함하고 있다. 펄에서 초기화 섹션은 다음과 같은 것으로 이루어져 있다:

  • 모듈과 프로그램
  • 상수(Constants)
  • BEGIN/END/INIT/CHECK 서브루틴
  • 초기화 코드

모듈과 프로그램

펄의 use 키워드는 인터프리터에게 모듈을 로딩하거나 프라그마를 작동시키도록 명령한다. 프라그마가 오른쪽 방향에서 인터프리터를 한 칸 내린다. 예를 들어 use utf8 는 인터프리터에게 UTF-8 인코딩 데이터 파일과 스트림을 준비하도록 명령한다.

각 모듈에 맞춰 수평으로 주석을 정렬하는 것이 좋다. 모듈 또는 프라그마 당 한 개의 주석을 달도록 한다:


Listing 5

use Data::Dumper;               # for debugging printouts
use strict;                     # be strict - pragma for the 
interpreter
use POSIX;                      # use the POSIX functions

그런다음, 모듈과 프라그마를 새로운 프로그램에서 시작하기 위해 복사 및 붙이기를 하면 된다. "strict" pragma를 권고한다. 변수를 선언하는 것에 있어서 정직해야 한다.

perldoc 명령어를 이용하여 모든 모듈과 프라그마 문서를 참조한다. 예를 들어, perldoc strict 는 strict pragma의 모든 것, 즉 어떤 일을 수행하는지 어떻게 사용하는가를 설명한다.

몇몇의 에디터는 특정 위치에 주석을 위치시키는 기능이 있다. 에디터 명령어를 완벽히 숙지하도록 한다.

상수(constants)

상수를 그저 또 다른 펄 프라그마로 생각하겠지만 고유의 섹션이라고 할 만 하다. 그것들에 주석을 다는 것은 모듈과 프라그마에 주석을 다는 것과 같다. 화살표가 다음과 같이 정렬되어도 보기가 좋다:


Listing 6

use constant ALPHA    => 1; # alpha code
use constant BETA     => 2; # beta code
use constant GAMMA    => 3; # gamma code
use constant USER     => 4; # user ID offset
use constant GROUP    => 5; # group ID offset
use constant DEPT     => 6; # dept. ID offset

BEGIN/END/INIT/CHECK 서브루틴

BEGIN/END/INIT/CHECK 서브루틴에 주석을 달아보자. (perldoc perlmod 참조). 파일의 어느곳에나 만들 수 있다. 여러번 정의할 수도 있다. 파일의 시작부분 이나 끝 부분에 위치시키도록 한다. 찾기 쉽도록 하기 위해서이다. 한 줄의 BEGIN 함수는 확장 주석이 필요하지 않다는 것에 주목하라.


Listing 7

# BEGIN: executed at startup, assigns 'root' to the USER environment 
variable
BEGIN 
{
  $ENV{USER} = 'root';
}

초기화 코드

초기화 섹션의 마지막은 실제 코드가 된다. 가능하다면 개별 블록에서 주석을 정렬한다.


Listing 8

$| = 1;  
                               # auto-flush the output
$Data::Dumper::Terse = 1;               # produce human-readable 
Data::Dumper output
# define the configuration variables
my $config = AppConfig->new();
$config->define(
                # list of undo commands
                'UNDO'            => { ARGCOUNT => ARGCOUNT_LIST },
                # file to log data
                'LOG_FILE'        => { ARGCOUNT => ARGCOUNT_ONE  }, 
                );
$config->file(whodunit.conf');          # load the whodunit 
configuration file

이 초기화 코드는 auto-flushing을 실행시킨다. 그런 다음 Data::Dumper 모듈에게 읽을 수 있는 아웃풋을 만들도록 명령하고 AppConfig 설정을 만든다.




위로


코드에 주석달기

코드에 주석 달기는 매우 쉽다. 가능하다면 주석을 간결하게 정렬하고, 명확하지 않을 때에는 과감하고 심도깊게 설명하도록 한다.


Listing 9

print Dumper \%ENV;                     # print the full ENV hash

# get the environment variable names that begin with USER
@user_vars = grep(/^USER/, keys %ENV); 

# print the values in all the variables that begin with USER, using a
# hash slice
print Dumper @ENV{@user_vars};          

print "Done\n";                         # print "done" message

# TODO: find better method of sorting variables
# TODO: use Data::Dumper with variable names

주석은 column 0 또는 column 40 에서 시작한다. 일관성은 주석을 더욱 읽기 쉽도록 만든다. 필요할 경우 여러 줄의 주석도 무방하다. 함수 유실, 버그, 미완성 등이 어디에서 발생했는지를 명시하기 위해 주석을 사용할 수도 있다. "TODO" 라는 단어는 모든 코드를 검사하거나 어떤 것이 미완인지를 검토 할 경우 유용하다. 빠른 grep 명령어는 TODO 목록를 프린팅 할 것이다.

코드 한줄 한줄 마다 주석을 달 필요는 없다. 하지만 주석들은 프로그램을 디버깅 하거나 확장할 때 최상의 자원이 된다.




위로


루프와 조건문에 주석달기

루프와 조건문도 보통 코드의 함수들 처럼 주석을 달도록 한다. 나중에 구별하기 쉽도록 루프에 번호를 매기는 것은 다소 극단적이다. 좀 더 나은 접근방식은 "editor-folding"을 사용하는 것이다. 이것은 루프를 폴딩할 때 한 라인으로 전체 루프를 볼 수 있도록 한다. (folding 표시 사이의 라인들은 숨어있는 것이지 없어진 것이 아니다). XML/HTML과 같은 folding 마크는 태그를 시작하거나 끝낸다. 중첩시키는 것도 가능하다. 어떤 에디터는 folding을 지원하는 경우도 있다. (X)Emacs는 Outline또는 folding.el modes를 사용하여 이를 수행한다.


Listing 10

# go through all the numbers between 2 and 200, and print a message
# for each one
foreach my $counter (2 .. 200) 
{
  print "Whoa, the counter is $counter!\n";
}

루프의 목적과 한계를 항상 기록하라. 논리적 조건들이 한계에 영향을 미친다면 그것 역시 기록하라.




위로


프로그램의 마지막 단계에 주석달기

프로그램의 마지막은 가장 지루하기 마련이다. 작업은 완성되었고 데이터 구조는 잠들었다. (펄에서는 걱정할 만한 메모리 "deallocation"이 없다). 그리고 약간의 라인만 남아있다. 이러한 것들이 여러분을 바보로 만들지 않도록 하라; 프로그램의 마지막 라인은 위험성이 농후 할 수 있다. 디버깅 프로그래머가 수행하는 첫 번째 일은 프로그램의 종료 작동을 보는 것이기 때문에 가장 사소한 라인이라도 주석처리를 하라.


Listing 11

# delete old files, warn if they can't be removed
foreach (@myfiles)
{
 unlink $_ or warn "Couldn't remove $_: $!";
}
print "whodunit.pl is done!\n";         # tell the user we're done
exit;                                   # exit peacefully




위로


POD 문서와 프로그램 도움말(help) 만들기

POD (Plain old documentation)는 스크립트 내에서 펄 스크립트를 문서화하는 방법이다. perldoc perlpod 명령어로 POD 문서와 신택스에 대한 좀 더 자세히 알 수 있다. 훌륭한 POD 문서는 사용자들이 여러분의 프로그램 도움말에 빠르고 효율적으로 액세스 할 수 있다는 것을 의미한다. POD 신택스를 배우기 위해서는 시간이 필요하다; 매뉴얼을 작성하는 것은 훨씬 쉽다. 게다가, POD는 다양한 매뉴얼 포매터와 호환되기 때문에 일반 텍스트 파일, 유닉스 스타일의 man page, LaTeX 파일을 같은 문서에서 만들수 있다. POD는 매우 제한된 포맷이지만 문서의 필요를 채우기에는 충분하다.

일반적으로 다음의 섹션들이 POD 문서에 포함되어야 한다: NAME, SYNOPSIS, DESCRIPTION, OPTIONS, RETURN VALUE, ERRORS, DIAGNOSTICS, EXAMPLES, ENVIRONMENT, FILES, CAVEATS/WARNINGS, BUGS, RESTRICTIONS, NOTES, SEE ALSO, AUTHORS, HISTORY.

어떤 프로그래머들은 그들의 프로그램에 -h switch를 만들어서 프로그램상의 perldoc을 호출하여 POD 문서가, 사용자가 perldoc whodunit.pl.을 타이핑했던 것처럼 프린트 되도록 한다. 여기에서 문제점은 사용자는 -h switch를 사용하여 그렇게 많은 가외 정보를 원하지 않는다는 점이다. 단지 시놉시스와 옵션 리스트만을 원할 수도 있다. 그럴 때에는 -h switch를 사용할 때 생기는 개별 help 핸들러를 작성하는 것이 더 낫다:


Listing 12

# print_help: help handler, prints out help for whodunit.pl and exits
sub print_help
{
 # print the help itself
 print << EOHIPPUS;
 This is help for the whodunit.pl program.

You can pass options to whodunit.pl as command-line arguments.  For
example:

..../whodunit.pl -h
..../whodunit.pl -show suspects

List of options:

-h     : print this help

-show  : show the suspects, victims, or detectives (all of them if no
         second argument is specified)

-quiet : print no information other than the killer's name

EOHIPPUS
 exit;                                  # do nothing else, just exit quietly
}

print_help 문서를 작성하라. POD 문서와 다른 온라인 help의 보여지는 모습도 중요하다. 사용자가 가는 첫 번째 장소는 매뉴얼이 아니다. -h flag를 사용하거나 POD documentation를 보는 것이 훨씬 더 편리하다. 콜론, 라인사이의 스페이스를 정리하여 전체적으로 깔끔한 인상을 주는 것이 좋다. 겉으로 보여지는 것이 때로는 프로그램의 내용보다 더 중요하게 여겨질 때가 있다. 잘 작성된 프로그램은 좋은 문서가 우선이 되어야 한다.

어떤 프로그래머는 기본적인 주석 대신 그들의 프로그램에 POD 문서를 포함하는 것을 더욱 선호한다. POD 주석들은 =pod 로 시작하고 =cut 로 끝난다. The =pod 라인은 펄 컴파일러에 명령하여 =cut 까지 모든 것을 인터프리팅 하는 것을 멈추도록 한다. 사용자들 또한 프로그래머라면 더 없이 좋겠지만 스크립트용 문서를 보고 싶어하는 일반 사용자들이라면 헷갈릴 수 있다. 제한적으로 사용하기 바란다.




위로


참고자료




위로


필자소개

Teodor Zlatanov는 1999년에 보스턴 대학에서 컴퓨터 공학을 전공했다. 졸업 후 Perl, Java, C, C++를 사용하여 프로그램을 개발하였다.





위로


기사에 대한 평가

매우 불만족 (1)
불만족 (2)
보통 (3)
만족 (4)
매우 만족 (5)




위로



    IBM 소개개인정보 보호정책문의