Wednesday, September 30, 2009

정보공유 : 리눅스 터미널 로그인시 1-2분 걸리는 현상

[정보공유]
리눅스 터미널 로그인시 1-2분 걸리는 현상이 발생하고 있다면?
이전에도 몇 번 경험한 내용이었는데 해결방법을 몰랐다가 이번에 알게 되었음.

sshd에서 정방/역방 IP조회를 하고 있기 때문에 DNS 타임아웃이 발생하는 시간까지 걸리는 것일 듯.
DNS에 정방/역방 등록을 하지 않고서 해결하는 방법으로는.

(A) 우선 sshd설정(/etc/ssh/sshd_config)에서 useDNS를 no로 하는 방법과.
(B) 접속하는 곳이 고정이라면 서버측 /etc/hosts에 이름을 등록하는 방법.

이상 정보공유.

Friday, September 25, 2009

rxvt on windows

윈도우즈의 cmd로는 뭔가 부족하게 느껴집니다.

1) 프로세스를 백그라운드로 실행시키기 라던가,
2) (default로) ansi가 적용되지 않기 때문에, groovysh할 때 컬러를 쓸 수 없는 것도 그렇고. (음? 이건 장점?),
3) parameter로 묶을 때, single quotation은 사용할 수 없고, double quotation ""만 사용할 수 있는 것
4) cmd에서는 터미널타입이 적당한 것이 없어서 perl로 ssh를 자동화하기도 곤란.

이러한 이유로 rxvt + bash를 사용해 보고 있습니다.

rxvt는 vt102터미널 에뮬레이터입니다. 이번에 GNUstep인스톨할 때 같이 설치된 rxvt를 사용해 보고 있습니다.(이럴 바에는 cygwin을 쓸까 하는 생각도 해보았습니다만, 아직까지는 일반 cmd상에서도 유닉스 커맨드를 사용할 수 있는 linux command for win32 처럼 cygwin의 커맨드를 cmd에서 사용가능한 지, 확인하지 못했습니다.)

유니코드용으로 컴파일된 urxvt와 탭형식으로 된 mrxvt도 있다고 합니다만, 모두 X-windows용으로, 아직 win32용으로 컴파일된 것은 못구했습니다. (시간이 없다는 이유로 아직 직접 컴파일 해보고 있지 않습니다. m(__)m )



그런대로 사용하기는 괜찮을 듯 합니다.
소프트링크도 제대로 사용할 수 있기 때문에, 필요한 경우
/c 이하의 디렉토리를 shell root안으로 가져온다던지 하는 것도 가능했고.

괜찮은 느낌입니다.

좀 더 사용해 보겠습니다.

Thursday, September 24, 2009

Record : 'use constant' on perl

perl의 constant는 반드시 먼저 선언해 주어야 하는 듯.
BEGIN으로 컴파일타임시에 정의되도록 해봤지만 잘 되지 않았습니다.
'use constant'는 컴파일타임 이전의 preprocessor가 처리하는 듯?(짐작) 합니다.

evalperl
use constant CONST_SERVICEID_IPADDR => 101;
eeprint(CONST_SERVICEID_IPADDR);

101
-----------------------------

evalperl
eeprint(CONST_SERVICEID_IPADDR);
use constant CONST_SERVICEID_IPADDR => 101;

CONST_SERVICEID_IPADDR
-----------------------------

evalperl
eeprint(CONST_SERVICEID_IPADDR);
BEGIN { use constant CONST_SERVICEID_IPADDR => 101; }

CONST_SERVICEID_IPADDR <- 101 이 아님. orz
-----------------------------

evalperl
eeprint($CONST_SERVICEID_IPADDR);
BEGIN { our $CONST_SERVICEID_IPADDR = 101; }

101 <- 이건 101. orz

어디선가 본 글처럼, perl이나 jscript같은 interpretor에서는, 그냥 constant를 사용하기 보다는 변수로 사용하는 것이 performance면에서도, 정신적인 건강면에서도 좋지 않은가 싶습니다.

# 생각해보면, python에서도 constant가 없긴합니다.


사진은 파키스탄의 10세(2008년기준) 최연소 MCP 인증받은 소녀 프로그래머.
http://www.pakassociationdubai.com/business_details.php?id=55

.

Wednesday, September 23, 2009

programming way of system engineer

이번 기술부 지원 프로젝트에서 경험했던, 'SE의 프로그래밍을 서포트한 2009년 여름 프로젝트'는 굉장히 색다른 느낌이었습니다. 이 이야기를 적어볼까 합니다.

서포트를 나가게 된 배경은 다음과 같습니다.
2008년 리만브러더스 파산과 더불어 시작된 불경기, 그리고 사내 파견사원의 감축과 정사원위주만으로의 운영, 신규프로젝트 발생과 기술부 리소스부족(perl과 python코딩에 대한), 개발부에 지원요청과 해당 경험이 있고 덜 중요한(?!) 리소스(바로 접니다)의 지원제공.

1. 굉장히 간결한 방식을 선호(shell script를 확장한 것과 같은 느낌의 프로그래밍.)

'심플한 것이 아름답다'라는 프로그래밍에서의 정석이 있습니다만, 정말 그것을 실천하려고 애를 씁니다. 특히, 한 줄 코드로 가능할 수 있다면, 그렇게 하려고 애를 씁니다. 여기서 몇가지 지금까지와는 다른 상식으로 진행되었는데, 예를 들면,

1) 가능하면 클래스는 사용하거나 작성하지 않습니다.
어차피 pointer를 tie하는 것에 지나지 않는 클래스를 생성하려고, new하는 한 줄의 코드를 작성하는 것은, 불필요한 리소스 낭비로 여기어 지는 것 같았습니다.

2) parameter는 주로 array of hash reference
hash reference인 것은 이해가 가지만, 그것의 array였다는 것은 좀 색달랐습니다.

3) 리턴값, int형 보다는 (rc, rm)의 배열.

rc는 return code, rm은 return message입니다.(간혹 엔지니어에 따라 rv 즉 return value로 사용하는 경우도 있었습니다.)
리턴이 perl의 subroutine이든, python의 method이든, 실패했을 경우 그 이유를 알기 위한 메시지를 함께 전달합니다. 실패라면 exception을 함께 전달하는 느낌입니다.
문제없이 진행되어 rc가 성공이라면, rm은 해당 리턴값을 가지게 하는 설계가 많았습니다.

4) 리턴값, 0 = 성공, 1 = 실패
이는 시스템 커맨드의 리턴(batch라면 errorlevel)이 대게 에러번호를 리턴하는데 기인합니다.
개발자로서의 인식으로는 non-zero = true, 0 = false 이기 때문에 checkData와 같은 함수의 리턴이 1(true)라면, OK라는 인식이지만, SE에게는 NG라는 인식입니다.
이는 정의하고 진행하면 되는 것이기 때문에 특별히 문제는 없었습니다만, "음? 성공하면 0입니까? (성공하면 false입니까?)"하고 물었을 때, '음? 당연한 것을 왜묻지?'하는 느낌의 반응은 약간의 이질감을 느끼게 되더군요.


2. 놀라운 시스템 관련 지식.

이것은 말할 것도 없습니다. (모든 SE가 다 그렇지는 아니겠지만) 굉장히 정확한 지식을 가지고 있었습니다.
이런 예가 있었습니다. 한번은 '어떤 명령어 | sed xxxxx'와 같은 외부 프로세스를 실행한 결과를 치환해 값을 받도록 실행하는 코드를 작성한 적이 있었습니다. 이때 다른 명령어는 모두 문제가 없었는데 어느 특정 한 명령어는 프로세스가 종료하지 않고 메모리에 남아 있게 되는 일이 있었습니다.
이를 SE에게 문의했는데, 추적하는 것을 보여주더군요. 값진 경험이었습니다.

우선, ps상 이 프로세스가 defunc가 아니었기 때문에(좀비가 아니었기 때문에) 폭주인지, 아니면 무엇을 하고 있는지 strace를 통해 pid에 걸어서 무엇을 하고 있는지 알아보더군요. 지금까지 나 이외에 strace를 사용하는 것을 '직접' 본 두번째 경험이었습니다.)

우선은 표준입력을 기다리고 있는 것을 알아내어 폭주는 아닌 것을 확인했습니다. 그다음 왜 표준입력을 기다리고 있는지 알아보았는데, 그 '특정 명렁어'가 표준 출력으로 출력하는 것을 모두 /dev/null로 돌려놓고 있었더군요. 결국 sed는 뭔가 파이프로 전해져 오는 것이 없었기 때문에 sed가 입력을 기다리고 있었고, child의 pid를 수확하지 못하고 있기 때문에 parent의 '특정 명령어' 및 shell이 살아남아 있는 것이었습니다.

이때 잠깐 질문을 제가 했는데, sed를 echo로 바꾸면 정상종료하는데, 그 차이를 잘 이해하지 못하다라고 얘기했을 때, 설명을 받았습니다.
이때 그는 파이프 처리에 관련된 설명을 하면서 File Descriptor라는 용어를 사용해 설명하였는데, 나는 시스템 프로그래밍 기사나 책을 읽으면서 몇번 본 적은 있지만, file descriptor라는 단어를 내 입으로 조차 발음해 그 소리를 내 귀로 들은 적이 한 번도 없었는데, 이때 설명받으면서 들은 것이 난생 처음이었습니다.(그만큼 그 개념을 직접 말해 설명하는 것을 듣는 것이 굉장히 드믄 일입니다.)

3. 기타

<작성중>

1) 자기가 작성한 코드는 장해 발생때 대응하는 사람이 살펴보고 긴급히 수정해 대응할 수 있어야 하는 코드

2) '로직을 아직 다 못썼습니다.'

3) '단순한 버그이기 때문에 위치를 알면 곧 수정해 대응이 가능합니다.'
대신 환경(장비상의, 또는 시스템상의) 이나 데이타의 대응이 훨씬 더 큰 일.

Thursday, September 17, 2009

which script language shall I choose?

어떤 언어를 주된 무기로 사용할까?

제가 생각하는 프로그래밍이란, 로직을 만드는 것(또는 일)이고,
프로그래밍 언어는 그 로직을 기록하는 Tool입니다.
이 정의만으로, 프로그래밍은 프로그래밍 언어 없이도(psudo code로) 할 수 있습니다.
그리고 정말 그렇다고 생각합니다.

프로그래밍 언어의 문법은 컴파일러가 사용하는 Parser의 Rule이고,
필요하다면 preprocessor를 만들어 더 간결하게 하는 것도 가능합니다.
즉 여기까지는, '문법만으로 프로그래밍언어를 선택하는 것'은 의미가 크지 않다고 생각합니다.

내장함수와 기초 클래스 라이브러리.
여기서부터는 꽤 중요해집니다.

우선 객체지향이 아닌 순차적프로그램에서 지원되는 내장함수는, 호환성때문에 업데이트가 자주 되지 않는다는 특징을 가지고 있습니다.(예를 들면, 그 유명한, javascript의 array의 length property, hash형식으로 사용할 때 엉뚱한 값을 리턴하더라도 유지되는.)
bash나 batch같은 shell script, perl, jscript, vbscript는 내장함수가 나타난 버전 이후로는 처음에 정의된 내용 그대로 거의 변화없이 사용되고 있습니다. (이는 어쩌면 장점일 수 있습니다.)

객체지향의 언어의 경우는, 기초 문법은 거의 그대로 유지하면서, 기초 클래스를 확장하거나 method를 override할 수도 있어, 순차적 프로그래밍 언어보다 비교적 더 잦은 업데이트(문법보다는 클래스쪽의)가 일어나는 특징이 있으며(역시 이는 단점일 수 있습니다.), 기초 클래스 라이브러리가 아니더라도 사용자가 만들어 배포하는 클래스는, 순차적 프로그래밍 언어의 라이브러리보다 더 응용해 접근하기 쉬운느낌입니다.(이것도 역시 단점일 수 있습니다. 프레임웍 수준의 사용자 정의 클래스 라이브러리의 등장, 그리고 난립은 축복이면서 동시에 재앙-가족과 사회에서 멀어지게 하는-입니다.)

또 순차지향적 프로그래밍 언어는, 작성하면서 곧 실행해 볼 수 있는 코드를 작성하는 경우기 많은 반면, 객체지향 언어는 바로 곧 실행해 볼 수 있는 코드를 작성한다라기 보다는, 라이브러리를 작성한다라는 느낌입니다.

----

어떤 개발언어의 레벨을 올려둘까 하고 고민했습니다.
이러한 고민을 한 계기로는 jscript로 작성한 개인의 Outlook관련 스크립트가 있는데, OutLook을 control하자니, COM을 다룰 수 있는 언어를 해야했고, JScript는 그다지 나쁘지 않은 선택이었습니다만,
Loop를 stop, start를 걸 수 있도록 하자니 여의치가 않더군요. VBS와 JScript에서는 Thread를 생성할 수가 없었습니다. OTL
지금까지 작성해 둔 것은 어쩔 수 없고, 다음에는 이런 작업으로 적절한 언어로 작업해야겠다하는 생각이 들어 어떤 것으로 할까 생각을 해보았습니다.

jscript, vbs는 앞으로도 많이 사용하겠지만, 윈도우즈환경에서만 돌아가므로 Pending
php만으로는 할 수 있는 것이 제한되어 php는 탈락
C, C++, MFC로는 스크립팅언어보다 손이 조금 더가므로 탈락
java자체로는 COM에 Access하도록 하자니 번거로운게 많아서 탈락.

유력한 후보는
perl, python, groovy(groovy는 Loop나 Daemon 형식으로 돌린다고 가정했을 때), ruby

결론
그중에 perl이 제일 유력했지만,
결론으로는 (나에게는) python.

왜냐하면

저는 일본OS를 사용합니다. 일본회사이고 회사에서 제공한 컴퓨터입니다.
일본OS에서 일본어를 사용하여 스크립트를 작성하는 경우는 거의 문제가 없지만,
한글을 사용하여 스크립트를 작성하는 경우, 문제가 발생하는 경우가 종종 있습니다.
또 저는 emmeditor의 매크로로 실행하게 하는 스크립트도 굉장히 많이 작성하는 편인데,
다른 언어로는 유니코드가 emeditor에서 지원되지 않는 한편(vbs와 jscript는 물론 지원합니다.), python은 유니코드를 emeditor에서 사용할 수 있었습니다.


evalpy
#!/usr/bin/python
a = [ "AAA", "BBB", "CCC", "똠방각하", u"똠방각하", "表示する", u"表示する"]
for i in a:
window.document.writeln( i )

AAA
BBB
CCC
・・ゥ・・葺
똠방각하
陦ィ遉コ縺吶k
表示する

그렇게 나쁜 선택은 아닌 것 같습니다만, 분명히 다른 언어로 작업하는 경우도 많을 것입니다.

Wednesday, September 16, 2009

release, release, after release,



(Dev) Kim tonghyun says:
헉 못보던 책이네
nowhere527 says:
오늘 갔다와서 받은 거야 .. 자기는 점심 먹고??.
nowhere527 says:
괜챦아??.
(Dev) Kim tonghyun says:
응 다이죠부. 오늘 부터 정상퇴근.
(Dev) Kim tonghyun says:
어디 갔다온건데??
(Dev) Kim tonghyun says:
책 받고 너무 좋아하네
nowhere527 says:
애기 셋 있는 집 .. 승환이 신났음..
nowhere527 says:
하영이랑도 놀고 .. 좋았지 ..
nowhere527 says:
오는 내내 재잘재잘 ..
(Dev) Kim tonghyun says:
나루호도 나루호도
nowhere527 says:
간식도 마다하고 책 하고 있음..
nowhere527 says:
소세지는 내팽개침 ..
(Dev) Kim tonghyun says:
ㅋㅋㅋㅋㅋㅋㅋㅋ

Tuesday, September 15, 2009

Redmine - Issue grapgh

약 오픈 1개월 전부터 테스트팀을 조직해 진행한 결과입니다. 그 전까지는 개발부, 기술부, 자체 테스트였습니다. (이정도는 올려도 괜찮겠지....)

Sunday, September 13, 2009

개발프로젝트의 경험공유 : TestCase의 문제와 TestCase만으로 해결 할 수 없는 문제에 대한 풀이의 고안.

개발프로젝트의 경험공유
TestCase의 문제와 TestCase만으로 해결 할 수 없는 문제에 대한 풀이의 고안.

이번 프로젝트로 테스트팀이 개발팀 외부에 있을 경우에 품질에 대한 확신이 높아지는 것을 확인했습니다.
전체적인 진행에 대해서는 따로 포스트 하려고 합니다만, 여기서는 우선, 개인적으로 이번 프로젝트에서 얻은 성과를 공유하고자 합니다.

개인적으로는 이번 프로젝트에서 느낀 것은,
1) perl의 경우, 프로그램을 종료하지 않는, 대화식의 interactive한 테스트용 프로그램을 만들기가 훨씬 더 쉬웠으며
2) eval이 지원된다면 모듈을 hot deploy도 할 수 있고, 직접적인 함수의 사용 결과를 눈으로 볼 수도 있어 유연한 테스트를 할 수 있었습니다.

우선은 TestCase를 사용했습니다.

처음에는 제가 작성하는 Module의 함수의 테스트를, Perl에서의 Test Framework이라고 말 할 수 있는 Test::More를 통해서 했습니다.
이 테스트를 통과하면 업로드 했습니다. 처음에는 괜찮았는데, 나중에 가니 테스트프로그램의 훨씬 더 커졌버리더군요.

하나의 함수를 사용할 수 있는 경우가 여럿인 경우, 모두 통과하게 해야 했으니까요.
예를 들면, select, insert, update, delete하는 DAO형식의 함수 4개를 만들었다고 할 때,
테스트 해야하는 항목으로는, 각 DAO의 함수에 대해 Parameter가 null일때, Parameter의 type이 잘 못되었을 때, Parameter의 조건이 안맞을 때
또, Data가 이미 있는데 insert하려 할 때, 없는데 update하려 할 때, 등등으로 4개함수당 테스트 해야할 케이스가 평균 50여개 정도가 나왔습니다.

이번 프로젝트에서는 외부로 공개해야하는 함수(perl에서는 subroutine)은 182개, 내부적으로 사용하는 것까지 합하면 작성한 함수는 약 220여개 정도가 되었습니다.
물론 만들어 놓고 보니, 납품하는 입장에서도 안심은 되더군요. 그러나 매우 노가다성 작업이라는 것을 알았습니다.
작성이 완료되었는데, 인터페이스상, Parameter가 하나 늘거나 또는 줄거나 하면(물론 parameter의 hash값의 key/value가 늘거나 줄거나 하는 것입니다.),
모듈만 수정하는 것보다, 테스트를 수정하는 것이 큰 일이었습니다.

TestCase만으로는 해결할 수 없는 문제.

문제는 또 있었습니다.
함수의 동작에는 문제가 없는데, 이를 사용해 조합하는 부분에서 잘 못 사용해서, 로그에는 제가 작성한 함수의 부분에서 출력하는 문자열이 남아서, 저에게 Bug Assign되는 것이었습니다.
조합하는 부분의 담당 개발자에게 api 인터페이스 문서를 보고 고치라고 강요할 수도 있지만,
결국은, 조합하는 부분의 코드를 어떻게 작성했는 지, 직접 열어보고야 말았습니다. (여기서 기가막혔습니다. perl 1만줄!)

이때는 실전에서 전달되는 값에 대한 테스트는 Test case로는 할 수 없습니다.
보통 이때의 디버깅 방법은
(1)console이나 파일로 값을 출력하게 하는 부분을 넣고, 다시 돌려보는 것이 일반적입니다.
(2)좀 더 똑똑하게 로그 파일로 출력하게 하는 경우도 있습니다. (그러나 웹과 같이 그 뒤에 요청되는 다른 request를 처리하는 로그가 계속 쌓이면 찾아보기 어렵습니다.)
(3)그보다 좀 더 수준높게 Debugger를 돌려 Trace하는 방법이 있습니다. 어쩌면 Perl에서 사용하기 쉬운 Debugger가 있었다면 이를 사용했을 지도 모릅니다.

우선, 조합하는 부분의 소스는 제가 직접 손 대는 것이 적합하지 않았습니다. 왜냐하면 계속 작업중이었기 때문이죠.
복사해서 로컬에서 수정해 볼 수는 있지만, 실전 DB의 값을 사용해 돌리게 하면, 시스템이 이상해 질 수도 있는 문제였습니다.
그렇다고 테스트 DB만 있으면 해결 할 수 있는 것도 아니었습니다. 가상머신을 생성하는 등, system call하는 부분이 많기 때문에, 적합한 환경이 제공되지 않으면, 기동하는 것도 불가능했습니다.

그래서 저는 이번에는 조그만 interactive한 프로그램(while(true)문으로 입력을 기다리고, 받아서 처리하고 다시 입력을 기다리고.. 하는 프로그램입니다.)을 만들어서, 현재의 실전 환경에서 이러한 값을 넣었을 경우, 함수가 어떻게 동작하는지 알아보는 방법을 취했습니다.
그리고 실전환경과 같은 함수에 데이타를 넣어보기 위해, 실행할 문장을 입력받아 실행하도록 eval을 사용했습니다.
이 방법은 매우 유연한 입력을 받을 수 있어서 테스트 하기에 아주 적합하다는 것을 알았습니다.

이번 경험의 확장

interactive한 프로그램은 perl로만 가능한 것이 아니라 어떤 언어든 가능합니다만,
eval은 그렇지 않습니다. eval은 주로 scripting언어에만 존재합니다.
compile언어에서는 실시간으로 해석하지 않고 컴파일된 코드를 수행하는 것이기 때문에 scripting언어보다 더 나은 퍼포먼스를 보이는 것이니까요.
그런데, java에서는 eval은 없지만, groovy에서 Eval 클래스가 있는 것을 알았습니다.
또 class의 핫디플로이라면 classloader의 loadClassData()를 직접 호출해서 hot deploy를 구현하면 될 것 같습니다.

그리고 닷넷 4.0에서는 Scripting을 지원한다고 하는데 어떻게 지원되는 지 아직 살펴보고 있지 않습니다.
c/c++에서는 아무래도 어렵지 않을까 싶습니다. (perl에서 inline c를 사용하는 방법으로 응용할 수 있을지. 어떨까 싶습니다.)


이러한 경험이, 다른 개발을 담당하시는 분들께 도움이 되었으면 하고, 정보공유합니다.

아직 개발이 완료된 것은 아닙니다. 좀 작업은 남아 있습니다.
좀 더 다른 느낀 점이 있다면 공유하겠습니다.

그리고...

저는, 개발경험 이외의 것이 더 큰 수확입니다. (다음번 포스트에서 적어볼가 합니다.)
개발경험도 개발경험이지만, 개발은 다른 사람에게 맡기고,
전체적으로 프로젝트를 지휘하는 것이 훨씬 재미있겠다라는 생각이 들었습니다.

이상.
정보공유 끝.

Wednesday, September 9, 2009

ssh for win32 cmd console

여러 전문 ssh용 프로그램이 있습니다만, 특별히 애용하거나, 싫어하거나 하는 것은 없습니다만, 주로 사용하는 것은 poderosa와 콘솔용 ssh입니다.


콘솔용 ssh는 rsync의 win32버전인 cwRsync에 딸려오는 ssh를 사용하고 있습니다. 아마도 cygwin을 설치했다면 같은 것이기 때문에 아무거나 상관없을 것입니다.

poderosa는 닷넷언어로 매크로가 가능하기 때문이고,

콘솔용 ssh의 장점이라면, 메모리를 적게 차지하고, ssh.exe는 표준 출력을 사용하기 때문에, 자기가 좋아하는 언어로, 입출력을 control하기 위해 접근할 수 있는 것이 장점입니다.
(putty도 가볍긴 하지만, 표준 출력을 사용하는 것이 아니기 때문에, 입출력을 control하는 데는 문제가 있습니다.)

큰 단점은 아니지만, 단점이라면 콘솔에서 지원하는 인코딩만을 사용해야 하는데, 주로 LANG=C나 LC_ALL=C를 주고 영어로만 사용하고 있습니다.
아. 그리고 Keep Alive가 안된다...

가끔 사람들이 윈도우 콘솔에서 SSH연결해 하는 걸 보면 신기하게 보고 갑니다. ^^;

text file containing text files

내 에디터의 화면(현황)

지금 현재의 회사 컴퓨터의 에디터 화면입니다. 열어놓은 문서가 너무 많습니다.


그중에서도 제목없는 문서들이 굉장히 많습니다.
이 제목없는 문서들에도 필요한 내용들이 담겨 있는데, 대게 화일로 저장하지 않고 실행해본 스크립트언어의 코드들이 들어 있습니다.
(emeditor가 지원하는 WSH(즉, jscript나 vbscript)로 문서의 저장여부에 상관없이 현재 작성중인 ActiveDocument의 내용을 Windows Scripting Control에 전달해 실행해 보는 것이 가능합니다.)

전에는 Tab을 한줄로 하고, 기본으로 제공하는 Open Documents Plug-in을 사용해 보기도 했습니다만, Open Documents Plug-in으로도 창의 세로폭으로 나열할 수 있는 양보다 더 많은 문서를 열면 Scroll bar가 생기는데, Scroll bar로 올렸다 내렸다 하며 찾아 클릭해 activate시키는 것이 훨씬 더 불편하더군요 그래서 그냥 위의 이미지 대로 이렇게 쓰고 있었습니다.

그런데, 오늘 퇴근하면서 생각한 것입니다만, 하나의 에디터 창에 여러개의 문서를 함께 가지고 있으면 안될까 하는 생각이 들었습니다.

현대인에게의 (휴먼 인터페이스로서의)파일시스템(현황을 고찰)

우리가 현재 쓰고 있는 파일시스템은 User가 사용하는 인터페이스에 있어서 꽤 오래전의 그것과 크게 다르지 않습니다. 디렉토리가 있고, 파일이 있고, 하나의 파일에는 하나의 내용이 있습니다.
파일의 역할에 맞는 파일의 확장명이 있고, 이 확장명에 따라 기대되는 사용방법이 있습니다. (shell에 따라 shebang으로 기대하는 역할을 부여하기도 합니다.)

이러한 방식은, 컴퓨터에게 있어서는 꽤나 적합한 설계이고, 그렇기 때문에 지금까지도 이 방식이 사용되고 있는 것이라고 생각합니다..

그런데, 컴퓨터의 용량이 커지고,고속화된 지금. (그것도 C언어가 고안되던 70년대에 비하면 매우매우.) 전문직업인으로 컴퓨터를 다루는 사람에게는 매우 많은 파일을 다루게 되는 일이 많습니다.

오나마에의 스즈끼상은 이클립스를 2년째 정도 끈 적이 없는데, 언제나 열려있는 파일의 갯수는
50+ 라고 나옵니다. (100개 정도를 닫아보았는데도 50+로 표시되는 것이 똑같습니다.)

Legacy팀의 Gohko상은 vim를 잘 다루는데, 여러 디렉토리와 파일로 나누어 관리하는 것이 vim로는 귀찮았는지(vim은 훌륭한 에디터이지만, 여러 파일을 다루기는 역시 좀 귀찮겠지... 싶습니다.) 하나의 파일에 몽땅 적습니다. (그리고 나는 이 방식이 좋지 않다고 생각합니다.) 지금 작업중인 프로젝트에서는 perl 스크립트 코드가 1만줄이 넘었습니다. OTL.

Hmmm.....(문제를 일반화)

컴퓨터가 작업하는 단위로서 파일이라는 단위는 꽤 적합하다라고 생각한다고 얘기했습니다.
그런데, 전문 직업인이 작업으로 생각하고 있는 하나의 작업은 하나의 파일 이상일 때가 있습니다.

예를 들면 c언어의 프로그래밍에서 c파일은 대게 c파일과 h파일, make파일로 나뉩니다.
자바등과 같이 객체지향의 프로그래밍의 경우라면, 전통적인 방법으로 하나의 파일에 하나의 public 클래스를 가지도록 구성하지만, 작업의 단위라면 여러개의 클래스가 동시에 손대야 할 경우가 생깁니다.(interface와 class, abstract class의 구분도 그렇고, BL, DAO의 구분도 그렇습니다. ant니 properties니 xml이니 하는 것 까지 생각하면 더욱 그렇습니다.)
aspx파일과 그 code behind파일도 그렇구요.

그렇다면?

그렇다면 에디터에서의 하나의 편집중인 Document는, 여러개의 문서의 내용을 포함하고 있으면 어떨까 하는 것을 생각해 보았습니다.

SDI를 바탕으로 하는 MDI(고안)

단순하게 생각해 보았습니다.
하나의 SDI인 ActiveDocument에서, 파일을 구분하는 markup이 있으면, 하고 말입니다.
즉, 하나의 텍스트 파일이 작은 project파일과 같이 작동하는 방법입니다.
이렇게 말이죠.

<file path="c:\temp\makefile">

</file>
<file path="c:\temp\test.h">

</file>
<file path="c:\temp\test.c">

</file>

<file path="${ActiveDocument.Path}\makefile">
</file>

save를 하면 덩치가 큰 이 파일하나와 각 markup에 있는 파일들이 생성 또는 update되도록 하는 것이 기본 조건입니다.

이 방식으로는 100개 이상의 파일이니, 1만줄이니 하는 그런 큰 규모의 프로젝트를 하나의 SDI로 대체할 수는 없습니다만, 작업의 단위로 나눠 사용하기에는 나쁘지 않을까 합니다.

준비해야할 매크로로는

현재 커서가 있는 부분의 파일을 save 하는 매크로
현재 커서가 있는 부분의 파일을 load 하는 매크로
ActiveDocument가 포함하고 있는 파일을 전부 save 하는 매크로
실행커맨드가 있는 부분의 내용을 실행하는 매크로

등이 있으면 편리하겠군요.

아이디어는 여기까지 입니다만, 효율성이 많이 좋을 지는 사용해 봐야 알겠습니다.
#적어도 lex & yacc작업할 때는 편해지겠다는 생각이 듭니다.

Tuesday, September 1, 2009

본부장의 고민과 RedMine

현재 근무하고 있는 곳에서 재미있는 시도를 하고 있습니다.

지금의 회사에서는 메일을 지금껏 일해본 여느 회사보다 더 많이 사용합니다.
거의 모든 작업의뢰는 메일을 사용하여 전달하는 것을 기본으로 하고, CC도 굉장히 많이 입력합니다.

메일로 보고되는 것은 구두로 보고되는 것과 동일시 하게 취급됩니다.
메일의 사용에 있어, 특별히 교육받은 것은 없습니다만, 상식으로 여겨지고 있다라고 생각되는 것들이 몇가지 있는데,
예를 들면, 팀 멤버가 발송하는 메일은 누구에게 발송하든 CC로 팀 매니저를 넣는 것을 원칙으로 하고 있는 것 같습니다.
팀 매니저도 또한 관련된 모든 팀원은 CC로 넣어서 발송합니다. 또 팀간의 조정이 필요한 경우에는 부서장을 CC로 입력합니다.
CC가 없는 메일은 매우 드믑니다. 예를 들면, 패스워드를 전달하는 메일정도일까.

작업의 전달은 구두 + 메일을 원칙으로 합니다. 대인 접촉을 어려워하는 일본인의 특성이 더해져 있달까(plus 엔지니어의 특성),
구두 전달은 생략될 수 있습니다.
만일 전달이 명확하지 않은 경우는 받은 쪽에서 미팅을 의뢰합니다. 이 의뢰도 역시 메일로 전달이 됩니다.

여기서, 본부장의 고민이 발생했나봅니다.
메일로 보고는 되고있고, 정기적으로 매니저들간의 회의를 통해 이를 파악하고 있기는 하지만,

어느 부서가 어느 부서에게 어떤 의뢰를 받아 어떤 작업을 하고 있고, 어떤 이슈가 얼마만큼 로드가 걸려있고, 그 각각의 진행은 어떻게 되어 가고 있는 지,
부서의 Resource를 어디에 어떻게 운영해야 적절한 판단이 되고, 어느 시기에 어떻게 Resource를 충당해야 할 지 파악하기 어려웠나봅니다.
어느 팀이 사람이 없다라고 호소를 해도, 매 분기별 평가를 통해 팀의 성과를 평가하는 자료로도, 메일과 미팅으로만은 부족하고, 뭔가 다른 툴이 필요하다고 느꼈던 것 같습니다.

그래서 최근, Redmine을 통한 전체의 Activity를 일람해 보고자 하는 시도가 이루어졌습니다.
각 팀별, 세부 부서별, 프로젝트별 티켓시스템이라던지는 존재했었습니다만, 부서 전체에 대한 시도는 아직 없었습니다.
원래 Redmine은 프로젝트 툴입니다. 엔지니어라면 Trac을 선호하는 사람도 있겠습니다만, Calender와 Gantt등을 지원하는 Redmine쪽이 관리자의 측면에 좀 더 매리트가 있다는데 동의합니다.
이 툴의 도입에서 빛나는 부분은 부서간의 Activity를 한 눈에 알 수 있다라는 것입니다.

설정은

메인 프로젝트로 시스템본부,
서브프로젝트로 각각의 부서와 팀을 넣습니다. 이 프로젝트들은 실제 프로젝트가 아니라 부서를 대표하고 이슈를 관리하는 것이니, 부서, 팀이 존재하는 한 종료되지 않는 프로젝트가 됩니다.

멤버로는 시스템본부의 멤버 전원, 사업부의 멤버 전원, 그리고 몇명의 재무부와 인사부의 인원이 멤버로 등록되어 있습니다.

이슈로는 내부적으로 발생하는 작업이 아닌 부서간의 의뢰의 내용을 적습니다.
Issue Tracking Item으로는 다음과 같은 내용이 있습니다.

상재 서버 상태 확인 의뢰:
상재 서버의 설정 변경 의뢰:
상재 서버의 어플리케이션 거동 확인 의뢰:
데이터 추출 의뢰:
멘테넌스 대응 의뢰:
사내 메일 로그 조사 의뢰:
사전 상담:
장해에 관련하는 조사 의뢰:
돌발적인 작업 의뢰:
청구 관련의 처리 의뢰:

각 팀원이 이 시스템의 사용에 익숙해지기까지는 조금 시간이 걸리겠지요.
그러나 어떤 부서가 어떤작업을 하고 있는 지 한눈에 알기 쉽다라는 느낌입니다.
회사의 시스템을 캡춰해 계재할 수 없는 것이 안타깝습니다.

RedMine을 사용한 프로젝트는 여러차례 경험해 보았습니다만, 이러한 사용방식은 처음이었고, 꽤 Smart하다고 생각합니다.
비슷한 고민을 하고 있다면, 한 번쯤 도입을 연구해 보는 것도 좋다라고 생각합니다.
어쩌면 이미 사용하고 있는 곳이 벌써 많은지도.

tcc cgi, 그리고 몇가지 C trick에 대한 답입니다.

생각난 김에,
Tiny C Compiler로 cgi를 돌려보았습니다.

체감속도는,
perl 보다 빠른 듯했습니다.


----

if ( blah(), 5) {
//do something
}


blah();
if (5) {
// do something
}
와같습니다.


++i와 i++은 c에서는 퍼포먼스(연산속도)는 같습니다.
단, c++에서는 ++i가 더 좋습니다.

왜냐하면 c++에서는 ++연산자를 다음과 같이 operator overloading하기 때문입니다.
(정수의 경우)
// Prefix
Integer& Integer::operator++()
{
*this += 1;
return *this;
}

// Postfix
const Integer Integer::operator++(int)
{
Integer oldValue = *this;
++(*this);
return oldValue;
}


a[5] == 5[a] 는 true입니다.
왜냐하면

*(a + 5)와 *(5 + a)는 같기 때문입니다.
이렇게 연산하는 이유는 c가 디자인된 70년대 64k면 많은 메모리였던 당시,
많은 syntax checking을 할 수 없었기 때문에 무조건 *(a + 5)로 변환했기 때문입니다.
더불어
"ABCD"[2] == 2["ABCD"] 역시 true이고,
모두 'C' 를 나타냅니다.

----

그리고 최근(2009/8/27) boost c++ library 1.40이 발표되었습니다.
http://www.boost.org/
gcc 4.4를 지원한다고 하는데, 저는 아직 3.4.5를 사용하고 있습니다.
살며시 버전을 올리는 것도 생각해 봐야겠습니다.


#어느 곳에서는 operator overriding이라고도 하는군요.
#나는 redefinition 플러스 operand에 따라 동작을 추가할 수 있으므로 overloading쪽에 한표.