프로그래밍은 예술이다


임백준 ( 루슨트 테크놀로지스 )
2004/01/15


필자는 프로그래밍을 비교적 늦은 나이인 이십대 중반에 시작했다. 따라서 독학을 통해서 익힌 '초식'이 많았는데 그래서인지 10년이 지나도록 잘 고쳐지지 않는 습관이 하나 있다. 머리 속에 알고리즘의 윤곽이 떠오르면 일단 키보드를 붙잡고 코드를 두드려야만 직성이 풀리는 것이다. 그렇게 하지 않으면 다음 내용이 잘 떠오르지 않는다. 프로그래밍 방법론이나 소프트웨어 공학의 충고에 의하면 이것은 '코딩'이 '설계'에 앞서는 대단히 잘못된 방법에 속한다. 교과서에 적힌 기본을 무시하는 철저한 아마추어리즘의 소산인 것이다.


프로그래밍의 맛


여러 명의 개발자가 함께 코딩을 하는 경우에는 물론 얘기가 다르다. 그런 경우에는 레쇼날 로즈 ( Rational Rose ) 같은 소프트웨어나 객체 설계용 언어인 UML 을 이용해서 어느 정도 설계를 마친 다음에 코딩을 시작할 수밖에 없다. 하지만 프로그래밍을 혼자서 할 때는 언제나 '코딩'이 '설계'를 앞선다. "진정한 '프로'는 설계를 마친 다음에 비로소 키보드를 잡는 거야"라고 아무리 말해도 소용이 없다. 커피를 마실 때 크림을 넣지 않으면 맛이 느껴지지 않는 것처럼 손끝에 전달되는 키보드의 감촉이 없으면 프로그래밍의 '맛'이 느껴지지 않는다.


이런 습관은 회사에서 수행하는 공식적인 프로그래밍에도 종종 연결된다. 외부의 API 가 모두 결정된 상태에서 독립적인 컴포넌트의 내부를 구현하는 경우에는 예외 없이 코딩에서 부터 설계가 시작된다. 화면에 뜬 편집기 ( 필자의 경우에는 주로 vi ) 라는 캔버스 위에 키보드 커서라는 연필을 조금씩 움직여 나가면 머리 속에 감추어져 있던 알고리즘이 서서히 눈앞에 모습을 드러낸다. 때로는 종이 위에 동그라미, 네모, 선 등을 그리면서 설계를 하는 경우도 있지만 그것은 어디까지나 키보드를 통해서 하는 붓질을 돕는 보조적인 조치일 뿐이다.


프로그래밍에 '조예'가 있는 개발자라면 이런 습관은 그다지 자랑할 바가 아니라고 생각할 것이다. 당연하다. 필자도 아주 최근까지 그렇게 생각했다. 그렇지만 프로그래머 중에서 이와 같은 습관을 가지고 있는 사람이 적지 않으리라는 점은 분명하다. 손끝에 키보드의 감촉이 전달될 때 비로소 프로그래밍의 맛을 느끼는 사람은 결코 필자에 국한되는 얘기가 아닐 것이다.


하지만 그런 사람들조차 대부분 '설계'에 앞서는 '코딩'은 자랑할 바가 아니라고 생각한다. 특히 프로그래밍 실력이 뛰어난 고수일수록 설계를 마치기 전에는 키보드를 넘실거리지 않을 것이라고 믿는다. 뒤집어 말하면 설계를 끝내기 전에 키보드를 만지작거리는 사람은 일종의 '하수'로 간주되는 셈이다.


프로그래밍 예술론


필자가 이와 같은 '설계'와 '코딩'의 관계를 포함하여 흔히 알려진 프로그래밍의 방법론이나 소프트웨어 공학의 '교리'를 의심하기 시작한 것은 ( 지난 해에 두 권의 책을 쓰면서 ) 프로그래밍의 본질이 '공학'에 있는가 아니면, '예술'에 있는가 하는 문제를 고민하면서부터였다.


프로그래밍이 도대체 예술일 수 있는가에 대한 답을 구하려면 우선 예술이 무엇을 의미하는지 이해해야 하는데 그것은 간단하지 않은 주제이므로 여기서 다루기 어렵다. 하지만 한 가지 분명한 것은 필자의 관점에서 볼 때 프로그래밍은 공학적 요소를 포함하고 있긴 하지만 분명히 예술에 더 가깝다는 점이다.


프로그래밍을 예술로 파악하는 것은 물론 새로운 관점이 아니다. 「프로그래밍의 예술 ( The Art of Computer Programming )」로 유명한 스탠포드 대학의 도날드 카누스 교수는 일찍이 「문학적 프로그래밍 ( Literate Programming )」이라는 책에서 '프로그래밍은 예술'이라고 선언한 바 있다. 그는 이러한 선언을 한 걸음 더 밀고 나아가 프로그램 소스 코드도 다른 예술 작품들과 마찬가지로 미학적 요소와 독창성을 고려해서 '값'이 매겨지는 시대가 도래할 것이라고 예언하기까지 했다.


문학적 프로그래밍이란


카누스 교수가 말한 '문학적 프로그래밍'이란 사실 단순한 비유에서 그치는 것이 아니라 코드의 예술성을 담보하기 위한 일종의 구체적인 프로그래밍 방법론이었다. 우리나라에서는 「생각하는 프로그래밍」이라는 책으로 번역된 '프로그래밍 펄 ( Programming Pearl )'로 유명한 존 벤틀리는 카누스 교수가 '문학적 프로그래밍'을 설명한 글을 읽고 감명을 받은 나머지 자신의 컬럼 몇 개를 카누스 교수의 새로운 방법론을 소개하는데 바치기도 했다.


'프로그래밍은 예술'이라는 명제는 사실 수학 명제처럼 명쾌하게 증명될 수 있는 것이 아니다. 그러나 프로그래밍을 하는 사람이라면, 그 '맛'을 조금이라도 아는 사람이라면, 이 명제를 간단하게 거부하지 못할 것이다. 오픈소스 프로젝트에 참여하여 자신의 여가시간마저 프로그래밍에 바치는 해커든, 아니면 회사에 출퇴근하면서 정해진 틀에 따라 코딩을 하는 '월급쟁이'이든 상관이 없다.


프로그래밍이 단순히 기술이나 공학의 수준에 머무르지 않는다는 사실은 누구에게나 분명하다. 프로그래밍이라는 행위 안에는 꼭 집어서 설명할 수 없지만 가슴이 떨리고 흥분이 밀려오는 '창조적 긴장'의 순간이 담겨 있기 때문이다.


카누스 교수는 스스로 수학적 논리와 알고리즘에 대해서 실로 심오한 내공을 갖추고 있었다. 그런 맥락에서 그는 프로그래밍이 가지고 있는 '과학적 미학'의 측면을 강조했다. 이에 비해서 폴 그래이엄은 프로그래밍에 담겨 있는 '창조적 미학'의 측면을 날카롭게 부각시켰다. 그래이엄은 하버드에서 컴퓨터 공학 박사 학위를 받고 인공지능 언어인 LISP에 대한 교과서를 쓸 정도로 내공이 중후한 프로그래머였다. 뿐만 아니라 인터넷 붐이 한창이던 1998년에 ViaWeb 이라는 회사를 야후에 팔아서 '비즈니스맨'으로서도 이름을 얻었다.


그래이엄은 프로그래밍에 담긴 예술의 측면을 설명하기 위해서 프로그래밍을 그림 그리는 행위에 비유했다. 앞에서 그를 소개하면서 내공이 중후한 '프로그래머였다고' 말한 이유는 그가 지금은 그림 ( painting ) 을 공부하여 화가의 길을 걷고 있기 때문이다.


그가 보기에 프로그래밍은 순수한 논리나 학문의 대상이라기보다는 '실천적 행위'를 통해서 몸에 익혀 가는 구체적인 '행동'에 가까웠다. 그것은 마치 텅빈 백지 위에 붓을 한 번 크게 긋는 행위와 다를 바 없었다. 그래서 그는 컴퓨터 과학이라는 표현이 프로그래밍의 진정한 속성을 정확하게 담지 못한다고 비판했다.


프로그래밍이 '컴퓨터 과학' 혹은 '컴퓨터 공학'과 같지 않은 이유는 그림을 그리는 예술적 실천이 물감의 화학적 배합을 연구하는 '학문'과 같지 않은 이유와 동일하다. 다시 말해서 그림을 그리는 화가는 물감의 화학적 성분이나 여러 화학 이론에 대해서 굳이 알 필요가 없다.


이와 마찬가지로 프로그래밍이라는 창조적 활동을 하는 사람 ( 즉, 프로그래머 ) 들은 컴퓨터 과학과 공학의 수많은 이론을 굳이 자세하게 알 필요가 없다. 예를 들어서 튜링 기계나 오토마타의 개념 정도는 알 필요가 있을지 몰라도 복잡성 이론 ( complexity theory ) 에 등장하는 명제를 모두 읽어야만 좋은 프로그램을 만들 수 있는 것은 아니다.


코딩이 설계에 앞선다?

그래이엄을 알기 전까지 필자는 '코딩'이 '설계'를 앞서는 습관을 '아마추어리즘'의 표현이라고 생각해 왔다. 진정한 프로라면 교과서에서 가르치는 대로 정확하게 설계를 마친 다음 비로소 코딩을 시작해야 하는 것이라고 생각했다. 이런 강박관념은 일종의 열등감마저 수반했는데 그래이엄의 통찰은 필자를 '예술'이라는 아름다운 이름과 함께 구원해 주었다.


프로그래밍을 예술로 바라보는 관점에서 생각해 보면 '판에 박힌 듯한' 소프트웨어 개발 방법론은 프로그래머 개개인의 감성을 존중하기보다는 정해진 틀에 맞는 상품을 생산하기 원하는 기업의 욕망을 반영하고 있다. '획일적인 틀'은 상품 생산을 위해서 필요할 뿐 진정한 창조와 아무런 상관이 없기 때문이다.


뛰어난 프로그래머였던 그래이엄은 자기 자신도 프로그래밍을 할 때 키보드를 붙잡고 코딩부터 시작한다고 고백했다. 그가 밝힌 방법은 우선 가볍게 키보드를 두드리면서 코드의 전체 윤곽을 잡고, 다시 처음으로 돌아가서 조금씩 각 부분의 디테일을 살려 나가는 방식으로 프로그램을 작성하는 것이었다. 그는 코딩이 설계에 앞서는 이와 같은 방식을 조금도 이상하게 여기지 않았다. 오히려 그는 모든 예술적 창조가 대개 이와 비슷한 과정을 거치면서 이루어지며 그림을 그리는 과정도 이와 다르지 않다고 말했다. 그리고 미술에서는 그것을 '스케치'라는 자연스러운 이름으로 부른다고 지적했다.


혹시 필자가 이 글을 통해서 '코딩은 설계에 앞서야 한다'는 명제를 주장하고 있다고 잘못 이해하지 않기 바란다. 그것은 손으로 달을 가리켰더니 손가락만 바라보더라는 이야기와 다를 바 없는 오해가 될 것이다. 여러 명이 함께 복잡한 소프트웨어를 만들 때 '설계'의 과정이 결정적으로 중요하다는 사실에는 이견이 있을 수 없다. 다만 필자는 소프트웨어의 '생산성'을 높이기 위한 방법론이 반드시 프로그래밍의 '예술성'을 강화시키는 쪽으로 작용하지 않는다는, 아니 정확하게 말하자면 그 반대의 방향으로 작용한다는 사실을 지적하고 싶었을 뿐이다.


그럼 프로그래밍의 '예술성'을 강조하는 프로그래머는 그렇지 않은 프로그래머에 비해서 소프트웨어 '생산성'이 떨어지는 것일까? 놀랍게도 전혀 그렇지 않다. 오히려 그 반대의 경우가 더 많다. 창조의 기쁨을 아는 사람과 그렇지 않은 사람이 발휘하는 능력에는 본질적인 차이가 존재하기 때문이다. 필자가 이 글을 통해서 말하고 싶은 것이 바로 그 차이이다. '기쁨'이 있는 사람과 없는 사람 사이에 존재하는 차이는 프로그래밍의 예술적 속성을 이해하는데 있어서 핵심적인 열쇠가 된다

반응형

'Information' 카테고리의 다른 글

개발자 등급 기준 -출처 Codeway-  (0) 2007.03.03
프로그래머를 위한「공부론」  (0) 2007.03.03
각종 확장자 파일 모음  (0) 2007.03.03
우리 프로그래머들은 항상 공부해야 합니다. 우리는 지식을 중요하게 여깁니다. 하지만 지식에 대한 지식, 즉 내가 그 지식을 얻은 과정이나 방법 같은 것은 소홀히 여기기 쉽습니다. 따라서 지식의 축적과 공유는 있어도 방법론의 축적과 공유는 매우 드문 편입니다. 저는 평소에 이런 생각에서 학교 후배들을 위해 제 자신의 공부 경험을 짬짬이 글로 옮겨놓았고, 이번 기회에 그 글들을 취합, 정리하게 되었습니다. 그 결실이 바로 이 글입니다.
김창준 (마이크로소프트웨어) 2002/06/02
이 글은 공부하는 방법과 과정에 관한 글입니다. 이 글은 제가 공부한 성공/실패 경험을 기본 토대로 했고, 지난 몇 년간 주변에서 저보다 먼저 공부한 사람들의 경험을 관찰, 분석한 것에 제가 다시 직접 실험한 것과 그밖에 오랫동안 꾸준히 모아온 자료들을 더했습니다. '만약 다시 공부한다면' 저는 이렇게 공부할 것입니다.

부디 독자 제현께서 이 글을 씨앗으로 삼아 자신만의 나무를 키우고 거기서 열매를 얻고, 또 그 열매의 씨앗이 다시 누군가에게 전해질 수 있다면 더 이상 바랄 것이 없겠습니다.

이 글은 특정 주제들의 학습/교수법에 대한 문제점과 제가 경험한 좋은 공부법을 소개하는 식으로 구성됐습니다. 여기에 선택된 과목은 리팩토링, 알고리즘·자료구조, 디자인패턴, 익스트림 프로그래밍(Extreme Programming 혹은 XP) 네 가지입니다.

이 네 가지가 선택된 이유는 필자가 관심있게 공부했던 것이기 때문만은 아니고, 모든 프로그래머에게 어떻게든 널리 도움이 될만한 교양과목이라 생각하여 선택한 것입니다. 그런데 이 네 가지의 순서가 겉보기와는 달리 어떤 단계적 발전을 함의하는 것은 아닙니다. 수신(修身)이 끝나면 더 이상 수신은 하지 않고 제가(齊家)를 한다는 것이 어불성설인 것과 같습니다.

원래는 글 후미에 일반론으로서의 공부 패턴들을 쓰려고 했습니다. 하지만 지면의 제약도 있고, 독자 스스로 이 글에서 그런 패턴을 추출하는 것도 의미가 있을 것이기에 생략했습니다. 그런 일반론이 여기 저기 숨어있기 때문에 알고리즘 공부에 나온 방법 대부분이 리팩토링 공부에도 적용할 수 있고, 적용되어야 한다는 점을 꼭 기억해 주셨으면 합니다. 다음에 기회가 닿는다면 제가 평소 사용하는 (컴퓨터) 공부패턴들을 소개하겠습니다.

알고리즘·자료구조 학습에서의 문제
우리는 알고리즘 카탈로그를 배웁니다. 이미 그러한 해법이 존재하고, 그것이 최고이며, 따라서 그것을 달달 외우고 이해해야 합니다. 좀 똑똑한 친구들은 종종 "이야 이거 정말 기가 막힌 해법이군!"하고 감탄할지도 모릅니다. 대부분의 나머지 학생들은 그 해법을 이해하려고 머리를 쥐어짜고 한참을 씨름한 후에야 어렴풋이 왜 이 해법이 그 문제를 해결하는지 납득하게 됩니다.

그리고는 그 '증명'은 책 속에 덮어두고 까맣게 사라져버립니다. 앞으로는 그냥 '사용'하면 되는 것입니다. 더 많은 대다수의 학생은 이 과정이 무의미하다는 것을 알기 때문에 왜 이 해법이 이 문제를 문제없이 해결하는지의 증명은 간단히 건너뜁니다.

이런 학생들은 이미 주어진 알고리즘을 사용하는 일종의 객관식 혹은 문제 출제자가 존재하는 시험장 상황에서는 뛰어난 성적을 보일 것임은 자명합니다. 하지만 스스로가 문제와 해답을 모두 만들어내야 하는 상황이라면, 또는 해답이 존재하지 않을 가능성이 있는 상황이라면, 혹은 최적해를 구하는 것이 불가능에 가깝다면, 혹은 알고리즘을 완전히 새로 고안해내야 하거나 기존 알고리즘을 변형해야 하는 상황이라면 어떨까요?

교육은 물고기를 잡는 방법을 가르쳐야 합니다. 어떤 알고리즘을 배운다면 그 알고리즘을 고안해낸 사람이 어떤 사고 과정을 거쳐 그 해법에 도달했는지를 구경할 수 있어야 하고, 학생은 각자 스스로만의 해법을 차근차근 '구성'(construct)할 수 있어야 합니다(이를 교육철학에서 구성주의라고 합니다. 교육철학자 삐아제(Jean Piaget)의 제자이자, 마빈 민스키와 함께 MIT 미디어랩의 선구자인 세이머 페퍼트 박사가 주창했습니다). 전문가가 하는 것을 배우지 말고, 그들이 어떻게 전문가가 되었는지를 배우고 흉내 내야 합니다.

결국은 소크라테스적인 대화법입니다. 해답을 가르쳐 주지 않으면서도 초등학교 학생이 자신이 가진 지식만으로 스스로 퀵소트를 유도할 수 있도록 옆에서 도와줄 수 있습니까? 이것이 우리 스스로와 교사들에게 물어야 할 질문입니다.

왜 우리는 학교에서 '프로그래밍을 하는 과정'이나 '디자인 과정'(소프트웨어 공학에서 말하는 개발 프로세스가 아니라 몇 시간이나 몇 십 분 단위의, 개인적인 차원의 사고 과정 등을 일컫습니다)을 명시적으로 배운 적이 없을까요? 왜 해답에 이르는 과정을 가르쳐주는 사람이 없나요? 우리가 보는 것은 모조리 이미 훌륭히 완성된, 종적 상태의 결과물로서의 프로그램뿐입니다. 어느 날 문득 하늘에서 완성된 프로그램이 뚝 떨어지는 경우는 없는데 말입니다.

교수가 어떤 알고리즘 문제의 해답을 가르칠 때, "교수님, 교수님께서는 어떤 사고 과정을 거쳐, 그리고 어떤 디자인 과정과 프로그래밍 과정을 거쳐서 그 프로그램을 만드셨습니까?"하고 물어봅시다. 만약 여기에 어떤 체계적인 답변도 할 수 없는 분이라면 그 분은 자신의 사고에 대해 '사고'해 본 적이 없거나 문제 해결에 어떤 효율적 체계를 갖추지 못한 분이며, 따라서 아직 남을 가르칠 준비가 되어있지 않은 분일 것입니다. 만약 정말 그렇다면 우리는 어떻게 해야 할까요?

자료구조와 알고리즘 공부
제가 생각건대, 교육적인 목적에서는 자료구조나 알고리즘을 처음 공부할 때 우선은 특정 언어로 구현된 것을 보지 않는 것이 좋을 때가 많습니다. 대신 말로 된 설명이나 의사코드(pseudo-code) 등으로 그 개념까지만 이해하는 것이죠. 그 아이디어를 절차형(C, 어셈블리어)이나 함수형(LISP, Scheme, Haskell), 객체지향(자바, 스몰토크) 언어 등으로 직접 구현해 보는 겁니다. 그 다음에는 다른 사람이나 다른 책의 코드와 비교합니다. 이 경험을 애초에 박탈당한 사람은 귀중한 배움과 깨달음의 기회를 잃은 셈입니다.

만약 여러 사람이 함께 공부한다면 각자 동일한 아이디어를 같은 언어로 혹은 다른 언어로 어떻게 다르게 표현했는지를 서로 비교해 보면 배우는 것이 무척 많습니다.

우리가 자료구조나 알고리즘을 공부하는 이유는, 특정 '실세계의 문제'를 어떠한 '수학적 아이디어'로 매핑시켜 해결할 수 있는지, 그것이 효율적인지, 또 이를 컴퓨터에 어떻게 효율적으로 구현할 수 있는지 따지고, 그것을 실제로 구현하기 위해서입니다. 따라서 이 과정에 있어 실세계의 문제를 수학 문제로, 그리고 수학적 개념을 프로그래밍 언어로 효율적으로 표현해내는 것은 아주 중요한 능력이 됩니다.

알고리즘 공부에서 중요한 것
개별 알고리즘의 목록을 이해, 암기하며 익히는 것도 중요하지만 더 중요한 것은 다음 네 가지입니다.

①알고리즘을 스스로 생각해낼 수 있는 능력
②다른 알고리즘과 효율을 비교할 수 있는 능력
③알고리즘을 컴퓨터와 다른 사람이 이해할 수 있는 언어로 표현해낼 수 있는 능력
④이것의 정상작동(correctness) 여부를 검증해 내는 능력

첫 번째가 제대로 훈련되지 못한 사람은 알고리즘 목록의 스테레오 타입에만 길들여져 있어서 모든 문제를 자신이 아는 알고리즘 목록에 끼워 맞추려고 합니다. 디자인패턴을 잘못 공부한 사람과 비슷합니다. 이런 사람들은 마치 과거에 수학 정석만 수십 번 공부해 문제를 하나 던져주기만 하면, 생각해보지도 않고 자신이 풀었던 문제들의 패턴 중 가장 비슷한 것 하나를 기계적·무의식적으로 풀어제끼는 문제풀이기계와 비슷합니다. 그들에게 도중에 물어보십시오. "너 지금 무슨 문제 풀고 있는 거니?" 열심히 연습장에 뭔가 풀어나가고는 있지만 그들은 자신이 뭘 풀고 있는지도 제대로 인식하지 못 하는 경우가 많습니다.

머리가 푸는 게 아니고 손이 푸는 것이죠. 이렇게 되면 도구에 종속되는 '망치의 오류'에 빠지기 쉽습니다. 새로운 알고리즘을 고안해야 하는 상황에서도 기존 알고리즘에 계속 매달릴 뿐입니다. 알고리즘을 새로 고안해 내건 혹은 기존의 것을 조합하건 스스로 생각해 내는 훈련이 필요합니다.

두 번째가 제대로 훈련되지 못한 사람은 일일이 구현해 보고 실험해 봐야만 알고리즘 간의 효율을 비교할 수 있습니다. 특히 자신이 가진 카탈로그를 벗어난 알고리즘을 만나면 이 문제가 생깁니다. 이건 상당한 대가를 치르게 합니다.

세 번째가 제대로 훈련되지 못한 사람은, 문제를 보면 "아, 이건 이렇게 저렇게 해결하면 됩니다"하는 말은 곧잘 할 수 있지만 막상 컴퓨터 앞에 앉혀 놓으면 아무 것도 하지 못합니다. 심지어 자신이 생각해낸 그 구체적 알고리즘을 남에게 설명해 줄 수는 있지만, 그걸 '컴퓨터에게' 설명하는 데는 실패합니다. 뭔가 생각해낼 수 있다는 것과 그걸 컴퓨터가 이해할 수 있게 설명할 수 있다는 것은 다른 차원의 능력을 필요로 합니다.

네 번째가 제대로 훈련되지 못한 사람은, 알고리즘을 특정 언어로 구현해도, 그것이 옳다는 확신을 할 수 없습니다. 임시변통(ad hoc)의 아슬아슬한 코드가 되거나 이것저것 덧붙인 누더기 코드가 되기 쉽습니다. 이걸 피하려면 두 가지 훈련이 필요합니다.

하나는 수학적·논리학적 증명의 훈련이고, 다른 하나는 테스트 훈련입니다. 전자가 이론적이라면 후자는 실용적인 면이 강합니다. 양자는 상보적인 관계입니다. 특수한 경우들을 개별적으로 테스트해서는 검증해야 할 것이 너무 많고, 또 모든 경우에 대해 확신할 수 없습니다. 테스트가 버그의 부재를 보장할 수는 없습니다. 하지만 수학적 증명을 통하면 그것이 가능합니다. 또, 어떤 경우에는 수학적 증명을 굳이 할 필요 없이 단순히 테스트 케이스 몇 개만으로도 충분히 안정성이 보장되는 경우가 있습니다. 이럴 때는 그냥 테스트만으로 만족할 수 있습니다.

실질적이고 구체적인 문제를 함께 다루라
자료구조와 알고리즘 공부를 할 때에는 가능하면 실질적이고 구체적인 실세계의 문제를 함께 다루는 것이 큰 도움이 됩니다. 모든 학습에 있어 이는 똑같이 적용됩니다. 인류의 지성사를 봐도, 구상(concrete) 다음에 추상(abstract)이 옵니다. 인간 개체 하나의 성장을 봐도 그러합니다. 'be-동사 더하기 to-부정사'가 예정으로 해석될 수 있다는 룰만 외우는 것보다 다양한 예문을 실제 문맥 속에서 여러 번 보는 것이 훨씬 나을 것은 자명합니다. 알고리즘과 자료구조를 공부할 때 여러 친구들과 함께 연습문제(특히 우리가 경험하는 실세계의 대상들과 관련이 있는 것)를 풀어보기도 하고, ACM의 ICPC(International Collegiate Programming Contest: 세계 대학생 프로그래밍 경진 대회) 등의 프로그래밍 경진 대회 문제 중 해당 알고리즘·자료구조가 사용될 수 있는 문제를 같이 풀어보는 것도 아주 좋습니다. 이게 가능하려면 "이 알고리즘이 쓰이는 문제는 이거다"하고 가이드를 해줄 사람이 있으면 좋겠죠. 이것은 그 구체적 알고리즘·자료구조를 훈련하는 것이고, 이와 동시에 어떤 알고리즘을 써야할지 선택, 조합하는 것과 새로운 알고리즘을 만들어내는 훈련도 무척 중요합니다.

알고리즘 디자인 과정의 중요성
알고리즘을 좀더 수월하게, 또 잘 만들려면 알고리즘 디자인 과정에 대해 생각해 봐야 합니다. 그냥 밑도 끝도 없이 문제를 쳐다본다고 해서 알고리즘이 튀어나오진 않습니다. 체계적이고 효율적인 접근법을 사용해야 합니다. 대표적인 것으로 다익스트라(E. W. Dijkstra)와 워스(N. Wirth)의 '조금씩 개선하기'(Stepwise Refinement)가 있습니다. 워스의 「Program Development by Stepwise Refinement」(1971, CACM 14.4, http://www.acm.org/classics/dec95)를 꼭 읽어보길 바랍니다. 여기 소개된 조금씩 개선하기는 구조적 프로그래밍에서 핵심적 역할을 했습니다(구조적 프로그래밍을 'goto 문 제거' 정도로 생각하면 안 됩니다). 다익스트라의 「Stepwise Program Construction」(Selected Writings on Computing: A Personal Perspective, Springer-Verlag, 1982, http://www.cs.utexas.edu/users/EWD/ewd02xx/EWD227.PDF)도 추천합니다.

알고리즘 검증은 알고리즘 디자인과 함께 갑니다. 새로운 알고리즘을 고안할 때 검증해 가면서 디자인하기 때문입니다. 물론 가장 큰 역할은 고안이 끝났을 때의 검증입니다. 알고리즘 검증에는 루프 불변식(loop invariant) 같은 것이 아주 유용합니다. 아주 막강한 무기입니다. 익혀 두면 두고두고 가치를 발휘할 것입니다. 맨버(Udi Manber)의 알고리즘 서적(『Introduction to Algorithms: A Creative Approach』)이 알고리즘 검증과 디자인이 함께 진행해 가는 예로 자주 추천됩니다. 많은 계발을 얻을 것입니다. 고전으로는 다익스트라의 『A Discipline of Programming』과 그라이스(Gries)의 『The Science of Programming』이 있습니다. 특히 전자를 추천합니다. 프로그래밍에 대한 관을 뒤흔들어 놓을 것입니다.

알고리즘과 패러다임
알고리즘을 공부하면 큰 줄기들을 알아야 합니다. 개별 테크닉도 중요하지만 '패러다임'이라고 할만한 것들을 알아야 합니다. 이것에 대해서는 튜링상을 수상한 로버트 플로이드(Robert Floyd)의 튜링상 수상 강연(The Paradigms of Programming, 1978)을 추천합니다. 패러다임을 알아야 알고리즘을 상황에 맞게 마음대로 변통할 수 있습니다. 그리고 자신만의 분류법을 만들어야 합니다. 구체적인 문제들을 케이스 바이 케이스로 여럿 접하는 동안 그냥 지나쳐 버리면 개별자는 영원히 개별자로 남을 뿐입니다. 비슷한 문제들을 서로 묶어서 일반화해야 합니다.

이런 패러다임을 발견하려면 '다시 하기'가 아주 좋습니다. 다른 것들과 마찬가지로, 이 다시 하기는 알고리즘에서만이 아니고 모든 공부에 적용할 수 있습니다. 같은 것을 다시 해보는 것에서 우리는 얼마나 많은 것을 배울 수 있을까요. 대단히 많습니다. 왜 동일한 문제를 여러 번 풀고, 왜 같은 내용의 세미나에 또 다시 참석하고, 같은 프로그램을 거듭 작성할까요? 훨씬 더 많이 배울 수 있기 때문입니다. 화술 교육에서는 같은 주제에 대해 한 번 말해본 연사와 두 번 말해본 연사는 천지 차이가 있다고 말합니다. 같은 일에 대해 두 번의 기회가 주어지면 두 번째에는 첫 번째보다 잘 할 기회가 있습니다. 게다가 첫 번째 경험했던 것을 '터널을 벗어나서' 다소 객관적으로 볼 수 있게 됩니다. 왜 자신이 저번에 이걸 잘 못 했고, 저걸 잘 했는지 알게 되고, 어떻게 하면 그걸 더 잘할 수 있을는지 깨닫게 됩니다. 저는 똑같은 문제를 여러 번 풀더라도 매번 조금씩 다른 해답을 얻습니다. 그러면서 정말 엄청나게 많은 것을 배웁니다. '비슷한 문제'를 모두 풀 능력이 생깁니다.

제가 개인적으로 존경하는 전산학자 로버트 플로이드(Robert W. Floyd)는 1978년도 튜링상 강연에서 다음과 같은 말을 합니다.


제가 어려운 알고리즘을 디자인하는 경험을 생각해 볼 때, 제 능력을 넓히는 데 가장 도움이 되는 특정한 테크닉이 있습니다. 어려운 문제를 푼 후에, 저는 그것을 처음부터 완전히 새로 풉니다. 좀 전에 얻은 해법의 통찰(insight)만을 유지하면서 말이죠. 해법이 제가 희망하는 만큼 명료하고 직접적인 것이 될 때까지 반복합니다. 그런 다음, 비슷한 문제들을 공략할 어떤 일반적인 룰을 찾습니다. 아까 주어진 문제를 아예 처음부터 최고로 효율적인 방향에서 접근하도록 이끌어줬을 그런 룰을 찾는 거죠. 많은 경우에 그런 룰은 불변의 가치가 있습니다. … 포트란의 룰은 몇 시간 내에 배울 수 있습니다. 하지만 관련 패러다임은 훨씬 더 많은 시간이 걸립니다. 배우거나(learn) 배운 것을 잊거나(unlearn) 하는 데 모두.

수학자와 프로그래머를 포함한 모든 문제 해결자들의 고전이 된 죠지 폴리야(George Polya)의 『How to Solve it』에는 이런 말이 있습니다:

심지어는 꽤나 훌륭한 학생들도, 문제의 해법을 얻고 논증을 깨끗하게 적은 다음에는 책을 덮어버리고 뭔가 다른 것을 찾는다. 그렇게 하는 동안 그들은 그 노력의 중요하고도 교육적인 측면을 잃어버리게 된다. … 훌륭한 선생은 어떠한 문제이건 간에 완전히 바닥이 드러나는 경우는 없다는 관점을 스스로 이해하고 또 학생들에게 명심시켜야 한다.

저는 ACM의 ICPC 문제 중에 어떤 문제를 이제까지 열 번도 넘게 풀었습니다. 대부분 짝 프로그래밍이나 세미나를 통해 프로그래밍 시연을 했던 것인데, 제 세미나에 여러 번 참석한 분이 농담조로 웃으며 물었습니다. "신기해요. 창준 씨는 그 문제를 풀 때마다 다른 프로그램을 짜는 것 같아요. 설마 준비를 안 해 와서 그냥 내키는 대로 하는 건 아니죠?" 저는 카오스 시스템과 비슷하게 초기치 민감도가 프로그래밍에도 작용하는 것 같다고 대답했습니다. 저 스스로 다른 해법을 시도하고 싶은 마음이 있으면 출발이 조금 다르고, 또 거기서 나오는 진행 방향도 다르게 됩니다. 그런데 중요한 것은 이렇게 같은 문제를 매번 다르게 풀면서 배우는 것이 엄청나게 많다는 점입니다. 저는 매번, 전보다 개선할 것을 찾아내게 되고, 또 새로운 것을 배웁니다. 마치 마르지 않는 샘물처럼 계속 생각할 거리를 준다는 점이 참 놀랍습니다.

알고리즘 개론 교재로는 CLR(Introduction to Algorithms, Thomas H. Cormen, Charles E. Leiserson, and Ronald L. Rivest)을 추천합니다. 이와 함께 혹은 이 책을 읽기 전에 존 벤틀리(Jon Bentley)의 『Programming Pearls』도 강력 추천합니다. 세계적인 짱짱한 프로그래머와 전산학자들이 함께 꼽은 위대한 책 목록에서 몇 손가락 안에 드는 책입니다. 아직 이 책을 본 적이 없는 사람은 축하합니다. 아마 몇 주간은 감동 속에 하루하루를 보내게 될 겁니다.

리팩토링 학습에서의 문제
먼저, 본지 2001년 11월호에 제가 썼던 마틴 파울러의 책을 추천하는 글을 인용하겠습니다.

OOP를 하건 안 하건 프로그래밍이란 업을 하는 사람이라면 이 책은 자신의 공력을 서너 단계 레벨업시켜줄 수 있다. 자질구레한 술기를 익히는 것이 아니고 기감과 내공을 증강하는 것이다.

혹자는 DP 이전에 RF를 봐야 한다고도 한다. 이 말이 어느 정도 일리가 있는 것이, 효과적인 학습은 문제의식이 선행해야 하기 때문이다. DP는 거시적 차원에서 해결안을 모아놓은 것이다. RF를 보고 나쁜 냄새(Bad Smell)를 맡을 수 있는 후각을 발달시켜야 한다. RF의 목록을 모두 외우는 것은 큰 의미가 없다. 그것보다 냄새나는 코드를 느낄 수 있는 감수성을 키우는 것이 더 중요하다. 필자는 일주일에 한 가지씩 나쁜 냄새를 정해놓고 그 기간 동안에는 자신이 접하는 모든 코드에서 그 냄새만이라도 확실히 맡도록 집중하는 방법을 권한다. 일명 일취집중후각법. 패턴 개념을 만든 건축가 크리스토퍼 알렉산더나 GoF의 랄프 존슨은 좋은 디자인이란 나쁜 것이 없는 상태라고 한다. 무색 무미 무취의 무위(無爲)적 자연(自然) 코드가 되는 그 날을 위해 오늘도 우리는 리팩토링이라는 유위(有爲)를 익힌다.

주변에서 리팩토링을 잘못 공부하는 경우를 종종 접합니다. 어떤 의미에서 잘못 공부한다고 할까요? '실체화'가 문제입니다. 리팩토링은 도구이고 방편일 뿐인데, 그것에 매달리는 것은 달은 보지 않고 손을 보는 것과 같습니다. 저는 리팩토링 책이 또 하나의 (이미 그 병폐가 많이 드러난) GoF 책이 되는 현상이 매우 걱정됩니다.

리팩토링 공부
사람들이 일반적으로 생각하는 바와는 달리 리팩토링 학습에 있어 어떤 리팩토링이 있는지, 구체적으로 무엇인지 등의 리팩토링 목록에 대한 지식과 각각에 대한 메카닉스(Mechanics: 해당 리팩토링을 해나가는 구체적 단계)는 오히려 덜 중요할 수 있습니다. 더 기본적이고 유용한 것은 코드 냄새(Code Smell)와 짧은 테스트-코드 싸이클입니다. 이것만 제대로 되면 리팩토링 책의 모든 리팩토링을 스스로 구성해낼 수 있으며, 다른 종류의 리팩토링까지 직접 발견해낼 수 있습니다.

그 책에서는 테스트의 중요성이 충분히 강조되지 않았습니다. 하지만 테스트 코드 없는 리팩토링은 안전벨트 없는 자동차 경주와 같습니다. 그리고 테스트 코드가 리팩토링의 방향을 결정하기도 합니다. 양자는 음과 양처럼 서로 엮여 있습니다. 이런 의미에서 리팩토링은 TDD(Test Driven Development)와 함께 수련하는 것이 좋습니다. 훨씬 더 빨리, 훨씬 더 많은 것을 배울 수 있을 겁니다.

리팩토링을 공부할 때는 우선 코드 냄새의 종류를 알고, 왜 그것이 나쁜 냄새가 될 수 있는지 이해하고(그게 불가하다면 리팩토링 공부를 미뤄야 합니다) 거기에 동의할 수 있어야 합니다. 그런 다음, 대충 어떤 종류의 리팩토링이 가능한지 죽 훑어봅니다. 그 중 몇 개는 메카닉스를 따라가면서 실험해 봅니다. 이제는 책을 덮습니다. 그리고 실제 코드를 접하고, 만약 거기에서 냄새를 맡는다면 이 냄새를 없애기 위해 어떻게 해야 할지 스스로 고민합니다. 리팩토링 책의 목록은 일단 무시하십시오. 그 냄새를 없애는 것이 목표이지, 어떤 리팩토링을 여기에 '써먹는 것'이 목표가 되어선 안 됩니다. 이 때, 반드시 테스트 코드가 있어야 합니다. 그래야 '좋은' 리팩토링을 할 수 있습니다. 책을 떠나 있으면서도 책에서 떠나지 않는 방법입니다.

리팩토링을 하기 전에 초록색 불(테스트가 모두 통과)이 들어온 시점에서 코드를 일부 고치면 빨간 불(테스트가 하나라도 실패)로 바뀔 겁니다. 이게 다시 초록색 불이 될 때까지 최소한도의 시간이 걸리도록 하십시오. 현 초록색에서 다음 초록색까지 최소한의 시간을 소비하도록 하면서 코드와 테스팅을 오가게 되면 자기도 모르는 사이에 훌륭한 리팩토링이 자발공으로 터져 나옵니다. 여기서 목적지는 우선은 OAOO(Once And Only Once: 모든 것은 오로지 한 번만 말해야 한다)를 지키는 쪽으로 합니다. 그러면 OAOO와 짧은 테스트-코드 싸이클을 지키는 사이 어느새 탁월한 디자인이 튀어나옵니다. 참고로 저는 '모래시계 프로그래밍'이란 걸 가끔 합니다. 모래시계나 알람 프로그램으로 테스트-코드 사이클의 시간을 재는 것입니다. 그래서 가급적이면 한 사이클이 3분 이내(대부분의 모래시계는 단위가 3분입니다)에 끝나도록 노력합니다. 여기서 성공을 하건 실패를 하건 많은 걸 얻습니다.

리팩토링 수련법
제가 고안, 사용한 몇 가지 리팩토링 수련법을 알려드립니다.

①일취집중후각법: 앞에 소개한 본지 2001년 11월호에서 인용된 글 참조
②주석 최소화: 주석을 최소화하되 코드의 가독성이 떨어지지 않도록(혹은 오히려 올라가도록) 노력합니다. 이렇게 하면 자동으로 리팩토링이 이뤄지는 경우가 많습니다.
③OAOO 따르기: OAOO 법칙을 가능하면 최대한, 엄격하게 따르려고 합니다. 역시 자동으로 좋은 리팩토링이 이뤄집니다. 여기서 디자인패턴이 창발하기도 합니다. GoF 책을 한번도 보지 못한 사람이 디자인패턴을 자유자재로 부리는 경우를 보게 됩니다.
④디미터 법칙(Law of Demeter) 따르기: 디미터 법칙을 가능하면 지키려고 합니다. 어떤 리팩토링이 저절로 이뤄지거나 혹은 필요 없어지는가요?
⑤짝(Pair) 리팩토링: 함께 리팩토링합니다. 혼자 하는 것보다 더 빨리, 더 많은 걸 배우게 됩니다. 특히, 각자 작성했던 코드를 함께 리팩토링하고, 제3자의 코드를 함께 리팩토링해 봅니다. 사람이 많다면 다른 짝이 리팩토링한 것과 서로 비교하고 토론합니다.
⑥'무엇'과 '어떻게'를 분리: 어떻게에서 무엇을 분리해 내도록 합니다. 어떤 리팩토링이 창발합니까?

여기서 번, 짝 리팩토링은 아주 효과적인 방법입니다. 저는 이것을 협동적 학습(Collaborative Learning)이라고 부릅니다. 상대가 나보다 더 많이 아는 경우만이 아니고, 서로 아는 것이 비슷해도 많은 양의 학습이 발생합니다. 특히, 전문가와 함께 짝 프로그래밍을 하면 무서울 만큼 빠른 학습을 경험할 수 있습니다. 저와 짝 프로그래밍을 한 사람이 학습하는 속도에서 경이감을 느낀 적이 한두 번이 아닙니다. 문화는 사회적으로 학습되는 것입니다. 우리가 지식이라고 하는 것의 상당 부분은 문화처럼 암묵적인 지식(Tacit Knowledge)입니다. 전문가가 문제가 생겼을 때 어떻게 사고하고, 어떤 과정을 거쳐 접근하며, 어떻게 디버깅하고, 키보드를 어떤 식으로 누르는지, 사고 도구로 무엇을 사용하는지, 일 계획과 관리를 어떻게 하는지, 동료와 어떻게 대화하는지 등은 성문화되어 있지 않습니다. 그러나 이런 것들은 아주 중요합니다. 프로페셔널의 하루 일과의 대부분을 이루고 있기 때문입니다. 이런 것들은 전문가 바로 옆에서 조금씩 일을 도와주면서 배워야 합니다. 도제 살이(Apprenticeship)입니다. 진정한 전문가는 모든 동작이 우아합니다. 마치 춤을 추는 것 같습니다. 이 모습을 바로 곁에서 지켜보게 되면, 주니어는 한마디로 엄청난 충격을 받습니다. 그리고 스펀지처럼 빨아들이게 됩니다. 도대체 이 경험을 책이나 공장화한 학교가 어떻게 대신하겠습니까. 이와 관련해서는 레이브와 웽거(Jean Lave, Etienne Wenger)의 『Situated Learning : Legitimate Peripheral Participation』을 강력 추천합니다. 이 글을 보는 모든 교육 종사자들이 꼭 읽어봤으면 합니다. 이 협동적 학습은 두 사람만이 아니고 그룹 단위로도 가능합니다. 스터디에 이용하면 재미와 유익함 일석이조를 얻습니다.

이 외에, 특히(어쩌면 가장) 중요한 것은 일취집중후각법 등을 이용해 자신의 코드 후각의 민감도를 높이는 것입니다. 코드 후각의 메타포 말고도 유사한 메타포가 몇 가지 더 있습니다. 켄트 벡은 코드의 소리를 들으라고 하고, 저는 코드를 향해 대화하라고 합니다. 코드의 소리를 듣는 것은 코드가 원하는 것에 귀를 기울이는 것을 말합니다. 코드는 단순해지려는 욕망이 있습니다. 그걸 이뤄주는 것이 프로그래머입니다. 그리고 짝 프로그래밍을 할 때 두 사람의 대화를 코드에 남기도록 합니다. 주석이 아닙니다. 왜 이것이 중요한가는 본지 2001년 12월호 「허실문답 XP 강화」를 참고하기 바랍니다.

기학으로 우리 사상사에 큰 획을 그은 철학자요, '서울서 책만 사다 망한 사람'으로 이름을 날릴 정도로 엄청난 지식욕을 과시하던 조선시대 사상가 혜강 최한기는 그의 저술 『신기통』(神氣通)에서 '눈에 통하는 법(目通), 귀에 통하는 법(耳通), 코에 통하는 법(鼻通)' 등을 이야기하고 있습니다. 어떻게 하면 우리는 코드에 도통할 수 있을까요? 리팩토링을 공부하거나 혹은 했던 사람들에게 많은 영감과 메타포를 주는 책으로 일독을 권합니다. 필자가 기회가 닿는다면 프로그래밍을 혜강의 사상적 측면에서 조망한 글을 써보고 싶습니다.

앞서의 것들이 어느 정도 이뤄지고, 리팩토링에 대한 감이 오게 되면 그 때 비로소 리팩토링 책을 하나 하나 파헤치고 또 거기서 제대로 된 비판을 할 수 있게 됩니다.

디자인패턴 학습에서의 문제
잡지에 연재되거나 서적으로 출간된 혹은 세미나에서 진행되었던 디자인패턴 '강의'를 몇 가지 접했습니다. 훌륭한 강의도 많았지만 그렇지 못한 것도 있었습니다. 몇 가지 문제점을 지적하겠습니다.

◆패턴을 지나치게 실체화, 정형화해 설명한다.
◆컨텍스트와 문제 상황에 대한 설명이 없거나 부족하다. 결과적으로 문제를 해결하기 위해 패턴이 도입된 것이 아니라 패턴을 써먹기 위해 패턴이 도입된 느낌을 준다.
◆문제의식을 먼저 형성하게 하지 않고 답을 먼저 보여준 뒤 그걸 어디에 써먹을지 가르친다. 왜 이걸 쓰는 게 좋은지는 일언반구 언급이 없다. 독자는 '어린아이가 망치를 들고 있는 오류'에 빠질 것이다.
◆패턴이 어떻게 생성되었는지 그 과정을 보여주지 못한다. 즉, 스스로 패턴을 만들어내는 데 도움이 전혀 되지 않는다.
◆해당 패턴이 현실적으로 가장 자주 쓰이는 맥락을 보여주지 못한다. 대부분 장난감 문제(Toy Problem)에서 끝난다.

그런 패턴 강의를 하는 분들이 알렉산더(Christopher Alexander, 패턴언어 창시자)의 저작을 충실히 읽어봤다면 이런 병폐는 없을 것이라 생각합니다. 알렉산더의 저작을 접해보지 못 하고서 패턴을 가르치는 사람은 성경을 읽어보지 않은 전도사와 같을 것입니다. 알렉산더가 『The Timeless Way of Building』의 마지막에서 무슨 말을 하는가요?

이 마지막 단계에는 더 이상 패턴은 중요하지 않다. … 패턴은 당신이 현실적인 것에 대해 수용적이 되는 것을 가르쳐줬다.

패턴 역시 도구요, 방편일 뿐입니다. 패턴은 현실적인 것에 대해 수용적이 되도록 가르친다는 말은 결국 우리가 궁극적으로 추구하는 것은 패턴이 아니라 현실이어야 한다는 이야기입니다. 물론 처음 단계에는 교육적인 목적에서, 어느 정도 패턴에 얽매여도 괜찮다고는 해도, 나중에 패턴을 잊고 패턴에서 자유로워지려면 처음부터 패턴에 대해 도구적·방편적인 인식을 가져야 합니다.

미국 캘리포니아 주립대학의 교수 베티 에드워즈(Betty Edwards)가 쓴 책 중에 『Drawing on the Right Side of the Brain』이라는 유명한 베스트셀러가 있습니다. 사람의 뇌와 그림 그리기의 관계에 대한 탁월한 책입니다. 에드워즈는 자신의 그리기 실력을 향상시키기 위해 우뇌를 적극적으로 사용하는 구체적인 방법들을 가르쳐줍니다. 그 중 대표적인 것 하나가 대상을 뒤집어 놓고 그리는 것입니다. 지금 실험해 보길 바랍니다. 1000원권 지폐를 바로 놓고 그걸 비슷하게 그려보고, 이번에는 그걸 위아래가 거꾸로 되게 놓고 따라 그려보십시오. 아마 무척 놀랐을 겁니다. "아니 내가 이렇게 그림을 잘 그리다니! 그것도 거꾸로!" 그렇습니다. 우리는 자신의 머리 속 패턴에 얽매여 세상을 제대로 보지 못 할 때가 많습니다. 실체가 코에 약간이라도 비슷하게 보이면 우리는 그것을 이미 우리 머리 속에 추상적으로 갖고 있던 기하학적 '코'의 패턴으로 대체해버리는 것입니다.

디자인 패턴 공부
우선은 제 교육철학과 언어교습론, 그리고 공부론 이야기를 잠깐 하겠습니다.

기본적으로 교육은 교육자가 피교육자가에게 지식을 그대로 전달하는 행위가 아닙니다. 진정한 교육은 피교육자의 개인적 체험에 기반한 전폭적 동의에서 출발합니다. 저는 이를 동의에 의한 교육이라고 합니다.

제가 "주석문을 가능하면 쓰지 않는 것이 더 좋다"는 이야기를 했을 때 이 문장을 하나의 사실로 받아들이고 기억하면 당장 그 시점에는 학습이 일어나지 않는다고 봅니다. 대신 여러분이 차후에 여러 가지 경험을 하면서도 이 화두를 놓치지 않고 있다가 어느 순간엔가, "아! 그래, 주석문을 쓰지 않는 게 좋겠구나!"하고 자각하는 순간, 바로 그 시점에 학습과 교육이 이뤄지는 것입니다. 이는 기본적으로 삐아제와 비갓스키(Lev Vygotsky)의 구성주의를 따르는 것이죠. 지식이란 외부에서 입력받는 것이 아니고, 그것에 대한 모델을 학습자 스스로가 내부에서 구축할 때 획득할 수 있는 것이라는 사상이죠.

권법에서 주먹에 대해 달통한 도사가 '권을 내지르는 법'에 대한 규칙들을 정리해서 애제자의 머리 속에 아무리 쑤셔 넣는 데 성공한들 그 제자가 도사만큼 주먹이 나갈리는 만무합니다. 권을 내지르는 법을 유추해 내기까지 그 스승이 겪은 과정을 제자는 완전히 쏙 빼먹고 있기 때문입니다. 소위 '몸'이 만들어지지 않은 것이지요. 제자는 마당 쓸기부터, 물 긷기 등의 수련 과정을 겪어야만 하고 스승이 정리한 그 일련의 규칙에 손뼉을 치고 춤을 추며 기쁨의 동의를 할 수 있을 정도로 수련 과정이 축적된 이후에야 비로소 진정한 '가르침'이 이뤄지는 것이며, 청출어람의 가능성도 생각해 볼 수 있는 것입니다.

이런 동의라는 것은 학습자 자신만의 컨텍스트와 문제의식을 바탕으로 한 것입니다. 우리는 많은 경우, 어떤 지식과 동시에 그 지식의 필요성까지도 지식화해서 외부에서 주입을 받습니다. 하지만 진정 체화된 지식을 위해서는 스스로가 이미 문제의식을 갖고 있어야 합니다.

패턴도 마찬가지인데, 대부분 그 패턴의 필요성을 체감하지 못한 채 그냥 도식적 구조를 외우기에만 주력하는 사람이 많습니다만, 사실 그렇게 되면 어떤 경우에 이 패턴이 필요하고 어떤 경우에는 사용하면 안 되는지(GoF는 패턴을 정말 안다는 것은 그 패턴을 쓰면 안 될 때를 아는 것이라 했습니다) 등을 알기 힘듭니다. 설령 책에 나온 가이드를 암기했더라도요. 자신의 삶 속에서 문제의식이 구체적으로 실제 경험으로 형성되지 않았기 때문입니다.

GoF 중 한 명인 랄프 존슨(Ralph Johnson)은 다음과 같이 말합니다.

우리[GoF]는 책에서, 정말 그 패턴들이 필요하다는 것을 알만큼 충분한 경험을 갖기 전에는 그것을 [시스템 속에] 집어넣는 것을 피해야 한다고 말할 만큼 대담하진 못했다. 하지만 우리 모두는 그 사실을 믿었다. 패턴은 프로그램의 초기 버전이 아니고 프로그램 생애의 훨씬 나중에 가서야 비로소 등장해야 한다고 나는 늘 생각해 왔다.

결국은 어떤 패턴의 필요성을 자신의 경험 속에서 절감하지 못한다면 그 패턴을 제대로 아는 것이 아니라고 말할 수 있을 겁니다. 따라서 패턴 하나를 공부할 때는 가능한 한 실제 예를 많이 접해야 합니다. 그리고 패턴을 적용하지 않은 경우에서 그 필요를 느끼고 설명할 수 있게끔 다양한 코드를 접해야 합니다.

소프트웨어 개발에 푹 빠지기
패턴 중에 보면 서로 비슷비슷한 것이 상당히 많습니다. 그 구조로는 완전히 동일한 것도 있죠. 초보자를 괴롭히는 것 중 하나입니다. 이것은 외국어를 공부할 때 문법 중심적인 학습을 하면서 부딪치는 문제와 비슷합니다. '주어+동사+목적어'라는 구조로는 동일한 두 개의 문장, 즉 'I love you'와 'I hate you'가 구조적으로는 동일할지라도 의미론적으로는 완전히 반대가 될 수 있는 겁니다. 패턴을 공부할 때는 그 구조보다 의미와 의도를 우선해야 하며, 이는 다양한 실례를 케이스 바이 케이스로 접하면서 추론화 및 자신만의 모델화라는 작업을 통해 하는 것이 최선입니다. 스스로 문법을 발견하고 체득하는 것이라고 할까요.

DP는 사전과 같습니다. 이 책은 순서대로 소설 읽듯이 읽어나가라고 집필된 것이 아니고, 일종의 패턴 레퍼런스로 쓰인 것입니다. 역시 GoF의 한 명인 존 블리스사이즈(John Vlissides)는 다음과 같이 말합니다.

여기서 내가 강조하고 싶은 것은 디자인패턴, 즉 GoF 책을 어떻게 읽느냐는 것이다. 많은 사람들은 그 내용을 온전히 이해하기 위해서는 순서대로 읽어야 한다고 느낀다. 하지만 GoF는 소설이 아니라 레퍼런스 북이다. 독일어를 배우기 위해 독영 사전의 처음부터 끝까지 하나하나 읽으려고 하는 경우를 생각해 보라. 그렇게는 결코 배울 수 없을 것이다! 독일어를 마스터하기 위해서는 독일어 문화에 자기 자신을 푹 담궈야(immerse) 한다. 독일어로 살아야 하는 것이다. 디자인패턴도 똑같다. 그걸 마스터하기 이전에 소프트웨어 개발에 자신을 푹 담궈야 한다. 패턴으로 살아야 하는 것이다.
만약 꼭 그래야 한다면 소설 읽듯이 디자인패턴 책을 읽어라. 하지만 거의 아무도 그 방식으로 유창해지지 못한다. 소프트웨어 개발 프로젝트의 열기 속에서 패턴이 동작하게 하라. 실제 디자인 문제를 직면했을 때 그 패턴들의 통찰을 이용하라. 이것이 GoF 패턴들을 자신의 것으로 만드는 가장 효율적인 방법이다.

어떤 지식을 체화하기 위해선 그 지식으로 살아야 한다는 말을 확인할 수 있습니다. 영어를 배우려면 영어로 살고, DP를 배우려면 DP로 살라는 단순하면서도 아주 강력한 말입니다.

어떤 특정 문장 구조를 학습하는 데 최선은 그 문장 구조를 이용한 실제 문장을 나에게 의미 있는 실제 컨텍스트 속에서 많이 접하고 스스로 나름의 모델을 구축하여 교과서의 법칙에 '기쁨에 찬 동의'를 하는 것입니다.

주변에서 특정 패턴이 구현된 코드를 구하기가 힘들다면 이 패턴을 자신이 만지고 있는 코드에 적용해 보려고 노력해 볼 수 있습니다. 이렇게 해보고 저렇게도 해보고, 그러다가 오히려 복잡도만 증가하면 "아 이 경우에는 이 패턴을 쓰면 안 되겠구나"하는 걸 학습할 수도 있죠. GoF는 패턴을 배울 때는 한결 같이 "이 패턴이 적합한 상황과 동시에 이 패턴이 악용, 오용될 수 있는 상황"을 함께 공부하라고 합니다.

이런 식의 '사례 중심'의 공부를 위해서는 스터디 그룹을 조직하는 것이 좋습니다. 혼자 공부를 하건, 그룹으로 하건 커리프스키(Joshua Kerievsky)의 「A Learning Guide To Design Patterns」(http://www.industriallogic.com/papers/learning.html)를 참고하세요. 그리고 스터디 그룹을 효과적으로 꾸려 나가는 데는 스터디 그룹의 패턴 언어를 서술한 「Knowledge Hydrant」(http://www.industriallogic.com/papers/khdraft.pdf)를 참고하면 많은 도움이 될 겁니다. 이 문서는 뭐든지 간에 그룹 스터디를 한다면 적용할 수 있습니다.

LG2DP(「A Learning Guide To Design Patterns」) 뒷부분에 보면 DP를 공부하는 순서와 각 패턴에서 던질만한 질문이 같이 정리되어 있습니다. DP는 순차적으로 공부해야만 하는 것은 아닙니다. 효과적인 공부의 순서가 있습니다. sorry라는 단어를 모르면서 remorseful이라는 단어를 공부하는 학생을 연상해 보세요. 외국어 공부에서는 자기 몸에 가까운 쉬운 단어부터 공략하는 것이 필수적입니다. 이런 걸 근접 학습(Proximal Learning)이라고도 하죠. 등급별 어휘 목록 같은 게 있으면 좋죠. LG2DP에서 제안하는 순서가 그런 것 중 하나입니다.

랄프 존슨은 이런 순서의 중요성에 관해 다음과 같은 말을 했습니다.

… 하지만 나는 언제나 싱글톤 패턴을 가르치기 전에 콤포짓, 스트래터지, 템플릿 메쏘드, 팩토리 메쏘드 패턴을 가르친다. 이것이 훨씬 더 일반적인 것들이며, 대다수의 사람들은 아마도 이것들 중 마지막 두 가지를 이미 사용하고 있을 것이다.

마이크로패턴
그런데 사실 GoF의 DP에 나온 패턴들보다 더 핵심적인 어휘군이 있습니다. 마이크로패턴이라고도 불리는 것들입니다. DP에도 조금 언급되어 있긴 합니다. 이런 마이크로패턴은 우리가 알게 모르게 매일 사용하는 것들이고 그 활용도가 아주 높습니다. 실제로 써보면 알겠지만, DP의 패턴 하나 쓰는 일이 그리 흔한 게 아닙니다. 마이크로패턴은 켄트 벡의 『Smalltalk Best Practice Patterns』에 잘 나와 있습니다. 영어로 치자면 관사나 조동사 같은 것들입니다.

그리고 이런 마이크로패턴과 함께 리팩토링을 공부하는 게 좋습니다. 리팩토링은 패턴의 필요를 느끼게 해줍니다. 제가 리팩토링 공부에서도 언급했지만 OAOO를 지키면서 리팩토링을 하다보면 자연스레 디자인패턴에 도달하는 경우가 많습니다. 이 때는 지나친 엔지니어링(Overengineering)이 발생하지 않고, 오로지 필요한 만큼만 생깁니다. 이에 관해서는 커리프스키의 「Stop Over-Engineering!」(Software Development Magazine, Apr 2002, http://www.sdmagazine.com/documents/s=7032/sdm0204b/0204b.htm)의 일독을 권합니다. 리팩토링이 디자인패턴을 어떻게 생성해낼 수 있는지 보여주고 있습니다.

1980년대 이후 최근 알렉산더의 향방도 이런 쪽으로 가고 있습니다. 그는 자신이 발표한 기존 패턴들이 너무 크다고 생각해 그런 패턴들을 구성하고, 자동으로 만들어 내며, 또 관통하는 더 작은 원칙들을 발견하는 데 노력해 오고 있습니다. 코플리엔(James Coplien)은 컴퓨터계가 알렉산더의 최근 발전을 쫓아가지 못한다고 늘 이야기합니다.

제대로 된 패턴 구현을 위한 다양한 접근 시도하기
우리의 지식이라는 것은 한 가지 표현양상(representation)으로만 이뤄져 있지 않습니다. 사과라는 대상을 음식으로도, 그림의 대상으로도 이해할 수 있어야 합니다. 실제 패턴이 적용된 '다양한 경우'를 접하도록 하라는 것이 이런 겁니다. 동일 대상에 대한 다양한 접근을 시도하라는 것이죠. 자바로 구현된 코드도 보고, C++로 된 것도 보고, 스몰토크로 된 것도 봐야 합니다. 설령 '오로지 자바족'이라고 할지라도요(전 이런 사람들을 자바리안(Javarian)이라고 부릅니다. 자바와 바바리안(barbarian)을 합성해서 만든 조어지요). 이런 '오로지 하나만 공부하는 것'의 병폐에 대해서는 존 블리스사이즈가 쓴 「Diversify」(http://www.research.ibm.com/people/v/vlis/pubs/gurus-99.pdf)라는 글을 읽어보세요. 이렇게 다양화를 해야 비로소 자바로도 '상황에 맞는' 제대로 된 패턴을 구현할 수 있습니다. 패턴은 그 구현(implementation)보다 의도(intent)가 더 중요하다는 사실을 꼭 잊지 말고, 설명을 위한 방편으로 채용된 한 가지 도식에 자신의 사고를 구속하는 우를 범하지 않기를 빕니다.

이런 맥락에서 저는 DP를 공부할 때 GoF와 동시에 『Design Patterns Smalltalk Companion』을 필수적으로 읽기를 권합니다. 두 권은 말하자면 양날개입니다. 하나는 정적언어로 구현되었고(간간이 스몰토크 구현이 있긴 합니다), 다른 하나는 동적언어로 구현되어 있습니다. 언어와 패턴의 고리를 느슨하게 하고, 패턴을 여러 관점에서 신선하게 볼 수 있는 계기가 될 것입니다. 또, 한 쪽을 보고 이해가 잘 되지 않을 때 다른 쪽을 보면 쉽게 이해됩니다. 서로 상보적인 것이죠.

패턴도 결국 '문제해결'을 위한 한 가지 방편에 지나지 않습니다. 주변에서 "이 경우에는 무조건 이 패턴을 써야 합니다"하고 생떼를 쓰는 사람을 보면 씁쓸한 기분을 감출 수 없습니다.

디자인패턴 추천서
디자인패턴 책 중에 중요한 서적을 몇 권 소개하겠습니다.

◆『Design Patterns Explained』(Shalloway, Trott): 최근 DP 입문서로 급부상하고 있는 명저
◆『Design Patterns Java Workbook』(Steven John Metsker): DPE 다음으로 볼만한 책으로 쏟아져 나오는 시중의 조악한 자바 패턴 책들과는 엄연히 다르다. 워크북 형식을 채용해서 연습문제를 풀고 뒷부분의 답과 대조해 볼 수 있는 등 독학자가 공부하기에 좋다.
◆『Refactoring』(Martin Fowler): DP 공부 이전에 봐서 문제의식 형성하기(망치를 들면 모든 것이 못으로 보이는 오류 탈피)
◆『Design Patterns』: 바이블.
◆『Design Patterns Smalltalk Companion』: GoF가 오른쪽 날개라면 DPSC는 왼쪽 날개
◆『Pattern Hatching』(John Vlissides): DP 심화학습. 얇지만 밀도 높은 책.
◆『Smalltalk Best Practice Patterns』(Kent Beck): 마이크로 패턴. 개발자의 탈무드. 감동의 연속.
◆『Pattern Languages of Program Design』 1,2,3,4: 패턴 컨퍼런스 논문 모음집으로 대부분은 인터넷에서 구할 수 있음
◆『Pattern-Oriented Software Architecture』 1,2: 아키텍처 패턴 모음. 2권은 네트워크 애플리케이션의 아키텍처 모음.
◆『Concurrent Programming in Java』(Doug Lea): 컨커런트 프로그래밍에 대한 최고의 서적.
◆『Patterns of Software』(Richard Gabriel): 패턴에 관한 중요한 에세이 모음.
◆『Analysis Patterns』(Martin Fowler): 비즈니스 분석 패턴 목록. 비즈니스 애플리케이션 개발자에게 많은 도움이 됨.
◆『A Timeless Way of Building』(Christopher Alexander): 프로그래머들이 가장 많이 본 건축 서적. 패턴의 철학적·이론적 배경. '구약'('신약'은 올해 안에 출간 예정인 동저자의 『The Nature of Order』).
◆『A Pattern Language』(Christopher Alexander): 알렉산더의 건축 패턴 모음집.
◆『Problem Frames』(Michael Jackson): DP의 해결(solution) 지향식의 문제점과 극복 방안으로서의 문제 지향식 방법. 마이클 잭슨은 요구 사항 분석 쪽에서 동명의 가수만큼이나 유명.

DP를 처음 공부한다면, DPE와 DPJW를 RF와 함께 보면서 앞서의 두 권을 RF적으로 독해해 나가기를 권합니다(하버드 대학의 뚜웨이밍 교수는 요즘 칸트를 유교적으로 독해하고 있다고 합니다. 하나의 책을 다른 각도에서 독해하는 것, 여기서 배우는 것이 많습니다). 이게 된 후에는 GoF와 DPSC를 함께 볼 수 있습니다. 양자는 상호 보완적인 면이 강합니다. 이쯤 되어 SBPP를 보면 상당히 충격을 받을 수 있습니다. 스스로가 생각하기에 코딩 경험이 많다면 다른 DP 책 이전에 SBPP를 먼저 봐도 좋습니다.

이 정도의 책을 봤다면 POSA와 PLOPD 등에서 자신이 관심이 가는 패턴들을 찾아 읽는 것이 좋습니다. 그리고 동시에 알렉산더의 원저들을 꼭 읽기를 권합니다. 가브리엘의 책이 알렉산더의 사상 이해에 많은 도움이 될 것입니다.

패턴 공부를 해나가면서 남을 가르치는 것이 공부에 많은 도움이 됩니다(사실 자바 패턴 책 중에 어떤 것은 "내가 패턴을 처음 공부하면서 같이 쓴 것이다"라고 저자가 고백한 것도 있습니다). 보이스카웃에서는 보통 다음 과정을 통해 뭔가를 '학습'하게 한다고 합니다. 처음은 어떻게 하는지를 보여주고, 다음은 스스로 그것을 해보게 하고, 다음으로 그걸 남에게 가르치게 합니다. 이 때 중요한 것은 상대가 이해하지 못 하면 그 이유를 자기 자신에게서 찾는 것이 나에게 더 이득이 된다는 것입니다. "내가 설명을 잘못 했군"하고 생각하는 것이죠. 그러면 다음번에는 설명을 좀더 잘 할 수 있게 되고, 동시에 자기의 이해도 더욱 명료해지게 됩니다. 저는 'OOP 개념을 한 시간 만에 가르치기'나 '특정 언어 문법을 한 시간 만에 가르치기' 등을 하나의 도전으로 생각하고 즐깁니다. 가르치면서 동시에 배운다는 것은 정말 놀라운 경험입니다.

익스트림 프로그래밍 학습에서의 문제
앞의 경우와 비슷합니다. 익스트림 프로그래밍을 공부하는 사람들은 실제로 행해보지 않고 책만 들여다보면 안 됩니다. 그렇다고 책이 중요하지 않다는 말은 아닙니다. 하지만 자전거 타기는 자기 몸으로 직접 굴려봐야 합니다.

게다가 켄트 벡 스스로가 『XP Explained』를 만약 다시 쓴다면 뜯어고치고 싶은 부분이 상당히 된다고 말하는 것을 봐도 알 수 있듯이 초기 XP 이후 바뀌고 보완된 점이 상당수 있습니다. 따라서 책만으로 XP를 공부하기는 힘듭니다. 지금은 책 속의 XP가 사람들의 머리 속 XP에 한참 뒤쳐져 있습니다.

어찌 되었든 XP에는 무술이나 춤, 혹은 악기 연주 등과 유사한 면이 많습니다. 따라서 글을 보고 그것을 익히기는 쉽지 않습니다. 그나마 메일링 리스트 같은 '대화'를 보면 훨씬 더 많은 것을 얻을 수 있기는 하지만, 태권도 정권 찌르기를 말로 설명하는 것이 불가능에 가깝듯이 XP를 언어를 통해 익히기는 정말 어렵습니다. 우리의 언어는 너무도 성글은 미디어입니다(XP는 매 초, 매 순간 벌어지는 '일상적' 장면의 연속이 매우 중요합니다).

익스트림 프로그래밍 공부
XP를 이해하려면 다음 기본 자료에 대한 이해가 우선해야 합니다(본지 2001년 12월호 「허실문답 XP 강화」 참조).

◆『XP Explained』(Kent Beck): XP 선언서
◆『XP Installed』(Ron Jeffries et al): C3 프로젝트에 적용한 예, 얻은 교훈 등
◆『Planning XP』(Kent Beck, Martin Fowler): 계획 부분 설명(관리자, 코치용)
◆『Refactoring』(Martin Fowler): 리팩토링에 대한 최고의 책
◆『XP Applied』: 유즈넷과 메일링 리스트의 논의 등 최근 자료를 반영
◆『XP Explored』: 가장 쉽고 구체적인 XP 안내서


이 중에서 XPI나 XPX를 먼저 권합니다. XPE는 좀 추상적인 서술이 많아서 봐도 느낌이 별로 없을 수 있습니다(2001년 본지 11월호에 제가 쓴 리뷰 참고). 여유가 되면 다음 자료를 더 참고합니다.

◆『The Timeless Way of Building』: 패턴 운동을 일으킨 알렉산더의 저작. 현장 고객(On-site Customer), 점진 성장(Piecemeal Growth), 소통(Communication) 등의 아이디어가 여기에서 왔음.
◆『XP in Practice』(Robert C. Martin 외): 두세 사람이 짧은 기간 동안 간단한 프로젝트를 XP로 진행한 것을 기록. 자바 사용(중요한 문헌은 아님).
◆『XP Examined』: XP 컨퍼런스에 발표된 논문 모음
◆『Peopleware』(Tom DeMarco): 개발에 있어 인간 중심적 시각의 고전
◆『Adaptive Software Development』(Jim Highsmith): 복잡계 이론을 개발에 적용. 졸트상 수상.
◆『Surviving Object-Oriented Projects』(Alistair Cockburn): 얇고 포괄적인 OO 프로젝트 가이드라인
◆『Software Project Survival Guide』(Steve McConnell): 조금 더 전통적인 SE 시각.
◆『The Psychology of Computer Programming』(Gerald M. Weinberg): 프로그래밍에 심리학을 적용한 고전. 코드 공유와 짝 프로그래밍에 필수인 비자아적 프로그래밍(Egoless Programming)이 여기서 나왔다.
◆『Agile Software Development』(Alistair Cockburn): 전반적 애자일 방법론에 대한 개론서
◆『Software Craftsmanship』(Pete McBreen): 장인으로서의 새로운 프로그래머 상
◆『Agile Software Development with SCRUM』(Schwaber Ken): 최근 확장성(Scalability)을 위해 XP+SCRUM의 시도가 애자일 쪽의 큰 화두임.
◆『A Practical Guide to eXtreme Programming』(David Astels 외): 저자들이 직접 참여한 프로젝트를 따라가 보면서 배움. 자바로 구현. XPP보다는 스케일이 큼.
◆『Agile Modeling』(Scott Ambler): 애자일 쪽에서 모델링이 무시되는 느낌이 있을 수 있는데, 그쪽으로 깊게 천착한 사람이 앰블러임.
◆『Agile Software Development Ecosystems』(Jim Highsmith): 각각의 애자일 방법론에 대한 소개와 동시에 각 방법론의 대표자들 인터뷰가 백미.
◆『Test Driven Development』(Kent Beck): 곧(아마 올해 내에) 출간 예정인 최초의 TDD 서적. TDD를 모르면 XP도 모르는 것(TDD를 실제 적용하려면 적어도 반년 정도는 계속 훈련해야 함)
◆IEEE Software/Computer, CACM, Software Development Magazine 등에 실린 기사
◆『XP Conference, XP Universe 등의 논문들(특히 최근 것들)
◆유즈넷, 메일링 리스트, 오리지널 위키(http://c2.com)의 논의들

특히 유즈넷, 메일링 리스트, 오리지널 위키는 늘 가까이 하고 있어야 합니다. 이 세 곳을 살필 때, 특히 다음 사람들의 글은 꼭 읽어보고 항상 레이더를 열어두면 좋습니다(이 외에도 개발 경력 10년, 20년이 넘는 짱짱한 사람이 많으므로 눈 여겨 관찰하세요. 모든 글을 읽는 것은 무리이므로 그들의 대화를 일차적으로 읽어야 합니다).

켄트 벡, 론 제프리즈(Ron Jeffries), 워드 커닝엄(Ward Cunningham), 앨리스테어 코번(Alistair Cockburn), 마틴 파울러, 로버트 마틴 혹은 엉클 밥(Robert C. Martin aka Uncle Bob), 마이클 페더즈(Michael Feathers), 켄 아우어(Ken Auer), 윌리엄 웨이크(William Wake), 로이 밀러(Roy Miller), 데이브 토마스(Dave Thomas), 앤디 헌트(Andy Hunt), 랄프 존슨, 스카트 앰블러(Scott Ambler), 짐 하이스미스(Jim Highsmith), 조슈아 커리프스키(Joshua Kerievsky), 로렌트 보사빗(Laurent Bossavit), 존 브루어(John Brewer) 등

이런 자료들 외에, 기회가 된다면 주변에서 XP를 직접 사용하는 곳을 방문해서 하루만 같이 생활해 보기를 권합니다. 반년 공부를 앞당길 수 있습니다. 제가 공부할 때는 주변에 XP를 아는 사람이 없어서 혼자 공부했는데, 그것에 비해 XP를 직접 사용하는 상황에 처한 사람은 (제가 억울하리만큼) 더 적은 노력으로 몇 배 이상 빨리 몸에 익히는 것 같았습니다.

이게 힘들면 같이 공부하는 방법이 있습니다(앞서 언급된 스터디 그룹에 관한 패턴 참고). 이 때 같이 책을 공부하거나 하는 것은 시간 낭비가 많습니다. 차라리 공부는 미리 다 해오고 만나서 토론을 하거나 아니면 직접 실험을 해보는 것이 훨씬 좋습니다. 두 사람 당 한 대의 컴퓨터와 커대란 화이트보드를 옆에 두고 말이죠. 제 경우 스터디 팀과 함께 저녁 시간마다 가상 XP 프로젝트를 많이 진행했고, 짤막짤막하게 프로그래밍 세션도 많이 가졌습니다. 나중에 회사에서 직접 XP를 사용할 때 많은 도움이 되었습니다.

Refactor Me
제가 하고 싶은 말은 더 있지만 이 글은 일단 여기서 끝이 납니다. 서두에서 말씀드렸듯이 애초 쓰려던 '일반론'은 생략하고, 대신 독자들의 몫으로 남겨두려 합니다. 이 글 자체가 여러분의 리팩토링 수련의 연장(延長)이 되었으면 하는 바램입니다. 이 글과 함께 실생활에서 직접 실험을 해보면서 - 이 때 욕심 부리지 않고 한 가지씩 지긋이 해보는 느긋함과 음미의 정신이 필요할지도 모르겠습니다 - 자신의 경험을 축적해 나가고, 동시에 이 글을 적절히 리팩토링해서 자신만의 패턴을 차근히 만들어 나가길 바랍니다. 그렇습니다. 리팩토링은 대상에 대한 이해가 깊고 경험이 많을수록 더 잘할 수 있습니다.

이 글에 소개된 제 공부론은 어찌 보면 상당히 진부해 보이기도 할 것입니다. 하지만 저는 이런 상식적이고 일상적이며 심지어는 소소해 보이는 것들에서 많은 감동을 받아왔습니다. 이 글도 사실 제 감동의 개인사입니다. 저는 "만약 오늘 어떤 것에라도 감동한 것이 없었다면, 오늘은 뭔가 잘못 산 것이다"라는 신조를 갖고 있습니다. 그것이 컴퓨터이건 대화이건 상관없이 말이죠. 저는 날마다 감동하며 살려고 노력합니다. 그러나 이 감동에 뭔가 꼭 대단한 것이 필요한 것은 아닙니다. 저는 오히려 감동 받기 위해 스스로 대단해져야 할 필요를 느끼기도 합니다. '감동'이라는 것은 주어지는 것이 아닙니다. 나와 타자가 공조하여 만드는 대화입니다.

감동해야 체득할 수 있다고 생각합니다. 그리고 이 감동은 개인적 삶 속에서 자기가, 자신의 몸으로, 직접 얻는 것입니다. 工夫 열심히 합시다.
반응형

'Information' 카테고리의 다른 글

프로그래밍은 예술이다?  (0) 2007.03.03
각종 확장자 파일 모음  (0) 2007.03.03
자바스크립트 강좌, 사용법, 객체, 이벤트 등  (0) 2007.03.03
A
01. adf : 어댑터 서술 파일
02. afm : 어도비 폰트 매트릭스 파일
03. ais : 압축 유틸ain을 사용해 만든 파일
04. ani : 애니메이션 커서의 모양을 움직이는 파일
05. aif : 매킨토시에서 소리를 녹음하거나 들을 때 사용하는 파일
06. and : 스프레드시트 프로그램중 하나인 로터스 1-2-3 추가기능을 제공하는 유틸리티 파일
07. ann : 주석파일로 삭제해도 된다
08. ans : 텍스트 파일의 일종
09. asp : MS웹 서버에서 사용하는 홈페이지 파일
10. asm : 어셈블리 언어의 소스를 담은 파일
11. asc : 아스키 텍스트 파일
12. arj : 압축 유틸리티 ARJ 로 압축한 파일
13. asv : 일정시간마다 자동 저장되는 파일
14. avi : MS에서 만든 동영상 파일로, 압축률이 낮다


B
01. bak : 새로운 파일이 생성되면 이전 파일을 보관하기위해 만들어지는 백업파일
02. bas : 베이직 언어의 소스파일
03. bat : 도스파일로, 여러 프로그램을 한꺼번에 실행할 때 사용된다
04. bgi : 볼랜드 그래픽 인터페이스 파일
05. bin : 실행파일의 보조파일
06. bk! : 백업파일
07. bmp : 기본적인 그래픽파일, 압축이 전혀 안됨
08. bnk : 악기에 대한 정보가 저장되어 있는 뱅크파일
09. btm : 4dos용 배치파일


C
01. cab : MS에서 프로그램을 공급할 때 사용하는 압축파일
02. cap : 통신프로그램에서 갈무리할 때 주로 사용
03. cat : 카탈로그 파일
04. cbl : 코볼의 소스 파일
05. cch : 코렐 드로용 차트 데이터 파일
06. cda : 윈도우에서 음악 한곡을 표현할 수 있는 파일
07. cdr : 코렐 드로용 그래픽 파일
08. cdt : 코렐 드로용 서식 파일
09. cfg : 환경설정을 하는데 이용하는 파일
10. cgm : 컴퓨터 그래픽 메타파일
11. chk : 도스의 디스크검사에서 chkdsk를 실행했을 때 결과로 만들어지는 파일
12. clp : 윈도의 클립보드에 저장된 내용을 파일로 만들 때 사용하는 파일
13. cmd : 실행프로그램의 보조 프로그램 파일
14. cmx : 코렐 드로용 그래픽 파일
15. cnf : 환경설정을 하는데 이용하는 파일
16. cnt : 목차내용을 담고 있는 파일
17. cod : 코볼의 소스파일
18. com : 실행파일의 한가지로 exe보다 메모리가 적고 속도가 빠르지만 크기가 64Kb미만이다
19. cpe : 팩스의 표지같은 문서 표지 파일
20. cpi : 국가코드 페이지 정보파일
21. cpl : 제어판에 실행파일형식으로 저장되어 있는 아이콘파일
22. cpp : c++위 소스코드 파일
23. cps : 바이러스 백신프로그램
24. crd : 카드 데이터 파일
25. cut : 도스에서 사용하던 그래픽 프로그램의 파일
26. cur : 마우스 커서 파일


D
01. dat : 실행프로그램이나 비디오 씨디에서 사용하는 데이터 파일
02. db : 데이터 베이스 파일
03. dbf : db의 기능을 확장한 파일형식
04. dct : 사전파일
05. dde : 동적 데이터 교환파일
06. ddi : 디스크 이미지 파일
07. def : 특정 내용을 보관해 두는 정의 파일
08. dem: 데모 파일
09. des : 설명 파일
10. dhp : 닥터할로의 그림 파일
11. dib : 비트맵 파일
12. dic : 워드프로세서에서 사용하는 사전 파일
13. dir : Mdir용 디렉토리 정보 파일
14. diz : 애로사항 해결을 위한 소개 및 제작사 설명 파일
15. dll : 여러프로그램에서 공통적으로 사용하는 기능을 모아놓은 파일
16. doc : MS워드 및 윈도우의 워드패드에서 사용하는 파일
17. dot : MS워드의 서식 파일
18. drv : 하드웨어를 제어하는 디바이스 파일
19. drw : 마이크로그래픽스 디자이너의 그래픽 파일
20. dta : 각종 데이터를 저장하는 파일
21. dvrl : 주변장치 드라이버 파일
22. dwg : 오토캐드의 설계 밑그림 파일


E
01. eml : 전자우편 파일
02. enc : 인코딩된 파일
03. eng : 영문 글꼴 파일
04. eps : 포스트스크립트 그래픽 파일
05. exe : 기본적인 실행파일
06. exp : 오토캐드용 드라이버 파일


F
01. fax : 팩스 파일
02. flc : 애니메이션에서 사용되는 동영상 파일
03. fli : 동영상 파일
04. flt : 필터 파일
05. fon : 기본 글꼴
06. for : 포트란의 소스 파일
07. fot : 트루타입 폰트 스타일 파일
08. frm : 한글파일


G
01. gal : 이야기에서 사용하는 파일
02. gif : 애니메이션이나 웹사이트에서 아이콘을 만들 때 사용되는 파일
03. gly: 요약한 내용을 담고 있는 파일
04. grf : 그래픽 파일
05. gz : 공개소프트웨어를 만드는 압축파일


H
01. hdr : 한그림용 데이터 파일
02. hft : 한글에서 사용하는 글꼴 파일
03. hgx: 매킨토시 압축 포맷
04. hlp : 프로그램의 도움말 파일
05. hst : 히스토리 파일
06. htf : 한글에서 사용하는 글꼴 파일
07. htm : 홈페이지 만드는 텍스트파일
08. html : 홈페이지 만드는 텍스트파일
09. hwp : 한글에서 저장한 문서 파일
10. hwt : 한글의 문서마당 파일


I
01. icn : 윈도아이콘 파일
02. ico : 윈도아이콘 파일
03. idx: 데이터베이스 인덱스 파일
04. iff : 아미가 그래픽 파일
05. img : 디스크 이미지의 그래픽 파일
06. ims : 음악 데이터 파일
07. ind : 데이터베이스 인덱스 파일
08. inf : 설치에 대한 정보를 담고 있는 파일
09. ini : 각종 설정 값을 저장한 파일


J
01. jas : JAS로 압축된 그래픽 파일
02. jpg : GIF의 단점을 개선한 그래픽 파일


K
01. key : 키보드 정의 파일
02. kor : 한글 글꼴 파일
03. ksr : 이야기의 디렉터리 정보 파일


L
01. lbm : 도스용 파일
02. lbr : 라이브러리 파일
03. leml : MS의 인터넷 메일에서 지정한 파일
04. lib : 라이브러리 파일
05. lnk : 단축아이콘 파일
06. lnws : 인터넷 뉴스에서 저장한 파일
07. log : 프로그램 실행결과를 저장한 파일
08. lst : 목록 파일
09. lurl : 단축아이콘의 일종
10. lzh : 압축 파일


M
01. mac : 매킨토시 그래픽 파일
02. man : 사용설명서 파일
03. mda : MS의 액세스 기능추가 파일
04. mdb : MS의 액세스의 데이터베이스 저장 파일
05. mdf : 메뉴정의 파일
06. mdn : MS의 액세스의 서식 파일
07. mdz : MS의 액세스 마법사 파일
08. me : 프로그램 안내 파일
09. men : 메뉴 파일
10. met : 윈도 메타 파일
11. mid : 미디용 음악 파일
12. mif : 관리정보 파일
13. mnu : 메뉴 파일
14. mod : 음악파일
15. mov : 애플에서의 동영상 파일
16. mpg(mpeg) : 압축률이 높은 동영상
17. mp3 : wav의 개선 압축 음악 파일
18. ms : 그래픽 파일
19. msg : 메시지 파일
20. msp : 그래픽 파일


N
01. new : 프로그램에 새로 추가된 파일
02. ncf : 명령어 파일
03. ndx : 데이터베이스의 인덱스 파일
04. ncd : 디렉터리 정보 파일


O
01. ori : 원본 파일
02. opt : 옵션 파일
03. old : 이전 버전의 백업 파일
04. ocx : 라이브러리 파일
05. obd : 여러 가지 파일을 묶는 바인더 파일
06. ovr : 오버레이 파일
07. ovl : 오버레이 파일
08. out : 외곽선 정보를 가진 파일


P
01. pho : 전화번호 목록 파일
02. pgp : 오토캐드의 인자정보 파일
03. pfm : 프린터 글꼴 매트릭스 파일
04. pfb : 프린터 글꼴 바이너리 파일
05. pdx : 데이터 파일
06. pdr : 한글용 프린터 드라이버 파일
07. pdf: 어도비에서의 문서 파일
08. pcx : 페인트브러쉬의 그래픽 파일
09. pcd : cd포맷에 알맞은 파일
10. pat : 프로그램 패치 파일
11. pas : 파스칼 소스 파일
12. pal : 색상정보 파일
13. pak : 유닉스용 압축 파일
14. pic : 페인트 브러쉬 파일
15. pif : 프로그램 정보 파일
16. pll : 사전링크 라이브러리 파일
17. pm5 : 페이지 메이커 5의 문서 파일
18. png : jpg처럼 압축률은 높인 그래픽 파일
19. ppd : 포스트스크립트 프린터 서술 파일
20. ppt : 파워포인트 데이터 파일
21. prd : 프린터 드라이버 파일
22. prf : 등록정보 담은 파일
23. prg : 프로그램 파일
24. prj : 프로젝트 파일
25. pro : 프로파일 파일
26. ps : 어도비에서 만든 이미지 글꼴 파일
27. psd : 포토샵의 데이터 파일
28. psz : 유닉스에서 사용하던 압축 파일
29. pub : 탁상출판 그래픽 파일


Q
01. qxd : 문서 파일


R
01. ra : 리얼오디오 파일
02. ram : 리얼오디오 파일
03. rar : 압축 윈라르의 압축 파일
04. ras : 이미지 그래픽 파일
05. rec : 리코더 파일
06. ref : 프로그램의 참조 파일
07. reg : 레지스트리의 데이터를 저장할 때 사용하는 파일
08. res : 프로그램의 리소스 파일
09. rol : 음악 파일
10. rtf : 문서 파일


S
01. sc : 통신프로그램의 스크립트 파일
02. sav : 백업 파일
03. scf : 통신프로그램의 스크립트 파일
04. scr : 화면보호기 파일
05. sdf : 표준 데이터 파일
06. s3m : 음악 파일
07. sys : 시스템 운영 파일
08. sdr : 한글용 화면 드라이버 파일
09. sea : 자동압축 풀림 파일
10. set : 환경 설정 파일
11. smp : 견본 파일
12. snd : 일반적인 소리 파일
13. src : 소스 파일
14. spl : 철자 정보 파일
15. srp : 스크립트 파일
16. sts : 시스템 점검 결과보고 파일
17. sty : 한글 스타일 정보 파일
18. swp : 임시 스왑 파일
19. sym : 심볼 파일


T
01. tar : 여러파일을 묶은 파일
02. tbk : 멀티미디어 저작 데이터 파일
03. tga : 그래픽 파일
04. tgz : 압축 파일
05. tif : jpg같은 압축률이 좋은 그래픽 파일
06. tiff : 그래픽 파일
07. tmp : 윈도우 정상 실행될 때 임시 생성 파일
08. trm : 하이퍼터미널 정보 파일
09. tst : 테스트 결과 정보 저장 파일
10. ttf : 윈도우용 트루타입 폰트 파일
11. txt : 기본 문서 파일


U
01. upt : 프로그램의 업그레이드 정보 담은 설명서 파일
02. uue : 인코딩된 파일


V
01. vbx : 비쥬얼 베이직 파일
02. voc : 음성 소리 저장 파일
03. vxd : 가상 디바이스 드라이버


W
01. vbx : 비쥬얼 베이직 파일
02. voc : 음성 소리 저장 파일
03. vxd : 가상 디바이스 드라이버


X
01. xlm : 엑셀 파일
02. xll : 엑셀 파일
03. xlk : 엑셀 백업 파일
04. xld : 엑셀 파일
05. xlc : 엑셀 차트 파일
06. xlb : 엑셀 파일
07. xla : 엑셀 파일
08. xbm : 윈도우 흑백 비트맵 그래픽 파일
09. xls : 엑셀 저장 파일
10. xlt : 엑셀 서식 파일
11. xlv : 엑셀 파일
12. xlw : 엑셀 파일
13. xpm : 윈도우 컬러 그래픽 파일


Z
01. zip : 압축 파일
02. zool : 압축 파일


Etc.
01. $$$ : 임시생성 파일
02. 000 : 4도스에서 만드는 임시 스왑 파일
03. 386 : 윈도우 386 확장모드 드라이버 파일
04. 1st : 프로그램 사용설명서가 들어 있는 파일
05. 3ds : 3D그래픽 프로그램의 편집용 밑그림 데이터 파일
06. 8b* : 어도비 데이터 파일
반응형
  • HTML에 JavaScript 삽입
    <script language="javascript">
    JavaScript Statements
    </script>


  • HTML에 JavaScript 코드 파일 삽입
    <script language="javascipt" src="src.js">
    </script>


  • 변수의 대소문자 구분

  • 변수에 포함된 데이터의 형을 지정하지 않고, JavaScript 인터프리터가 변수에 포함된 데이터 형을 추적하고 변환.

  • JavaScript 데이터 형
    • 숫 자 형 : 정수와 부동 소수
    • BOOLEAN : true, false
    • STRING : 작은 따옴표나 큰 따옴표에 들어가 있는 값으로, 특수문자 포맷 사용시에는 '\'와 함께 사용.
    • null : 아무런 값도 없는 것으로, 변수를 초기화 시키거나 어떤 값이나 이벤트를 지울 때 사용됨
    • undefined : 변수만 만들고, 값을 할당하지 않은 상태

  • 유형간의 변환
    • 스트링 피연산자가 비스트링 연산자와 사용된 경우 다른 연산자를 모두 스트링으로 변환
    • BOOLEAN값은 1과 0으로 변환되어 수치 연산을 지원
    • null값은 스트링 연산에 대해서는 "null", 논리 연산에서는 false, 그리고 수치 연산에서는 0으로 각각 변환
    • 변환 함수
      • eval() : 스트링 표현식을 수치값으로 변환하고, 파라미터가 수치형태가 아닌 스트링 값이면 에러 발생
      • parseInt() : 스트링에 포함된 첫번째 정수를 리턴하고, 스트링이 정수로 시작되지 않으면 0을 리턴
      • parseFloat() : 스트링에 포함된 첫번째 부동 소수를 리턴하거나 스트링이 적절한 부동 소수로 시작되지 않으면 0을 리턴

  • 배열 : 값의 시퀀스를 정렬할 수 있는 객체로, JavaScript의 특수형으로 배열 사용 전엔 반드시 선언해야 한다.
    • 배열 선언 예
      arrayName = new Array(arrayLength)
      arrayName = new Array()
      arrayName = new Array(value0,value1, ..., valuen)

  • JavaScript만의 특수 연산자
    • comma(,) 연산자 : 두 표현식을 계산하고, 두 번째 표현식의 값 리턴
    • delete 연산자 : 객체의 프로퍼티나 배열 인덱스의 요소 삭제하고, 항상 undefined 값 리턴
    • new 연산자 : 객체 형의 인스턴스를 만들기 위해 사용
    • typeof 연산자 : 연산자의 형을 식별하는 스트링 값을 리턴
    • void 연산자 : 값을 리턴하지 않는다

  • 지역 변수와 전역 변수 : 함수 안에서만 사용되는 것을 지역 변수라 하고, 프로그램 내에서 사용되는 변수를 전역 변수라 하는 데, 지역 변수 사용시 반드시 var 키워드와 함께 선언해야 함

이벤트 처리!!

  • 이벤트 정의와 사용
    • 이벤트 : 사용자가 웹페이지나 기타 다른 브라우저에 수행한 작업으로 인한 결과
    • 이벤트 처리 : 이벤트로 인해 수행되는 프로세스
    • 이벤트 핸들러 : 프로세스를 수행하는 코드
    • 사용 예 : 사용자가 링크 위로 마우스를 갖다 대면 다이얼로그 박스를 표시한다거나, 폼에 입력한 데이터를 검증한다거나, 버튼을 클릭할 때 애니메이션을 나타내거나, Java 애플릿과 브라우저 플러그인이 상호작용을 하도록 한다.

  • JavaScript가 정의한 이벤트
    HTML 태그 JavaScript 이벤트 설명
    다양 mouseMove 마우스 이동
    <A>..</A> Click 마우스로 링크를 클릭
    dbClick 마우스를 링크위에서 더블클릭
    mouseDown 마우스 버튼을 누름
    mouseUp 마우스 버튼을 놓음
    mouseOver 마우스를 링크위로 이동
    mouseOut 링크 위에 있던 마우스를 링크 밖으로 이동
    keyDown 사용자가 키를 누름
    keyUp 사용자가 키를 놓음
    keyPress 사용자가 키를 눌렀다가 놓음
    <IMG> abort 사용자 액션으로 인해 이미지 로딩 작업을 중단함
    error 이미지 로딩하는 동안 에러 발생
    load 이미지가 로드되고 화면에 나타남
    keyDown 사용자가 키를 누름
    keyUp 사용자가 키를 놓음
    keyPress 사용자가 키를 눌렀다가 놓음
    <AREA> mouseOver 마우스가 클라이언트측 이미지맵의 한 영역으로 이동함
    mouseOut 마우스가 이미지맵 영역 밖으로 이동
    dbClick 사용자가 이미지맵의 한 영역을 더블클릭함
    <BODY>..</BODY> Click 사용자가 문서의 본문을 클릭
    dbClick 문서의 본문을 더블 클릭함
    keyDown 키를 누름
    keyUp 키를 놓음
    keyPress 키를 눌렀다가 놓음
    mouseDown 마우스 버튼을 누름
    mouseUp 마우스 버튼을 놓음
    <BODY>..</BODY>
    <FRAMESET>..</FRAMESET>
    <FRAME>..</FRAME>
    blur 윈도우에서 현재 입력 포커스가 사라짐
    error 윈도우가 로드되는 동안 에러 발생
    focus 입력 포커스가 현재 윈도우로 이동
    load 윈도우 로딩이 완료됨
    unload 윈도우를 종료함
    move 윈도우가 이동됨
    resize 윈도우의 크기가 바뀜
    dragDrop 윈도우에 객체를 드롭
    <FORM>..</FORM> submit 사용자가 폼을 제출
    reset 사용자가 폼을 재설정
    <INPUT TYPE="text"> blur 현재 입력 포커스가 텍스트 필드에서 사라짐
    focus 현재 입력 포커스가 텍스트 필드로 이동
    change 텍스트 필드가 변경되어 현재 입력 포커스가 사라짐
    select 텍스트 필드에 있는 텍스트가 선택됨
    <INPUT TYPE="password"> blur 패스워드 필드에서 입력 포커스가 사라짐
    focus 패스워드 필드에 입력 포커스 생김
    <TEXTAREA>..</TEXTAREA> blur 텍스트 영역이 현재 입력 포커스가 사람짐
    focus 텍스트 영역에 입력 포커스 생김
    change 텍스트 영역이 변경되어 입력 포커스가 사라짐
    select 텍스트 영역에서 텍스트가 선택됨
    keyDown 키를 누름
    keyUp 키를 놓음
    keyPress 키를 눌렀다 놓음
    <INPUT TYPE="button"> Click 버튼이 클릭됨
    blur 입력할 수 없도록 버튼이 흐려짐
    focus 입력할 수 있도록 포커스 생김
    mouseDown 버튼 위에서 왼쪽 마우스 버튼 누름
    mouseUp 버튼 위에서 왼쪽 마우스 버튼 놓음
    <INPUT TYPE="submit"> Click 제출 버튼이 클릭됨
    blur 제출 버튼에서 입력 포커스가 사라짐
    focus 제출 버튼에 입력 포커스 생김
    <INPUT TYPE="reset"> Click 리셋 버튼이 클릭됨
    blur 리셋 버튼에서 포커스가 사라짐
    focus 리셋 버튼에서 포터스가 놓임
    <INPUT TYPE="radio"> Click 라디오 버튼이 클릭
    blur 라디오 버튼에서 입력 포커스가 사라짐
    focus 라디오 버튼에 입력 포커스 생김
    <INPUT TYPE="checkbox"> Click 체크 박스가 클릭
    blur 체크 박스에서 입력 포커스가 사라짐
    focus 체크 박스에 입력 포커스 놓임
    <INPUT TYPE="file"> blur 파일 업로드 폼 요소에서 입력 포커스 사라짐
    change 사용자가 업로드될 파일을 선택
    focus 파일 업로드 폼 요소에 입력 포커스 놓임
    <SELECT>..</SELECT> blur 선택 요소가 현재 입력 포커스 잃음
    change 선택 요소가 변경되어 입력 포커스가 사라짐
    focus 선택 요소에 현재 입력 포커스가 놓임

  • 이벤트 처리 속성
    이벤트핸들링속성 실행되는 상황
    onAbort 이미지를 로딩하는 작업이 사용자의 한 행동으로 인해 취소되었음
    onBlur 문서나 윈도우, 프레임세트, 폼 요소에서 현재 입력 포커스가 사라짐
    onChange 텍스트 필드나 텍스트 영역, 파일 업로드 필드, 선택 항목이 변경되어 현재 입력 포커스가 사라짐
    onClick 링크나 클라이언트측 이미지맵 영역, 폼 요소가 클릭됨
    onDbClick 링크나 클라이언트측 이미지맵 영역, 문서가 더블 클릭됨
    onDragDrop 드래그된 객체가 윈도우나 프레임에 드롭됨
    onError 이미지나 윈도우, 프레임을 로딩하는 동안 에러가 발생함
    onFocus 문서나 윈도우, 프레임 세트, 폼 요소에 입력 포커스 놓임
    onKeyDown 키를 누름
    onKeyPress 키를 눌렀다 놓음
    onKeyUp 키를 놓음
    onLoad 이미지나 문서, 프레임이 로드됨
    onMouseDown 마우스 버튼 누름
    onMouseMove 마우스를 이동함
    onMouseOut 링크나 클라이언트측 이미지맵에서 마우스를 옮김
    onMouseOver 마우스를 링크나 클라이언트측 이미지맵으로 옮김
    onMouseUp 마우스 버튼을 놓음
    onMove 사용자가 윈도우나 프레임을 이동함
    onReset 폼의 리셋 버튼을 클릭하여 폼을 리셋시킴
    onResize 사용자가 윈도우나 프레임의 크기를 조절
    onSelect 텍스트는 텍스트 필드나 영역에서 선택됨
    onSubmit 폼이 제출됨
    onUnload 사용자가 문서나 프레임 세트를 종료함


 


객체 정의하기

  • 객체 유형 정의
    • 프로퍼티 : 객체에 들어 있는 데이터 값에 액세스할 때 사용.
    • 메소드 : 객체에 어떤 작업을 할 때 사용하는 함수.
  • 객체 유형 만들기
    사용자가 직접 객체 유형을 정의하고 특정 객체 인스턴스를 만들 수 있 는데 이렇게 만들려면 객체 유형의 특정 인스턴스를 만들 때 사용되는 함수를 정의하기만 하면 된다. 본래 이러한 생성자 함수는 다음과 같은 일을 한다.
    • 객체 유형의 프로퍼티에 값을 할당한다.
    • 객체 유형의 메소드로 사용할 수 있는 다른 함수를 지정한다.
  • 객체 사용 예
    1. table 객체의 정의 (table.js)
      function table_getValue(row,col){
        return this.data[row* this.columns+col ];
      }
      function table_setValue(row,col,value){
        this.data[row* this.columns+col ]=value;
      }
      function table_set(contents){
        var n=contents.length;
        for(var j=0;jthis.data[j]
      =contents[j];
      }
      function table_isHeader(row,col){
        return this.header[row* this.columns+col ];
      }
      function table_makeHeader(row,col){   this.header[row* this.columns+col ]=true;
      }
      function table_makeNormal(row,col){   this.header[row* this.columns+col ]=false;
      }
      function table_makeHeaderRow(row){   for(var j=0;j< this.columns+j)
          this.header[row* this.columns+col ]=true;
      }
      function table_makeHeaderColumn(col){   for(var i=0;i< this.rows;++i)
          this.header[i* this.columns+col ]=true;
      }
      function table_write(doc){
        doc.write("<TABLE BORDER="+ this.border+">");
        for(var i=0;i< this.rows;++i) {
          doc.write("<TR>");
          for(var j=0;j< this.columns;++j) {
            if( this.header[i* this.columns+j ]) {
              doc.write("<TH>");
              doc.write( this.data[i* this.columns+j ]);
              doc.write("</TH>");
            }
            else {
              doc.write("<TD>");
              doc.write( this.data[i* this.columns+j ]);
              doc.write("</TD>");
            }
          }
          doc.writeln("</TR>");
        }
        doc.writeln("</TABLE>");
      }
      funtion table(rows,columns) {
        this.rows=rows
        this.columns=columns
        this.border=0
        this.data=new Array(rows*columns)
        this.header=new Array(rows*columns)
        this.getValue=table_getValue
        this.setValue=table_setValue
        this.set=table_set
        this.isHeader=table_isHeader
        this.makeHeader=table_makeHeader
        this.makeNormal=table_makeNormal
        this.makeHeaderRow=table_makeHeaderRow
        this.makeHeaderColumn=table_makeHeaderColumn
        this.write=table_write
       
      }

    2. table 객체 사용하기
      <HTML>
      <HEAD>
      <TITLE>Defining Object Types</TITLE
      <SCRIPT LANGUAGE="JavaScript" SRC="table.js"><!-
      //-></SCRIPT>
      </HEAD>
      <BODY>
      <H1>Defining Object Types</H1>
      <SCRIPT LANGUAGE="JavaScript"><!-
      t=new table(3,4)
      contents=new
      Array("This","is","a","test","of","the","table","object.","Let's","see","it","work")
      t.set(contents)
      t.border=4
      t.makeHeaderColumn(0)
      t.write(document)
      //-></SCRIPT>
      </BODY>
      </HTML>

    3. 객체 유형에 프로퍼티와 메소드 추가
      : prototype 프로퍼티를 통해서 인스턴스화할 수 있는 미리 정의된 객체 유형에 프로퍼티와 메소드 추가
      사용 예
      <HTML>
      <HEAD>
      <TITLE>Updating Object Types </TITLE>
      <SCRIPT LANGUAGE="JavaScript" SRC="table.js"><!-
      //-></SCRIPT>
      </HEAD>
      <BODY>
      <H1>Updating Object Types</H1>
      <SCRIPT LANGUAGE="JavaScript"><!-
      function table_colorWrite(doc){
        ........
        함수 정의
        ........
        ........
      }
      t=new table(3,4)
      table.prototype.bgColor="Cyan"
      table.prototype.colorWrite=table_colorWrite
      .............
      .............
      t.colorWrite(document)
      //-></SCRIPT>
      </BODY>
      </HTML>

    4. 프로퍼티와 메소드 삭제
      delete objectName.propertyName
      delete objectName.methodName


     


    브라우저 객체

    객 체 용 도
    window 객체 브라우저 윈도우나 윈도우 안에 있는 프레임에 액세스할 때 사용한다. 프로퍼티와 메소드를 참조할 때, window 객체가 존재하는 경우에는 "window."접두사를 붙일 필요가 없다
    document 객체 현재 윈도우에 로드되어 있는 문서에 액세스할 때 사용한다. document 객체는 컨텐트를 제공하는 HTML 문서, 즉 HEAD와 BODY 태그가 있는 문서를 의미한다.
    location 객체 URL을 나타낼 때 사용한다. 이 객체는 URL객체를 만들거나 URL의 일부분에 액세스하거나 기존의 URL을 수정할 때 사용할 수 있다.
    history 객체 한 윈도우 안에서 액세스된 URL의 히스토리를 유지할 때 사용
    frame 객체, frames 배열 HTML 프레임에 액세스할 때 사용
    frames 배열은 윈도우안에 있는 모든 프레임에 액세스할 때 사용
    link 객체, links 배열 하이퍼텍스트 링크의 텍스트 기반이나 이미지 기반 소스 앵커(anchor)에 액세스할 때 사용
    links배열은 문서 안에 있는 모든 link 객체에 액세스할 때 사용한다. I.E.는 link 객체의 anchor객체를 결합한다.
    anchor 객체, anchors 배열 하이퍼텍스트 링크의 타켓에 액세스할 때 사용
    anchors 배열은 문서 안에 있는 모든 anchor 객체에 액세스할 때 사용
    image객체, images 배열 HTML 문서에 삽입되어 있는 이미지에 액세스할 때 사용
    images 배열은 문서 안에 있는 모든 image 객체에 액세스할 때 사용
    area 객체 클라이언트측 이미지맵 안에 있는 영역에 액세스할 때 사용
    applet 객체, applets 배열 Java 애플릿에 액세스할 때 사용
    애플릿 배열은 문서 안에 있는 모든 애플릿에 액세스할 때 사용
    event 객체, Event 객체 이벤트 발생에 대한 정보에 액세스할 때 사용
    event 객체는 특정 이벤트에 대한 정보 제공
    Event 객체는 이벤트를 식별하는 데 사용하는 상수 제공
    form 객체, forms 배열 HTML 폼에 액세스시 사용
    forms 배열은 문서 안에 있는 모든 폼에 액세스시 사용
    element 객체 폼 안에 들어있는 모든 폼 요소에 액세스시 사용
    text 객체 폼의 텍스트 필드에 액세스시 사용
    textarea 객체 폼의 텍스트 영역 필드에 액세스시 사용
    radio 객체 폼의 라디오 버튼 세트에 액세스하거나 세트 안에 있는 각각의 버튼에 액세스할 때 사용
    checkbox 객체 폼의 체크 박스에 액세스할 때 사용
    button 객체 Submit나 Reset 버튼이 아닌 폼 버튼에 액세스시 사용
    reset 객체 폼의 Reset 버튼에 액세스시 사용
    selet 객체 폼의 선택 리스트에 액세스시 사용
    option 객체 option 객체는 선택 리스트의 요소에 액세스시 사용
    password 객체 폼의 패스워드 필드에 액세스시 사용
    hidden 객체 폼의 숨겨진 필드에 액세스시 사용
    FileUpload 객체 폼의 파일 업로드 요소에 액세스시 사용
    navigator 객체 스크립트를 실행하고 있는 브라우저에 대한 정보에 액세스시 사용
    screen 객체 사용자의 화면의 색상 깊이와 크기에 대한 정보에 액세스시 사용
    embed 객체, embeds 배열 삽입된 객체에 액세스시 사용
    embeds 배열은 문서 안에 삽입된 모든 객체에 대한 액세스 제공
    mimeType 객체, mimeTypes 배열 브라우저가 제공하는 특징 MIME 유형에 대한 정보에 액세스시 사용
    mimeTypes 배열은 제공하는 모든 mimeType 객체의 배열
    I.E.는 빈 배열을 리턴하면서 mimeTypes에 대해서 임시적으로 지원
    plugin 객체, plugins 배열 특정 브라우저 플러그인에 대한 정보에 액세스시 사용
    plugins 배열은 브라우저가 지원하는 모든 플러그인의 배열
    I.E.는 빈 배열을 리턴하면서 plugins에 대해서 임시적으로 지원


    window 객체

    • 모든 브라우저 스크립트의 기본적인 것으로, 브라우저가 자동으로 정의하는 최상위 레벨의 객체이다. 현재 열려 있는 각 윈도우에 대해 별도의 window 객체가 정의된다.


    window 객체의 프로퍼티
    프로퍼티 설 명
    closed 윈도우가 닫혀 있는지 식별
    defaultStatus 브라우저 윈도우의 하단의 상태바에 나타나는 디폴트 상대 메시지를 지정
    document 윈도우에 표시되어 있는 현재 문서를 지정하는 객체
    frames 윈도우 객체에 들어 있는 모든 프레임 객체로 구성된 배열
    history 마지막으로 윈도우로 로드된 URL의 리스트를 포함하는 윈도우의 히스토리 객체
    length window에 들어 있는 프레임의 수 식별
    location window 객체와 관련된 URL을 지정하는 객체
    name 윈도우의 이름 지정
    offscreenBuffering 윈도우 정보의 오프스크린 버퍼링이 사용될 것인지를 지정하는 부울값
    오프스크린 버퍼링은 윈도우를 나타내기 전에 윈도우의 모든 요소를 로드할 때 사용
    opener 윈도우를 만들거나 열 수 있도록 해주는 window 객체 지정
    parent 특정 윈도우를 포함하는 윈도우를 지정하는 시너님
    self 참조될 현재 윈도우를 지정하는 시너님
    status 브라우저 윈도의 하단의 상태 표시줄에 나타날 임시 메시지를 지정
    top 중첩된 일련의 윈도우에서 맨 위에 있는 브라우저 윈도우를 의미하는 시너님
    window 참조될 현재 윈도우를 식별하는 시너님

    window 객체의 메소드
    메 소 드 설 명
    alert(text) 경고 다이얼로그 박스를 표시
    blur() 포커스를 윈도우에서 옮긴다
    setInterval(expression,milliseconds) 지정된 타임아웃 인터벌이 지난 이후에 표현식을 반복해서 평가하거나 함수를 불러온다.
    clearInterval(interval) 이전에 설정된 인터벌 타이머를 클리어
    setTimeout(expression,milliseconds) 타임아웃 기간이 지난 이후에 표현식을 평가하거나 함수를 호출한다.
    clearTimeout(timer) 이전에 설정된 타임아웃을 클리어
    close() 지정된 윈도우를 닫는다.
    confirm(text) 확인 다이얼로그 박스를 나타낸다.
    focus() 윈도우로 포커스를 가져간다.
    open(url,name,[options]) 새로운 윈도우를 열고 새로운 window 객체를 만듬
    prompt(text,defaultInput) 프롬프트 다이얼로그 박스를 나타낸다.
    scroll(x,y) 윈도우를 특정 위치까지 스크롤한다.

    open() 메소드의 옵션
    옵 션 설 명
    toolbar yes no 윈도우에 툴바 제공
    location yes no 윈도우에 위치 필드 제공
    directories yes no 디렉토리 버튼 제공
    status yes no 상태 표시줄 제공
    menubar yes no 메뉴바 제공
    scrollbars yes no 스크롤 바 제공
    resizable yes no 윈도우 크기 조절 가능
    width 정수 윈도우의 폭(픽셀)
    height 정수 윈도우의 높이(픽셀)


    frame 객체

    • 프레임은 윈도우를 독립된 표시 영역들로 분할한 후, 이 영역들에 표시되는 정보들을 강력하게 컨트롤 할 수 있게 해준다.
    • 프레임 객체의 프로퍼티와 메소드는 window 객체와 같지만, close() 메소드는 지원하지 않는다.


     


    document 객체

    • JavaScript 에서 아주 중요한 객체로, 이 객체를 사용하면 로드될 문서를 업데이트하고 로드된 문서 안에 있는 HTML 요소에 액세스할 수 있다.


    프로퍼티 설 명
    alinkColor <BODY> 태그의 alink 속성의 값 지정
    anchor 문서에 들어 있는 배열을 참조하는 객체
    anchors 문서에 들어 있는 모든 앵커의 배열
    applet 문서에 들어 있는 애플릿을 참조하는 객체
    applets 문서에 들어 있는 모든 애플릿의 배열
    area 문서 안의 이미지맵 영역을 참조하는 객체
    bgColor <BODY> 태그의 bgColor 속성의 값 식별
    cookie 쿠키의 값 식별
    domain 문서가 로드되는 서버의 도메인 이름 식별
    embeds 문서안의 모든 플러그인의 배열
    fgColor <BODY> 태그의 text 속성값 지정
    form 문서 안의 폼을 참조하는 객체
    Forms[] 문서 안의 모든 폼의 배열
    image 문서 안의 이미지를 참조하는 객체
    Images[] 문서 안의 모든 이미지의 배열
    lastModified 문서가 마지막으로 수정된 날짜
    link 문서 안의 링크를 참조하는 객체
    links 문서 안의 모든 링크의 배열
    linkColor <BODY> 태그의 link 속성의 값 식별
    plugin 문서 안의 플러그인을 참조하는 객체
    plugins[] 브라우저가 지원하는 플러그인을 나타내는 객체의 배열
    referrer 문서에 대한 링크를 제공하는 문서의 URL
    title 문서의 타이틀
    URL 문서의 URL
    vlinkColor <BODY> 태그의 vlink 속성의 값 식별

    document 객체의 메소드
    메 소 드 설 명
    close() 문서의 객체를 만드는 데 사용된 스트림
    open([mimeType][,"replace"]) 선택적인 MIME 유형으로 문서 객체를 만들 때 사용되는 흐름을 개시한다. "replace" 파라미터는 text/html MIME 유형과 함께 사용되어 히스토리 리스트에 있는 현재 문서를 대체
    write(expr1[,expr2...,exprN]) 문서에 표현식의 값을 기록
    write(expr1[,expr2...,exprN]) 개행 문자가 다음에 따라오는 문서에 표현식의 값 기록


    navigator 객체

    • navigator 객체는 window 객체와 마찬가지로 브라우저 객체 모델에서 최상위 레벨의 객체이며, 스크립트를 실행할 때 사용되는 브라우저의 종류와 버전에 대한 정보 제공한다.


    navigator 객체의 프로퍼티
    프로퍼티 브라우저 지원 설 명
    appCodeName N2, I.E3 브라우저 색상 이름
    AppMinorVersion I.E4 브라우저 버전 번호
    appName N2, I.E3 브라우저 이름
    appVersion N2, I.E3 브라우저의 버전
    browserLanguage I.E4 브라우저에 설정되어 있는 언어
    connectionSpeed I.E4 브라우저가 네트워크에 연결되는 속도
    cookieEnabled I.E4 브라우저가 쿠키를 허용하도록 설정되어 있는지의 여부
    cpuClass I.E4 브라우저 실행시 사용되는 마이크로프로세서의 유형
    onLine I.E4 브라우저가 현재 온라인 연결을 가지고 있는지 여부
    Language N4, I.E4 브라우저에 설정되어 있는 언어
    mimeTypes N3, I.E4 현재 브라우저가 지원하는 모든 MIME 유형의 배열
    platform N4, I.E4 브라우저가 실행되는 운영체제 플랫폼
    plugins N3, I.E4 현재 브라우저에 설치된 모든 플러그인의 배열
    systemLanguage I.E4 운영체제의 디폴트 언어
    userAgent N2, I.E3 브라우저에서 서버로 전송된 HTTP 프로토콜의 사용자 에이전트 헤더
    userLanguage I.E4 사용자가 사용하는 언어
    userProfile I.E4 사용자 프로파일 정보에 대한 액세스를 제공하는 객체

    navigator 객체의 메소드
    메 소 드 설 명
    javaEnabled() 사용자가 브라우저의 Java 기능을 켜두었는지의 여부를 나타내는 부울값 리턴
    taintEnabled() 사용자가 data tainting(보안 메커니즘)을 활성화했는지 여부를 나타내는 부울값 리턴
    preference 서명이 되지 않은 스크립트가 보안 관련 프로퍼티를 얻고 설정할 때 사용


    event 객체

    event 객체의 프로퍼티
    프로퍼티 브라우저 설 명
    data N DragDrop 이벤트로 인해 드롭된 객체의 URL이 들어있는 스트링 배열
    height, width N 윈도우나 프레인의 길이와 너비(픽셀표시)
    pageX, pageY N 픽셀로 나타낸 커서의 수평/수직 위치(페이지에서의 상대적위치)
    screenX, screenY N, I.E 픽셀로 나타낸 커서의 수평/수직 위치(화면에서의 상대적 위치)
    layerX, layerY N 픽셀로 나타낸 커서의 수평/수직 위치, 이벤트가 발생한 레이어에 대한 상대적 위치. Resize 이벤트와 함께 사용하면 layerX와 layerY가 이벤트가 타겟으로 하는 객체의 길이와 너비 지정
    clientX와 clientY I.E 픽셀로 나타낸 커서의 수평/수직 위치, 이벤트가 발생한 웹페이지에서의 상대적 위치
    offsetX, offsetY I.E 픽셀로 나타낸 커서의 수평/수직 위치, 이벤트가 발생한 컨테이너에 대한 상대적 위치
    X, Y I.E 픽셀로 나타낸 커서의 수평/수직 위치, 이벤트가 발생한 문서에 대한 상대적 위치
    target N 이벤트가 전송된 원래 객체
    srcElement I.E 이벤트가 전송된 원래 객체
    type N, I.E 발생한 이벤트 유형
    which N 눌려진 마우스 버튼(왼:1, 가:2, 오:3)이나 눌려진 키의 ASCII값
    keyCode I.E 키 누름과 연관된 Unicode 키 코드를 식별
    button I.E 이벤트가 발생했을 때 눌려진 마우스 버튼 식별(0:눌려진버튼없음, 1:왼, 2:오, 4:가)
    modifiers N 마우스나 키 이벤트와 연관된 수정자 키(ALT_MASK,CONTROL_MASK,SHIFT_MASK,META_MASK)를 식별
    altkey,ctrlkey,shiftkey I.E true나 false로 설정하여 이벤트가 발생했을 때 Alt키와 Control키, Shift 키 중에 어떤 것이 눌려졌는지 알려준다.
    cancelBubble I.E true나 false로 설정하여 이벤트 버블링을 취소하거나 활성화한다.
    fromElement, toElement I.E 이동 중인 HTML 요소 지정
    reason I.E 데이터 소스 객체에 대한 데이터 전송 상태를 나타내는데 사용
    returnValue I.E true나 false로 설정하여 이벤트 핸들러의 리턴값을 나타낸다. 이벤트 핸들러에서 true나 false를 리턴하는 것과 같다.
    srcFilter I.E onfilterchange 이벤트를 시작하는 filter객체 지정


    screen 객체

  • screen 객체의 프로퍼티
    • height : 사용자의 화면의 현재 높이(픽셀)
    • width : 사용자의 화면의 현재 너비(픽셀)
    • colorDepth : 사용자의 화면/비디오 카드에서 현재 지원하는 색상당 바이트 수


      form 객체

      • document 객체의 프로퍼티로 액세스되고, form 객체는 문서 안의 폼에 액세스할 수 있도록 해주고, 폼 관련 이벤트에 응답을 할 수 있도록 해주기 때문에 중요하다.
      form 객체의 프로퍼티
      프로퍼티 설 명
      action <FORM> 태그의 HTML action 속성에 대한 액세스 제공
      button GUI 컨트롤 버튼을 나타내는 객체
      checkbox 체크 박스 필드를 나타내는 객체
      elements 폼 안에 포함되어 있는 모든 필드와 GUI 컨트롤을 포함하는 배열
      encoding <FORM> 태그의 HTML enctype 속성에 대한 액세스 제공
      FileUpload 파일 업로드 폼 필드를 나타내는 객체
      hidden 숨겨진 폼 필드를 나타내는 객체
      length elements 배열의 길이에 대한 액세스 제공
      method <FORM> 태그의 HTML method 속성에 대한 액세스 제공
      name 폼의 이름 식별
      password 패스워드 필드를 나타내는 객체
      radio 라디오 버튼 필드를 나타내는 객체
      reset reset 버튼을 나타내는 객체
      select 선택 항목 리스트를 나타내는 객체
      submit submit 버튼을 나타내는 객체
      target <FORM> 태그의 HTML target 속성에 대한 액세스 제공
      text 텍스트 필드를 나타내는 객체
      textarea 텍스트 영역 필드를 나타내는 객체

      form 객체의 메소드
      메 소 드 설 명
      handleEvent() 지정된 이벤트에 대한 폼의 이벤트 핸들러를 호출할 때 사용
      submit() 폼을 제출시 사용
      reset 폼의 엔트리를 디폴트 값으로 재설정시 사용

      form 요소 객체의 프로퍼티
      객 체 프로퍼티 설 명
      button name 버튼의 name 속성에 대한 액세스 제공
      type 객체의 유형 지정
      value 객체의 값 지정
      checkbox checked 체크박스가 현재 체크되어 있는지를 식별
      defaultChecked 체크박스가 디폴트로 체크되어 있는지 식별
      name 체크박스의 HTML name 속성에 대한 액세스 제공
      type 객체의 유형 식별
      value 객체의 값 식별
      FileUpload name 객체의 name 속성에 대한 액세스 제공
      type 객체의 type 속성에 대한 액세스 제공
      value 객체의 값 식별
      hidden name 객체의 name 속성에 대한 액세스 제공
      type 객체의 유형 식별
      value 객체의 값 식별
      password defaultChecked 객체의 디폴트 값 식별
      name 객체의 name 속성에 대한 액세스 제공
      type 객체의 유형 식별
      value 객체의 값 식별
      radio checked 라디오 버튼이 체크되어 있는지 식별
      defaultChecked 라디오 버튼이 디폴트로 체크되어 있는지 식별
      name 객체의 name 속성에 대한 액세스 제공
      type 객체의 유형 식별
      value 객체의 값 식별
      reset name 객체의 name 속성에 대한 액세스 제공
      type 객체의 유형 식별
      value 객체의 값 식별
      select length 선택 리스트의 길이 식별
      name 객체의 name 속성에 대한 액세스 제공
      option 선택 리스트가 제공하는 옵션 식별하는 배열
      selectedIndex 선택 리스트 안에서 처음 선택된 옵션 식별
      type 객체의 유형 식별
      submit name 객체의 name 속서에 대한 액세스 제공
      type 객체의 유형 식별
      value 객체의 값 식별
      text defaultValue 텍스트 필드에 나타나는 디폴트 텍스트를 식별
      name 객체의 name 속성에 대한 액세스 제공
      type 객체의 유형 식별
      value 객체의 값 식별
      textarea defaultValue 텍스트 영역 필드에 나타나게 되는 디폴트 텍스트 식별
      name 객체의 name 속성에 대한 액세스 제공
      type 객체의 유형 식별
      value 객체의 값 식별

      form 요소 객체의 메소드
      객 체 메 소 드 설 명
      button Click() 클릭된 버튼 시뮬레이트
      blur() 포커스 잃음
      focus() 포커스 맞춤
      checkbox Click() 클릭된 체크 박스 시뮬레이트
      blur() 포커스 잃음
      focus() 포커스 맞춤
      FileUpload blur() 포커스 잃음
      focus() 포커스 맞춤
      select() 입력 영역을 선택
      hidden 없음
      password blur() 포커스 잃음
      focus() 포커스 맞춤
      select() 패스워드 필드에 나타나는 텍스트를 하이라이트
      radio Click() 라디오 버튼 클릭 시뮬레이트
      blur() 포커스 잃음
      focus() 포커스 맞춤
      reset Click() 리셋 버튼 클릭 시뮬레이트
      blur() 포커스 잃음
      focus() 포커스 맞춤
      select blur() 포커스 잃음
      focus() 포커스 맞춤
      submit Click() 제출 버튼 클릭 시뮬레이트
      blur() 포커스 잃음
      focus() 포커스 맞춤
      text blur() 포커스 잃음
      focus() 포커스 맞춤
      select() 텍스트 필드에 있는 텍스트 하이라이트
      textarea blur() 포커스 잃음
      focus() 포커스 맞춤
      select() 텍스트 영역에 있는 텍스트 하이라이트


      location 객체

      • 윈도우에 로드되어 있는 현재 문서의 URL에 액세스하거나 새로운 문서를 로드할 때 사용

      location 객체의 프로퍼티
      프로퍼티 설 명
      hash URL의 앵커 부분(존재하는 경우)
      host URL의 hostname:port 부분
      hostname URL의 host부분
      href 전체 URL
      pathname URL의 경로명 부분
      port URL의 포트 부분
      protocol URL의 프로토콜 부분
      search URL의 쿼리 스트링 부분

      location 객체의 메소드
      • reload() : 윈도우의 현재 문서를 브라우저의 Reload 버튼에서 사용하는 정책에 따라 다시 로드
        • Every time : 문서는 매번 서버에서 다시 로드
        • Once per session : 서버의 문서의 날짜가 캐시에 저장되어 있는 문서보다 더 최신 날짜라는 것을 나타내면 문서는 세션당 한 번씩 서버에서 다시 로드된다. 문서가 캐시에 없는 경우에는 서버에서 로드
        • Never : 문서는 가능하면 캐시에서 다시 로드, 그렇지 않으면 서버에서 로드
      • replace() : URL을 파라미터로 취하여, 현재 문서 히스토리 목록에 있는 현재 문서위로 그 URL의 문서를 로드, 그러면 브라우저의 Back버튼을 클릭하여 이전 문서로 돌아갈 수 없음


      link 객체

      • link 객체는 document 객체의 프로퍼티로, 문서에 들어있는 텍스트나 이미지 링크를 캡슐화
      • links 배열은 문서에 들어있는 모든 링크의 배열
      • link 객체의 메소드
        handleEvent() : event 객체를 인자로 취하며 그 이벤트에 대해 적당한 이벤트 핸들러 호출

      link 객체의 프로퍼티
      프로퍼티 설 명
      hash URL의 앵커 부분(존재하는 경우)
      host URL의 hostname:port 부분
      hostname URL의 host부분
      href 전체 URL
      pathname URL의 경로명 부분
      port URL의 포트 부분
      protocol URL의 프로토콜 부분
      search URL의 쿼리 스트링 부분
      target 링크의 HTML, target 속성


      anchor 객체

      • HTML 문서 안에서 이름이 지정된 오프셋으로 사용되는 앵커 의미
      • anchors 배열에는 문서의 모든 앵커가 들어있음
      • 프로퍼티나 메소드 또는 이벤트를 전혀 가지고 있지 않음
      • HTML 문서와 관련하여 정의된 이름이 지정된 오프셋을 추적할 때 사용
      • anchor 객체는 HREF 속성을 포함하는 경우에 link 객체가 된다.


      history 객체

      • history 객체의 프로퍼티
        • current : 윈도우에 나타나는 현재 문서의 URL
        • length : History 리스트의 길이
        • next : History 리스트에서의 다음 URL
        • previous : History 리스트에서의 이전 URL
      • history 객체의 메소드
        • back() : History 리스트에 이전 문서를 로드. 브라우저의 Back 버튼을 클릭하는 것과 같은 효과
        • forward() : History 리스트에 다음 문서를 로드. 브라우저의 Forward 버튼을 클릭하는 것과 같은 효과
        • go() : History 리스트에 있는 특정 문서로 감
          • go(n) : n>0인 경우, 이 메소드는 History 리스트에서 n개의 엔트리가 앞에 있는 문서를 로드, n=0인 경우에는 현재 문서가 다시 로드되고, n<0인 경우엔 History 리스트에서 n개의 엔트리 뒤에 있는 문서를 로드
          • go(string) : go()는 이 스트링을 서브스트링으로 갖고 있는 URL의 History 리스트에서 가장 가까운 문서를 로드


      image 객체

      • document 객체의 프로퍼티
      • 문서와 함께 로드된 이미지에 대한 액세스 제공
      • images 배열은 문서 안에 지정되어 있는 각각의 <IMG>태그에 대한 엔트리가 들어있음
      • image 객체 유형을 사용하면 키워드와 생성자로 새로운 image 객체를 명시적으로 만들 수 있다. Image() 생성자는 웹페이지의 일부로서 처음에 나타나지 않는 이미지를 만들고 미리 로드할 때 사용한다. 이러한 image 객체는 브라우저의 캐시에 저장되면 이미 나타난 이미지를 대체할 때 사용
        * Image() 생성자를 사용하여 캐시된 이미지 만드는 예 cachedImage=new Image()
        cachedImage.src="myImage.gif"
        = > 첫번째 문장은 새로운 image 객체를 만들고 그것을 cachedImage 변수에 대입하고, 두번째 문장은 image 객체의 src프로퍼티를 myImage.gif 이미지 파일로 설정한다. 이 경우 myImage.gif는 브라우저 캐시로 로드된다. 그러면 로드된 이미지는 cachedImage 변수를 사용하여 참조 가능하다.

        image 객체의 프로퍼티
        프로퍼티 설 명
        border <:IMG> 태그의 BORDER 속성의 값
        complete 이미지가 완전히 로드되었는지 식별
        height <:IMG> 태그의 HEIGHT 속성의 값
        hspace <IMG> 태그의 HSPACE 속성의 값
        lowsrc <IMG> 태그의 LOWSRC 속성의 값
        name <IMG> 태그의 NAME 속성의 값
        prototype image 객체에 사용자 지정 프로퍼티를 추가할 때 사용
        src <IMG> 태그의 SRC 속성의 값
        vspace <IMG> 태그의 VSPACE 속성의 값
        width <IMG> 태그의 WIDTH 속성의 값


      area 객체

      • 이미지맵은 여러 가지 다른 영역으로 나누어져 있는 이미지로서 각각의 영역은 자체 URL과 관련되어 있다. 그리고 이러한 영역과 관련된 사용자 처리 방식으로 area 객체를 제공

      area 객체의 프로퍼티
      프로퍼티 설 명
      hash area 객체의 HREF 속성의 파일 오프셋 부분
      host area 객체의 HREF 속성의 호스트 이름 부분
      hostname area 객체의 HREF 속성의 host:port 부분
      href area 객체의 완전한 HREF 속성
      pathname area 객체의 HREF 속성의 경로명 부분
      port area 객체의 HREF 속성의 포트 부분
      protocol area 객체의 HREF 속성의 프로토콜 부분
      search area 객체의 HREF 속성의 쿼리 스트링 부분
      target area 객체의 TARGET 속성


      Array 객체

      • Array 객체를 사용하면 배열을 객체처럼 액세스 가능
      • Array 객체의 프로퍼티
        • length : 배열의 길이 식별
        • prototype : 모든 객체 유형이 지원하는 프로퍼티로 객체 유형에 대해 추가적인 프로퍼티 및 메소드 정의 가능
      • Array 객체의 메소드
        • toString() : 배열의 스트링 버전 리턴, 배열 요소는 컴마로 구분
        • join(separator) : 배열의 스트링 버전 리턴, 배열 요소는 seperator 스트링으로 구분, 분리자가 없으면 컴마로 구분
        • reverse() : 배열의 요소를 역순으로 바꿈
        • sort(comparisionFunction) : 비교 연산에 따라 배열의 요소 정렬. 비교 함수가 지정되면, 배열 요소는 사전순서로 정렬. 비교 연산이 지정되면 두개의 파라미터 p1,p2를 취하고, p1이 p2보다 작은 경우에는 음의 정수를 리턴하고, 같으면 0을 리턴하고, p1이 p2보다 크면 양의 정수 리턴


      Boolean 객체

      • Boolean 객체를 사용하면 부울값은 객체로서 액세스 가능
      • Boolean 객체는 생성자에 대한 인자로서 값을 식별하여 만들어짐 myBoolean=new Boolean(false)
        yourBoolean=new Boolean(true)
      • Boolean 객체의 프로퍼티
        • prototype : 모든 객체 유형이 지원하는 프로퍼티로 객체 유형에 대해 추가적인 프로퍼티 및 메소드 정의 가능
      • Boolean 객체의 메소드
        • toString() : 부울값에 해당하는 스트링 리턴
        • valueOf() : 객체의 값에 따라 true나 false로 리턴


      Date 객체

      Date 객체의 메소드
      메 소 드 설 명
      getDate()
      getUTCDate()
      setDate()
      setUTCDate()
      Date 객체의 날짜를 설정하거나 리턴
      getDay()
      getUTCDay()
      Date 객체의 한 주의 날짜를 설정하거나 리턴
      getHours()
      getUTCHours()
      setHours()
      setUTCHours()
      Date 객체의 시간를 설정하거나 리턴
      getMilliseconds()
      getUTCMilliseconds()
      setMilliseconds()
      setUTCMilliseconds()
      Date 객체의 밀리초 값을 설정하거나 리턴
      getMinutes()
      getUTCMinutes()
      setMinutes()
      setUTCMinutes()
      Date 객체의 분을 설정하거나 리턴
      getMonth()
      getUTCMonth()
      setMonth()
      setUTCMonth()
      Date 객체의 달을 설정하거나 리턴
      getSeconds()
      getUTCSeconds()
      setSeconds()
      setUTCSeconds()
      Date 객체의 초를 설정하거나 리턴
      getTime()
      getUTCTime()
      Date 객체의 시간을 설정하거나 리턴
      getTimeZoneOffset() Date 객체의 시간대 오프셋(분)을 리턴
      getYear()
      getFullYear()
      getUTCFullYear()
      setYear()
      setFullYear()
      setUTCFullYear()
      Date 객체의 연도를 리턴하거나 설정한다. 완전한 연도를 나타내는 방법으로 4자리 연도 값을 사용한다.
      toGMTString() 날짜를 Internet GMT(Greenwich Mean Time) 포맷의 스트링으로 변환
      toLocaleString() 날짜를 로케일(locale)포맷의 스트링으로 변환. 로케일 포맷이란 사용자가 위치해 있는 지형적 위치에서 일반적으로 사용하는 포맷 의미
      toString() Date 객체의 스트링 값을 리턴
      valueOf() 1970년 1월 1일 자정 이후의 밀리초 값 리턴
      toUTCString() UTC에서 시간을 나타내는 스트링 값을 리턴

      Date 생성자
      생 성 자 설 명
      Date() 현재 날짜와 시간으로 Date 인스턴스 만듬
      Date(dateString) dateString 파라미터에 지정되어 있는 날짜로, Date 인스턴스를 만든다. dateString의 포맷은 "월,일,연도,시:분:초"
      Date(milliseconds) 1970년 1월 1일 자정 이후 지정된 밀리초 값으로 Date 인스턴스를 만든다.
      Date(year,month,
      day,hours,minutes,
      seconds,milliseconds)
      년,월,일,시,분,초,밀리초 정수에 따라 지정된 날짜로 Date 인스턴스를 만든다. 연도와 월 파라미터는 제공되어야 하고 다른 나머지 파라미터가 포함되면 앞에 오는 모든 파라미터가 제공되어야 한다.


      Function 객체

      • 함수를 객체처럼 액세스 가능하고, 이 객체는 스크립트를 실행하는 동안에 함수를 동적으로 만들고 호출할 때 사용
      • Function 객체는 함수의 파라미터와 본문을 Function() 생성자에 제공하면 된다.
        variable=new Function("p1","p2", ... ,"pn","body")
      • Function 객체 프로퍼티
        • length : 함수에 대해 정의된 파라미터의 숫자 식별
        • prototype : 모든 객체 유형이 지원하는 프로퍼티로 객체 유형에 대해 추가적인 프로퍼티 및 메소드 정의 가능
        • arguments : 호출시 함수에 전달되는 인자를 가리키는 배열
        • caller : 특정 함수를 호출한 함수를 가리킴
      • Function 객체의 메소드
        • toString() : 함수의 스트링 형태 리턴
        • valueOf() : 함수 자체 리턴


      Global 객체

      • new Global() 을 통해서 명시적으로 만들거나, 참조할 수 없다. 대신 해당 프로퍼티와 메소드가 전역 변수와 함수로 직접 참조됨
      • Global 객체의 프로퍼티
        • Nan : 숫자가 아니라는 의미
        • Infinity : 양수 무한대 값 의미
      • Global 객체의 메소드
        • escape(string) : string을 새로운 스트링으로 변환
        • eval(x) : 표현식 x의 값을 계산하고 리턴
        • inFinite(number) : number가 유한하면 true를 리턴하고, 무한하면 false를 리턴
        • inNaN(number) : number가 숫자가 아니면 true를 리턴하고, 숫자이면 false를 리턴
        • parseFloat(string) : string을 부동 소수 값으로 파싱
        • parseInt(string,radix) : string을 밑이 radix인 정수로 파싱
        • unescape(string) : escape()에 들어 있는 스트링을 원래의 값으로 되돌린다.


      Math 객체

      • 수학적 상수와 함수의 표준 라이브러리 제공
      • Math의 특수 인스턴스는 Math가 내장 객체이고 객체 유형이 아니기 때문에 만들어지지 않는다.

      Math 프로퍼티
      프로퍼티 설 명
      E Euler의 상수. 이것은 계산을 하는 어디에서나 발견할 수 있으며 자연대수의 기초
      LN2 2의 자연대수. 이것은 자연대수와 밑이 2인 대수 사이의 전환에 사용되는 간단한 상수
      LN10 10의 자연대수. LN2와 마찬가지로 대수 변환에 사용
      LOG2E 밑이 2인 E의 대수. 이것은 밑이 10인 대수를 밑이 E인 대수로 변환시 사용
      PI 원의 원주 대 지름의 비율
      SQRT1_2 1/2의 제곱근은 많은 삼각법 계산에서 사용
      SQRT2 2의 제곱근은 대수식에서 흔히 사용

      Math 메소드
      메 소 드 설 명
      abs(x) x의 절대값 리턴
      acos(x) x의 아크 코사인값 라디안으로 리턴
      asin(x) x의 아크 사인값 라디안으로 리턴
      atan(x) x의 아크 탄젠트 값을 라디안으로 리턴
      atan2(x,y) (x,y)에 해당하는 극좌표의 각도를 리턴
      ceil(x) x보다 크거나 작은 최소 정수값 리턴
      cos(x) x의 코사인 값 리턴
      exp(x) eX를 리턴
      floor(x) x보다 작거나 같은 최대 정수값 리턴
      log(x) x의 자연대수 리턴
      max(x,y) x, y 중 큰 값 리턴
      min(x,y) x, y 중 작은 값 리턴
      pow(x,y) xy를 리턴
      random() 0과 1사이의 임의의 숫자 리턴
      round(x) x의 가장 가까운 정수로 반올림되는 값 리턴
      sin(x) x의 사인값 리턴
      sqrt(x) x의 제곱근 리턴
      tan(x) x의 탄젠트 값 리턴


      Number 객체

      • Number 객체 유형을 사용하면 숫자를 객체로 다룰 수 있다.
      • Number 객체의 프로퍼티
        • MAX_VALUE : 숫자는 가능한 최대 수치값
        • MIN_VALUE : 숫자는 가능한 최소 수치값
        • NaN : 숫자가 아니다
        • NEGATIVE_INFINITY : 숫자가 음수 무한대 값
        • POSITIVE_INFINITY : 숫자가 양수 무한대 값
        • prototype : 모든 객체 유형이 지원
      • Number 객체의 메소드
        • toString(radix) : 밑이 radix인 숫자를 나타내는 스트링 리턴
        • valueOf() : Number 객체의 수치값 리턴


      Object 객체

      • Object 객체는 다른 모든 객체들이 파생되어 나가는 기반 객체로 이것의 프로퍼티와 메소드는 다른 객체 유형들에서 사용 가능
      • Object 객체의 프로퍼티
        • prototype : 모든 객체 유형이 지원
        • constructor : 객체 생성자의 이름 식별
      • Object 객체의 메소드
        • toString() : 객체를 스트링 표현으로 바꾸는 역할
        • valueOf() : 객체와 관련된 경우의 원시값(숫자,스트링,부울값)을 리턴하고, 그렇지 않은 경우에는 객체 자체를 리턴


      String 객체

      • 스트링을 객체로 액세스 가능
      • String 객체의 프로퍼티
        • length : 문자에서 스트링의 길이 알아내는 역할
        • prototype : 모든 객체 유형이 지원
      String 메소드
      메 소 드 설 명
      charAt(index) 메소드가 적용되는 스트링의 지정된 인덱스에 있는 문자로 구성된 스트링을 리턴
      charCodeAt(index) 지정된 인덱스의 문자의 Unicode 인코딩 리턴
      fromCharCode(codes) 문자 코드의 컴마로 구분된 시퀀스에서 스트링 만듬
      indexOf(pattern) 스트링안에 들어있는 pattern 파라미터가 지정한 첫 번째 스트링의 인덱스 리턴, 패턴이 스트링 안에 들어있지 않으면 -1 리턴
      indexOf(pattern,startIndex) startIndex가 지정한 위치에서 검색을 시작하는 것을 제외하면 indexOf(pattern) 메소드와 같다.
      lastIndexOf(pattern) 스트링에 들어 있는 pattern 파라미터가 지정한 마지막 스트링의 인덱스 리턴, 패턴이 스트링 안에 들어있지 않으면 -1 리턴
      lastIndexOf(pattern,startIndex) startIndex가 지정한 위치에서 검색을 시작하는 것을 제외하면 lastIndexOf(pattern)과 같다.
      splitSeparator() 하나의 스트링을 분리자를 기반으로 하여 서브스트링의 배열로 분리
      substring(startIndex) startIndex에서 시작하는 스트링의 서브스트링을 리턴
      substring(startIndex,endIndex) startIndex에서 시작하고, endIndex에서 끝나는 스트링의 서브스트링을 리턴
      toLowerCase() 소문자로 변환된 스트링의 복사본 리턴
      toString() 객체의 스트링 값을 리턴
      toUpperCase() 대문자로 변환된 스트링의 복사본 리턴
      valueOf() 객체의 스트링 값을 리턴


      출처: http://blog.naver.com/nhsbs/120012081562

    • 반응형

      'Information' 카테고리의 다른 글

      각종 확장자 파일 모음  (0) 2007.03.03
      insertAdjacentElement Method  (0) 2007.03.03
      Flash OBJECT and EMBED tag attributes  (0) 2007.03.03

      insertAdjacentElement Method

      Internet Development Index

      Inserts an element at the specified location.

      Syntax

      oElement = object.insertAdjacentElement(sWhere, oElement)

      Parameters

      sWhere Required. String that specifies where to insert the HTML element, using one of the following values:
      beforeBegin Inserts oElement immediately before the object.
      afterBegin Inserts oElement after the start of the object but before all other content in the object.
      beforeEnd Inserts oElement immediately before the end of the object but after all other content in the object.
      afterEnd Inserts oElement immediately after the end of the object.
      oElement Required. Object that specifies the element to be inserted adjacent to the object that invoked the insertAdjacentElement method.

      Return Value

      Returns an element object.

      Remarks

      You cannot insert text while the document is loading. Wait for the onload event before attempting to call this method.

      If you try to insert an object that already exists on the page, the existing object will be moved to the point that you specified in the insertAdjacentElement method; no new object will be created.

      Example

      This example uses the insertAdjacentElement method to add a new list item to an ol object.

      Hide Example

      <SCRIPT>
      function fnAdd()
      {
         var oNewItem = document.createElement("LI");	
         oList.children(0).insertAdjacentElement("BeforeBegin",oNewItem);
         oNewItem.innerText = "List Item 0";
      }
      </SCRIPT>
      :
      <BODY>
      <OL ID = "oList">
      <LI>List Item 1</LI>
      <LI>List Item 2</LI>
      <LI>List Item 3</LI>
      </OL>
      
      <INPUT TYPE = "button" VALUE = "Add Item" onclick="fnAdd()">
      
      </BODY>

      Standards Information

      There is no public standard that applies to this method.

      Applies To

      TABLE
      Platform Version
      Win16: 5
      Win32: 5
      Unix: 5
      Mac: 5
      Windows CE: 5.5
      A, ACRONYM, ADDRESS, APPLET, AREA, B, BASE, BASEFONT, BDO, BGSOUND, BIG, BLOCKQUOTE, BODY, BR, BUTTON, CAPTION, CENTER, CITE, CODE, COL, COLGROUP, COMMENT, DD, DEL, DFN, DIR, DIV, DL, DT, EM, EMBED, FIELDSET, FONT, FORM, FRAME, FRAMESET, HEAD, hn, HR, HTML, I, IFRAME, IMG, INPUT type=button, INPUT type=checkbox, INPUT type=file, INPUT type=hidden, INPUT type=image, INPUT type=password, INPUT type=radio, INPUT type=reset, INPUT type=submit, INPUT type=text, INS, KBD, LABEL, LEGEND, LI, LINK, LISTING, MAP, MARQUEE, MENU, nextID, OBJECT, OL, OPTION, P, PLAINTEXT, PRE, Q, S, SAMP, SCRIPT, SELECT, SMALL, SPAN, STRIKE, STRONG, SUB, SUP, TABLE, TBODY, TD, TEXTAREA, TFOOT, TH, THEAD, TITLE, TR, TT, U, UL, VAR, XMP
      Move the mouse pointer over an element in the Applies To list to display availability information for the listed platforms.
      반응형

      Flash OBJECT and EMBED tag attributes

      This document lists the required and optional attributes of the OBJECT and EMBED tags used to publish Flash movies.

      For specific usage information for these attributes, refer to sections of the Using Flash manual devoted to using OBJECT and EMBED tags (exact headings vary among Flash versions). Information is also available in Macromedia Flash OBJECT and EMBED tag syntax (TechNote 4150).

      For more information on scripting with Flash see Scripting with Flash.

      Required attributes:

      • CLASSID - Identifies the ActiveX control for the browser. (See example code in TechNote 4150 for the correct value.) OBJECT only.
      • CODEBASE - Identifies the location of the Flash Player ActiveX control so that the browser can automatically download it if it is not already installed. OBJECT only. (See example code in TechNote 4150 for the correct value.)
      • WIDTH - Specifies the width of the movie in either pixels or percentage of browser window.
      • HEIGHT - Specifies the height of the movie in either pixels or percentage of browser window.
      • SRC - Specifies the location (URL) of the movie to be loaded. EMBED only.
      • PLUGINSPAGE - Identifies the location of the Flash Player plug-in so that the user can download it if it is not already installed. EMBED only. (See example code in TechNote 4150 for the correct value.)
      • MOVIE - Specifies the location (URL) of the movie to be loaded. OBJECT only.

      Optional attributes and possible values:

      • ID - Identifies the Flash movie to the host environment (a web browser, for example) so that it can be referenced using a scripting language. OBJECT-specific.
      • NAME - Identifies the Flash movie to the host environment (a web browser, typically) so that it can be referenced using a scripting language such as JavaScript or VBScript. EMBED-specific.
      • SWLIVECONNECT - (true, false) Specifies whether the browser should start Java when loading the Flash Player for the first time. The default value is false if this attribute is omitted. If you use JavaScript and Flash on the same page, Java must be running for the FSCommand to work.
      • PLAY - (true, false) Specifies whether the movie begins playing immediately on loading in the browser. The default value is true if this attribute is omitted.
      • LOOP - (true, false) Specifies whether the movie repeats indefinitely or stops when it reaches the last frame. The default value is true if this attribute is omitted.
      • MENU (true, false)
        • True displays the full menu, allowing the user a variety of options to enhance or control playback.
        • False displays a menu that contains only the Settings option and the About Flash option.
      • QUALITY - (low, high, autolow, autohigh, best )
        • Low favors playback speed over appearance and never uses anti-aliasing.
        • Autolow emphasizes speed at first but improves appearance whenever possible. Playback begins with anti-aliasing turned off. If the Flash Player detects that the processor can handle it, anti-aliasing is turned on.
        • Autohigh emphasizes playback speed and appearance equally at first but sacrifices appearance for playback speed if necessary. Playback begins with anti-aliasing turned on. If the actual frame rate drops below the specified frame rate, anti-aliasing is turned off to improve playback speed. Use this setting to emulate the View > Antialias setting in Flash.
        • Medium applies some anti-aliasing and does not smooth bitmaps. It produces a better quality than the Low setting, but lower quality than the High setting.
        • High favors appearance over playback speed and always applies anti-aliasing. If the movie does not contain animation, bitmaps are smoothed; if the movie has animation, bitmaps are not smoothed.
        • Best provides the best display quality and does not consider playback speed. All output is anti-aliased and all bitmaps are smoothed.
      • SCALE - (showall, noborder, exactfit)
        • Default (Show all) makes the entire movie visible in the specified area without distortion, while maintaining the original aspect ratio of the movie. Borders may appear on two sides of the movie.
        • No Border scales the movie to fill the specified area, without distortion but possibly with some cropping, while maintaining the original aspect ratio of the movie.
        • Exact Fit makes the entire movie visible in the specified area without trying to preserve the original aspect ratio. Distortion may occur.
      • ALIGN - (l, t, r, b)
        • Default centers the movie in the browser window and crops edges if the browser window is smaller than the movie.
        • Left, Right, Top, and Bottom align the movie along the corresponding edge of the browser window and crop the remaining three sides as needed.
      • SALIGN - (l, t, r, b, tl, tr, bl, br)
        • L, R, T, and B align the movie along the left, right, top or bottom edge, respectively, of the browser window and crop the remaining three sides as needed.
        • TL and TR align the movie to the top left and top right corner, respectively, of the browser window and crop the bottom and remaining right or left side as needed.
        • BL and BR align the movie to the bottom left and bottom right corner, respectively, of the browser window and crop the top and remaining right or left side as needed.
      • WMODE - (window, opaque, transparent) Sets the Window Mode property of the Flash movie for transparency, layering, and positioning in the browser.
        • Window movie plays in its own rectangular window on a web page.
        • Opaque the movie hides everything on the page behind it.
        • Transparent the background of the HTML page shows through all transparent portions of the movie, this may slow animation performance.

          Note: This property is not supported in all browsers and platforms. For more information about WMODE see How to make a Flash movie with a transparent background (TechNote 14201).
      • BGCOLOR - (#RRGGBB, hexadecimal RGB value) Specifies the background color of the movie. Use this attribute to override the background color setting specified in the Flash file. This attribute does not affect the background color of the HTML page.
      • BASE - ( . or base directory or URL) Specifies the base directory or URL used to resolve all relative path statements in the Flash Player movie. This attribute is helpful when your Flash Player movies are kept in a different directory from your other files.
      • FLASHVARS (variable to pass to Flash Player) Requires Macromedia Flash Player 6 or later.
        • Used to send root level variables to the movie. The format of the string is a set of name=value combinations separated by '&'.
        • Browsers will support string sizes of up to 64KB (65535 bytes) in length.
        • For more information on FlashVars, please refer to Using FlashVars to pass variables to a SWF (TechNote 16417).

      Note: Values in italics indicate that the developer chooses the value.

      Last updated: May 29, 2003
      Easy Link this TechNote

      http://www.macromedia.com/go/tn_12701

      Easy Links give you a simpler URL to reference in emails, as bookmarks… anywhere.


      http://www.macromedia.com/cfusion/knowledgebase/index.cfm?id=tn_12701

      반응형

      'Information' 카테고리의 다른 글

      insertAdjacentElement Method  (0) 2007.03.03
      보기좋은 코딩원칙1-80칸의 원칙  (0) 2007.03.03
      CSS Properties To JavaScript Reference Conversion  (0) 2007.03.03
      소스코드를 펼쳐보았을때 보기 좋은 코드가 이해하기도 쉽고 에러확률이 적고 디버깅하기 쉬운건 당연한 이치이다. 보기좋은 코드를 짜는건 몇가지 원칙만 지키면 되지만 많은 사람들이 그 몇가지를 지키지 않아 복잡하고 에러확율이 높고 디버깅하기 어려운 코드를 만들어 낸다.

      이번글에선 보기 좋은 코딩을 하기위한 첫번째 원칙 '80칸의 원칙'을 소개한다. 80칸의 원칙만 지켜도 코드가 정말 간결해 보인다. 물론 이글에서 제시하는하는것이 무조건 옳다는건 아니다. 사람에 따라서는 이글에서 나쁘다고 한 방식이 좋아보일수도 있겠다. 하지만 이글이 제시하는게 전혀 허무맹랑한것이 아니고 그렇게 들린다면 진지하게 한번더 생각해보고 선택했으면 한다.


      각설하고.. 아래 코드를 보자
      if(variable1 == variable2 && variable3 == variable4 && variable5 == variable6 && variable7 == variable8 && variable9 == variable10)
      {
          do_somthing();
      }
      
      일단 횡스크롤바가 생겨서 코드가 한눈에 안들어오고 if안에 뭐가 들어있나 찾아내기가 쉽지 않다. 같은코드를 아래처럼 수정했다.
      if(variable1 == variable2 && 
         variable3 == variable4 && 
         variable5 == variable6 && 
         variable7 == variable8 && 
         variable9 == variable10)
      {
          do_somthing();
      }
      
      라인이 조금 길어지긴했지만 우선 스크롤바가 없어져 코드가 한눈에 들어오고 if안에 것들이 열맞춰 정렬이 되어 있기때문에 한눈에 비교대상이 눈에 들어오고 쉬프트+방향키를 통해 에디팅하기도 편하다.

      그런데 왜하필 80칸이냐고? 80인이유는 80칸이 너무 좁지도 넓지도 않은 사이즈인데다가 윈도우의 도스 콘솔창이나 리눅스 쉘(이건 아닐지도..)의 가로 사이즈가 가로로 80칸이기 때문이다. 혹시나 콘솔에서 코드를 열어야 될지도 모르잖아?

      대부분의 유명한 코드들은 이원칙을 대부분 지킨다. 교육용 OS인 나초스에서도 이원칙을 지키고 MS의 DirectX 샘플코드들도 물론이원칙을 지킨다. 나초스의 소스를 링크해 뒀다. 확인해 보시라.
      나초스 - machin.cc


      출처 : 킬레인넷 v12.0
      반응형

      'Information' 카테고리의 다른 글

      Flash OBJECT and EMBED tag attributes  (0) 2007.03.03
      CSS Properties To JavaScript Reference Conversion  (0) 2007.03.03
      asp 속도업  (0) 2007.03.01

      CSS Properties To JavaScript Reference Conversion

      CSS Property JavaScript Reference
      background background
      background-attachment backgroundAttachment
      background-color backgroundColor
      background-image backgroundImage
      background-position backgroundPosition
      background-repeat backgroundRepeat
      border border
      border-bottom borderBottom
      border-bottom-color borderBottomColor
      border-bottom-style borderBottomStyle
      border-bottom-width borderBottomWidth
      border-color borderColor
      border-left borderLeft
      border-left-color borderLeftColor
      border-left-style borderLeftStyle
      border-left-width borderLeftWidth
      border-right borderRight
      border-right-color borderRightColor
      border-right-style borderRightStyle
      border-right-width borderRightWidth
      border-style borderStyle
      border-top borderTop
      border-top-color borderTopColor
      border-top-style borderTopStyle
      border-top-width borderTopWidth
      border-width borderWidth
      clear clear
      clip clip
      color color
      cursor cursor
      display display
      filter filter
      font font
      font-family fontFamily
      font-size fontSize
      font-variant fontVariant
      font-weight fontWeight
      height height
      left left
      letter-spacing letterSpacing
      line-height lineHeight
      list-style listStyle
      list-style-image listStyleImage
      list-style-position listStylePosition
      list-style-type listStyleType
      margin margin
      margin-bottom marginBottom
      margin-left marginLeft
      margin-right marginRight
      margin-top marginTop
      overflow overflow
      padding padding
      padding-bottom paddingBottom
      padding-left paddingLeft
      padding-right paddingRight
      padding-top paddingTop
      page-break-after pageBreakAfter
      page-break-before pageBreakBefore
      position position
      float styleFloat
      text-align textAlign
      text-decoration textDecoration
      text-decoration: blink textDecorationBlink
      text-decoration: line-through textDecorationLineThrough
      text-decoration: none textDecorationNone
      text-decoration: overline textDecorationOverline
      text-decoration: underline textDecorationUnderline
      text-indent textIndent
      text-transform textTransform
      top top
      vertical-align verticalAlign
      visibility visibility
      width width
      z-index zIndex

      Usage

      Internet Explorer

      document.all.div_id.style.JS_property_reference = "new_CSS_property_value";



      Older Netscape's (4.7 and earlier)

      document.div_id.JS_property_reference = "new_CSS_property_value";



      Netscape 6.0+ and Opera (and other Mozilla)

      document.getElementById(div_id).style.JS_property_reference = "new_CSS_property_value";

      Note the use of parentheses instead of square brackets in newer Mozilla's "getElementById()" reference.

       
       
       
      반응형

      'Information' 카테고리의 다른 글

      보기좋은 코딩원칙1-80칸의 원칙  (0) 2007.03.03
      asp 속도업  (0) 2007.03.01
      asp기본함수  (0) 2007.03.01
      아래의 내용은 ASP웹 응용 프로그램의 성능을 높이기 위한 팁을 설명한 것이다.

      [추가 정보]

      1. 가급적 Session 변수를 사용하지 않는다.

      Session 변수는 클라이언트 사이드에서 쿠키에 의해 유지되기 때문에, 웹 사용자가 브라우저상에서 쿠키의 사용을 Off했다면 Session변수는 작동되지 않을 것이다. 또한 Session변수는 오랜 시간 동안 유지된다.(새로운 사용자가 웹 서버를 들어왔을 때 생성되어 사용자의 세션이 유지되는 동안 살아있다.) 그러므로 만약 Session변수에 많고 복잡한 개체를 저장한다면 성능 저하를 초래할 것이다.(특히 사용자가 많아지면 많아질 수록) 꼭 필요 시에만 Session변수를 사용하고 사이즈가 큰 Dynamic Array나 ADO 개체, Business개체를 Session변수로 사용하지 않도록 한다.

      2.DataBase 성능을 높이기 위해서 ASP에서 SQL 쿼리문을 직접 사용하기 보다는 Stored Procedure를 이용한다.

      ASP 내에서 사용된 Database와 관련된 작업들의 성능을 높이기 위한 좋은 방법은 ASP 레벨에서 SQL 쿼리문을 실행하지 않고 저장 프로시저(Stored Procedure)를 사용하는 것이다. 3-Tier 응용프로그램에서 가장 좋은 접근 방법은 ASP에서 저장 프로시저를 호출하는 비즈니스 개체의 메서드를 호출하는 것이다.
      이 경우 Middle-Tier인 MTS Component에서는 코드의 유지보수가 훨씬 쉬워지고, DataBase-Tier에서는 SQL 저장 프로시저가 한번 실행되면 SQL서버의 메모리에 캐쉬되기 때문에 다음 번에 실행될 때 훨씬 속도가 빨라지는 장점을 가진다.

      3. Connection Pooling을 On한다.

      대 부분의 ASP 웹 응용프로그램이 데이터베이스 작업과 연관되어 있기 때문에 데이터베이스 작업의 성능을 높이는 것은 전체 ASP웹 응용프로그램의 성능과 관련이 깊다. 데이터베이스에 연결하기 위해 드는 시간과 리소스는 큰 비중을 차지한다. 그러므로 데이터 연결이 필요한 매 페이지마다 새로운 데이터베이스 연결을 하고 페이지가 실행을 마친 다음에 연결이 삭제되는 것은 특히 웹 서버에 동시 사용자가 많은 경우 성능은 매우 떨어질 것이다. Connection Pooling은 특정 페이지에서 사용된 Connection을 Pool에 가지고 있다가, 이 것이 필요할 때 재 사용할 수 있게 하는 것이다.
      ASP 웹 응용프로그램이 Connection Pooling을 사용하게 하려면 레지스트리에서 설정을 확인해야 한다.
      IIS 3.0인 경우에는 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\W3SVC\ASP\Parameters 에서 StartConnectionPool 엔트리의 값을 1로 설정해야 한다. IIS 4.0에서는 디폴트로 Connection Pooling이 On 되어 있다.

      또한 SQL 서버를 사용하는 경우에는 Network Library를 TCP/IP Socket로 설치해야 한다.

      4.Option Explicit를 사용한다.

      Option Explicit 옵션을 사용하게 되면, 선언되지 않은 변수는 에러를 발생한다. 선언되지 않은 로컬 변수는 선언된 변수보다 2배 정도 속도가 느리다. 이 옵션을 On함으로써 속도 뿐만 아니라 코드상에서 Mis-Spelling으로 인한 에러를 쉽게 발견할 수도 있다.

      5.생성된 개체를 Close하고 파괴하라.

      생성한 개체를 쓰고 난 후에는 꼭 그 개체를 Close하고 메모리에서 개체에 대한 인스턴스를 내려야 한다. 특히 ADO 개체인 경우 Connection Pooling이 사용되면 가능한 한 빨리 ADO Connection 개체를 Pool로 되돌려 주는 것이 좋기 때문에 명시적으로 Close와 Set 변수명 = Nothing을 사용해야 한다. 만약 ADO Connection개체를 Close하지 않고 Nothing만 하면 Connection Pooling이 적용되지 않으므로 Close와 Nothing을 모두 명시해야 한다.

      6. ADO의 Getstring을 사용하라.

      데 이터베이스의 쿼리를 실행하여 웹 페이지에 표시하는 작업은 레코드 수가 많아질 때 ASP의 스크립트 프로세싱 타임을 느리게 하는 원인이 된다. 예를 들어 테이블에 데이터를 나타낼 때 레코드셋의 EOF를 확인하여 DO…LOOP을 돌려 데이터를 테이블에 표시했다. 하지만 ADO 2.0에서 제공하는 GetString을 이용하면 loop이나 Eof의 Check없이 단 한번의 Response.write로 데이터를 테이블에 표시할 수 있게 된다.

      7. Collection의 값을 로컬 변수로 복사한다.

      사 용자가 ASP Collection의 값을 반복적으로 사용할 필요가 있다면 그 값들을 로컬 변수로 저장한다. 이렇게 함으로써 사용자가 Collection의 값을 사용할 때마다 서버가 Collection에서 값을 찾아오는 작업에 대한 시간을 적게 줄임으로써 스크립트 실행속도를 향상시킨다. 예를 들어 사용자는 다음과 같이 코딩할 수 있을 것이다.
      If Request.QueryString("Name") = "Frank" Then
      ...
      End If

      If Request.QueryString("Name") = "Steve" Then
      ...
      End If

      Response.Write("Your name is " & Request.QueryString("Name"))

      하지만 위의 코드에서 사용자가 Request개체를 사용할 때마다 ASP는 Querystring변수명을 읽어들여야 한다. 사용자는 다음과 같이 코드를 수정하므로써 Querystring으로부터 값을 한번만 읽어오게 할 수 있다.
      Dim strName
      strName = Request.QueryString("Name")

      If strName = "Frank" Then
      ...
      End If

      If strName = "Steve" Then
      ...
      End If

      Response.Write("Your name is " & strName)

      8. 데이터베이스 연결에 대해서 include파일을 이용하라.

      많 은 ASP개발자가 반복작업을 피하기 위해서 데이터베이스에 연결하는 ADO코드를 Session변수를 이용하는 경우가 있다. 하지만 위에서 언급한 바와 같이 Session변수에 ADO 개체를 할당하는 것은 권장되지 않는다. 이를 위한 가장 간단한 방법은 매 페이지마다 반복되는 데이베이스 연결 코드를 include파일에 작성하여 이 코드가 필요한 페이지마다 Include파일을 명시해주는 것이다.
      예를 들어 다음은 코드를 가진 scripts/dbconn.asp라는 페이지를 만든다.
      <%
      Dim objConn
      Set objConn = Server.CreateObject("ADODB.Connection")
      objConn.ConnectionString = "DSN=Blah"
      objConn.Open
      %>
      그 다음 데이터베이스 연결이 필요한 매 페이지에 다음의 한 라인을 추가해주면 된다.



      9. <%@ ENABLESESSIONSTATE = False %>

      ASP웹 페이지의 성능을 높이는 방법중의 하나는 @ENABLESESSIONSTATE 를 False로 설정하는 것이다. 만약 ASP페이지가 Session변수를 사용하지 않는다면 ASP 페이지의 가장 윗부분에 꼭 다음을 명시한다.
      <%@ ENABLESESSIONSTATE = False %>

      10.ADO 상수 사용 시 Numeric 상수 대신에 Named 상수를 사용한다.

      ADOVBS.INC를 Include하여 ADO의 Named 상수를 사용하는 것이 성능 향상에 도움이 된다.

      11. 클라이언트-사이드 폼 Validation을 사용한다.

      사 용자가 폼에 데이터를 입력하였을 때, 유효한 데이터가 입력되었는지 확인하기 위해서 클라이언트-사이드 스크립트를 사용하거나 ASP의 서버-사이드 스크립트에서 각 필드의 값을 확인할 수 있다. 서버 사이드 스크립트를 사용하는 경우 유효하지 않은 데이터가 입력된 경우 다시 ASP파일로 Redirection이 일어난다, 이 작업은 서버에 Round Trip을 발생시키기 때문에 성능에 좋지 않다. 클라이언트-사이드 Validation을 이용하여 폼이 Submit될 때 동시에 데이터 Validation이 일어나게 하는 것이 좋다.

      --------------------------------------------------------------------------------

      (주)마이크로소프트 KNOWLEDGE BASE내에서 제공되는 정보는 어떤 종류의 보증도 하지 아니하고 "있는 그대로"
      제공됩니다.(주)마이크로소프트는 시장성에 대한 보증 및 특정한 목적을 위한 적합성에 대한 보증을 포함하여
      모든 명시적, 또는 묵시적 보증을 배제합니다.(주)마이크로소프트 또는 그 공급자들은 직접적 손해, 간접적 손해, 부수적 손해,
      결과적 손해, 영업이익의 상실 또는 특별한 손해에 대하여 (주)마이크로소프트 또는 그 공급자들이 그 손해의 가능성을
      통지받은 경우에도 아무런 책임을 지지 않습니다.경우에 따라서는 결과적 손해 또는 부수적 손해의 배제 또는 책임의 제한을
      인정하지 않으므로 위와 같은 제한이 적용되지 않을 수도 있습니다.

      저작권 (주)마이크로소프트 1994 - 2000.
      반응형

      내 장 함 수

      설         명

        Abs(수)
        Abs(수식)

        절대값 구하기

        Array(배열1,배열2,.....)

        배열 반환

        Asc(문자열)

        문자의 ANSI 문자값 반환

        Atn(수)

        주어진 수를 아크탄젠트로 반환

        CBool(식)

        주어진 식을 Boolean(True 또는 False)형식으로 반환

        Cbyte(식)

        주어진 식을 Byte( 0~255 )형식으로 반환

        CCur(식)

        주어진 식을 Currency(통화:-922,337,203,685,477.5808~
        922,337,203,685,477.580)형식으로 반환

        CDate(날짜식)

        주어진 식을 Date(날짜)형식으로 반환

        CDbl(식)

        주어진 식을
        Double(-1.79769313486232E308~-4.94065645841247E-324
        및 4.94065645841247E-324~1.79769313486232E308)형식 반환

        Chr(ANSI문자코드)

        ANSI 문자코드를 일반문자로 반환

        CInt(식)

        주어진 식을 Interger(정수:-32,768~32,767)형식으로 반환

        CLng(식)

        주어진 식을 Long(-2,147,483,648~2,147,483,647)형식 반환

        Cos(수)

        주어진 수의 코사인 값을 반환

        CreateObject(클래스)

        다른 객체에 대한 참조를 만들어 반환

        CStr(식)

        주어진 식을 String(가변 길이 문자열의 경우 0개에서
        약 20억개까지의 문자)형식으로 반환

        Date()

        현재 날짜를 반환

        DateSerial(년,월,일)

        주어진 년,월,일의 Date(100년 1월 1일부터~9999년 12월 31일
        까지)형식을 반환

        Exp(수)

        주어진 수의 자연로그(e)를 반환

        Filter(검색문자열의1차원배열,검색문자열)
        Filter(검색문자열의1차원배열,검색문자열,Boolean)
        Filter(검색문자열의1차원배열,검색문자열,Boolean,
        비교형식의숫자값)

        지정한 필터로 문자열 배열 반환
        Boolean이 True면 검색문자 검색시 문자열 반환,
        False면 검색문자 미검색된 문자열 반한.

        Fix(수)

        주어진 수의 정수 반환

        FormatCurrency(수)
        FormatCurrency
        (수,NumDigitsAfterDecimal)
        FormatCurrency
        (수,NumDigitsAfterDecimal,IncludeLeadingDigit)
        FormatCurrency
        (수,NumDigitsAfterDecimal,IncludeLeadingDigit,
        UseParensForNegativeNumbers)
        FormatCurrency
        (수,NumDigitsAfterDecimal,IncludeLeadingDigit,
        UseParensForNegativeNumbers,GroupDigits)

        컴퓨터 규정의 통화값 반환

        FormatDateTime(날짜)
        FormatDateTime(날짜,날짜시간의숫자값)

        규정된 날짜와 시간으로 반환

        FormatNumber(수)
        FormatNumber
        (수,NumDigitsAfterDecimal)
        FormatNumber
        (수,NumDigitsAfterDecimal,IncludeLeadingDigit)
        FormatNumber
        (수,NumDigitsAfterDecimal,IncludeLeadingDigit,
        UseParensForNegativeNumbers)
        FormatNumber
        (수,NumDigitsAfterDecimal,IncludeLeadingDigit,
        UseParensForNegativeNumbers,GroupDigits)

        규정된 숫자로 반환

        FormatPercent(수)
        FormatPercent
        (수,NumDigitsAfterDecimal)
        FormatPercent
        (수,NumDigitsAfterDecimal,IncludeLeadingDigit)
        FormatPercent
        (수,NumDigitsAfterDecimal,IncludeLeadingDigit,
        UseParensForNegativeNumbers)
        FormatPercent
        (수,NumDigitsAfterDecimal,IncludeLeadingDigit,
        UseParensForNegativeNumbers,GroupDigits)

        규정된 퍼센트값을 반환

        Hex(수)

        주어진 수를 16진수 문자로 반환

        Hour(시간)

        0과 23사이의 시간으로 반환

        Inputbox(프롬프트)
        Inputbox(프롬프트,제목)
        Inputbox(프롬프트,제목,기본값)
        Inputbox(프롬프트,제목,기본값,xpos,ypos)
        Inputbox(프롬프트,제목,기본값,xpos,ypos,도움파일의URL,
        도움파일에서항목위치값)

        입력대화상자의 프롬프트를 생성

        InStr(문자열,찾을문자열)
        InStr(시작위치,문자열,찾을문자열,비교상수값)

        주어진 문자의 위치값을 반환

        InStrRev(문자열,찾을문자열)
        InStrRev(문자열,찾을문자열,시작위치,비교상수값)

        주어진 문자열의 위치값을 끝에서 부터 검색하여 반환

        Int(수)

        주어진 수의 정수값만 반환

        IsArray(변수)

        주어진 변수 배열여부를 Boolean값으로 반환

        IsDate(식)

        주어진 식이 날짜로 변환되는지를 Boolean값으로 반환

        IsEmpty(식)

        주어진 식의 변수가 초기화됐는지를 Boolean값으로 반환

        IsNull(식)

        주어진 식의 데이타 유효성을 Boolean값으로 반환

        IsNumberic(식)

        주어진 식의 값이 숫자화 될지 여부를 Boolean값으로 반환

        IsObject(식)

        자동화 객체를 참조하는지의 여부를 Boolean값으로 반환

        Join(목록)
        Join(목록,구분기호)

        배열에 포함된 여러 문자열을 결합하여 만든 문자열을 반환,
        구분기호 기본값은 공백(" ")이다.

        LBound(배열이름)
        LBound(배열이름,가장작은차원)

        주어진 배열에서 사용할 수 있는 가장 작은 첨자를 반환

        LCase(문자)

        주어진 문자를 소문자로 반환

        Left(문자열,수)

        주어진 문자열을 주어진 수만큼 문자를 반환

        Len(문자열)

        주어진 문자열의 문자갯수를 반환

        LoadPicture(그림파일명)

        그림 객체를 반환

        Log(자연로그)

        주어진 수의 자연로그를 반환

        LTime(문자열)

        주어진 문자열의 앞에 공백을 삭제하고 반환

        Mid(문자열,시작)
        Mid(문자열,시작,반환될길이)

        주어진 문자열에서 주어진 위치에서부터의 문자를 반환

        Minute(시간)

        시간에서 분값을 반환

        Month(날짜)

        달의 값을 반환

        MonthName(달)

        주어진 달의 수를 문자열로 반환

        MsgBox(프롬프트)
        MsgBox(프롬프트,단추)
        MsgBox(프롬프트,단추,제목)
        MsgBox(프롬프트,단추,제목,도움파일의URL,도움파일에서
        항목위치값)

        대화상자의 메세지를 생성

        Now()

        현재 날짜와 시간을 반환

        Oct(수)

        주어진 수의 8진수 값을 반환

        Replace(문자열,찾을문자열,바꿀문자열)
        Replace(문자열,찾을문자열,바꿀문자열,시작위치)
        Replace(문자열,찾을문자열,바꿀문자열,시작위치,바꿀횟수)
        Replace(문자열,찾을문자열,바꿀문자열,시작위치,바꿀횟수,
        바꿀비교형식)

        주어진 문자열의 주어진 문자를 바꾸어 반환

        Right(문자열,수)

        주어진 문자를 주어진 수만큼 오른쪽에서부터 반환

        Rnd()

        난수를 반환

        Round(수)

        주어진 수의 반올림 반환

        RTrim(문자열)

        주어진 문자열의 뒤 공백이 없는 문자을 반환

        ScriptEngine()

        사용 중인 스크립트 언어를 반환

        ScriptEngineBuildVersion()

        사용 중인 스크립트 언어의 버젼 수를 반환

        ScriptEngineMajorVersion()

        사용 중인 스크립트 언어의 주 버전 수를 반환

        ScriptEngineMinorVersion()

        사용 중인 스크립트 언어의 보조버전 수를 반환

        Second()

        시스템 시간의 초 값을 반환

        Sgn(수)

        주어진 수의 부호를 나타내는 정수를 반환

        Sin(수)

        주어진 수의 사인값을 반환

        Space(수)

        주어진 수만큼의 공백이포함된 문자열을 반환

        Split(문자열)
        Split(문자열,구분기호)
        Split(문자열,구분기호,반환문자열수)
        Split(문자열,구분기호,반환문자열수,바꿀비교형식)

        주어진 문자열이 포함된 1차 배열을 반환.
        구분기호 기본값은 공백(" ")이다

        Sqr(수)

        주어진 수의 제곱근을 반환

        StrComp(문자열,문자열)
        StrComp(문자열,문자열,비교형식)

        주어진 두 개의 문자열을 비교하여 결과값을 반환

        StrReverse(문자열)

        주어진 문자열을 뒤에서 부터 읽어서 반환

        String(수,문자열)

        주어진 문자가 주어진 수만큼 반복된 문자열을 반환

        Tan(수)

        주어진 각도의 탄젠트 값을 반환

        Time()

        현재 시간을 반환

        TimeSerial(시,분,초)

        주어진 시간의 시간,분,초에 대한 시간값을 반환

        TimeValue(시간)

        시간이 포함된 Date형식을 반환

        Trim(문자열)

        주어진 문자열의 앞,뒤 공백이 없는 문자열 반환

        TypeName(변수명)

        변수의 정보를 나타내는 문자열 반환

        UBound(배열명)
        UBound(배열명,가장큰차원)

        배열의 차원에서 가장 큰 첨자를 반환

        UCase(문자열)

        주어진 문자열을 대문자로 반환

        varType(변수명)

        변수의 형식을 나타내는 값을 반환

        Weekday(날짜)
        Weekday(날짜,주의첫째요일의숫자)

        요일을 나타내는 정수를 반환

        WeekdayName(요일)
        WeekdayName(날짜,주의첫째요일의숫자)

        요일을 나타내는 문자를 반환

        Year(1970표기날짜)

        현재의 연도를 반환

       
      반응형

      'Information' 카테고리의 다른 글

      asp 속도업  (0) 2007.03.01
      ASP에서 join과 split을 이용한 문자열 파싱(parsing)  (0) 2007.03.01
      전월세계약 6가지 포인트  (0) 2007.02.28

      join과 split는 문자열을 파싱(parsing)함에 있어 매우 유용한 함수들이다. 같단히 설명하자면, join은 하나의 일차원 배열의 내용을 하나의 문자열로 만드는 함수이고, split은 하나의 문자열 내용을 하나의 일차원 배열로 나누어 담는 함수이다.

      join에 대한 문법은 다음과 같다:


      join(list[, delimiter]) 


      여기서 list는 문자열로 연결시킬 내용들이 들어 있는 배열을 나타낸다. Delimeter는 배열에 있는 요소들로부터 문자열을 만들 때 각 요소 사이에 들어갈 문자열을 의미한다. 이 값은 옵션으로 이것을 지정하지 않으면 내부적으로 빈 문자열(" ")로 처리된다. 이제 간단한 예를 한 번 살펴 보도록 하자.


      Dim OneDimArray(5)
      OneDimArray(0) = "Hello,"
      OneDimArray(1) = "my"
      OneDimArray(2) = "name"
      OneDimArray(3) = "is"
      OneDimArray(4) = "Daniel!"

      Dim strSentence
      strSentence = join(OneDimArray) 


      위의 코드는 strSentence에 "Hello, my name is Daniel!"을 저장하게 된다. 만일 strSentence = join(OneDimArray) 부분을 strSentence = join(OneDimArray, ",") 부분으로 변경하면 strSentence에는 "Hello,,my,name,is,Daniel!"이 저장된다. 즉, 디리미터(delimeter, 구분자)는 앞의 경우 디폴트인 " " 이고, 후자의 경우는 ","인 것이다. 만일 배열의 각 요소를 하나의 문자열로 만들 때 각 요소 사이의 구분자가 없이 붙이고 싶을 경우는 단순히 strSentence = join(OneDimArray, "")라고 해주면 된다. 그 결과는 "Hello,mynameisDaniel!"이 될 것이다.


      split은 join의 반대 결과를 만든다. split은 문자열을 취하여 문자열의 각 요소들을 적절한 기준으로 잘라 내 일차원 배열로 담아낸다. split의 문법은 다음과 같다:


      split(String Expression[, delimiter[, count[, compare]]]) 


      여기서 반드시 필요한 파라미터는 배열로 담을 문자열, Expression이다. Delimeter는 join과 마찬가지로 옵션이다. 디폴트는 " " 이다. count는 결과로 반환할 부분 문자열의 갯수이다. compare는 부분 문자열을 비교하는 방법을 결정한다. 이제 간단한 예를 한 번 살펴 보도록 하자.


      Dim strSentence
      strSentence = "Hello, my name is Daniel!"

      Dim OneDimArray
      OneDimArray = split(strSentence)
       


      위의 코드는 strSentence에 담겨 있는 문자열을 OneDimArray란 일차원 배열의 각 요소에 "Hello,", "my", "name", "is", "Daniel!"을 저장한다. 만일 OneDimArray 배열에 3 요소만 저장하고 싶은 경우 count 파라미터를 이용하여 부분 문자열의 갯수를 정해주면 된다. 즉, OneDimArray = split(strSentence) 부분을 OneDimArray = split(strSentence, " ", 3)으로 변경시켜주면 된다. 이 결과는 "Hello,", "my", "name is Daniel!"이 된다. 만일 구분자로 컴마(,)를 사용하고 싶다면 OneDimArray = split(strSentence) 부분을 OneDimArray = split(strSentence, ",")로 변경시켜주면 된다. 이 결과는 "Hello", "my name is Daniel!"이 될 것이다.

      앞에서도 언급했지만 join과 split은 서로 반대 관계이다. 예를 들어, 다음과 같은 코드를 보자.


      Dim strSentence, strCopy
      strSentence = "Hello, my name is Bob!"
      strCopy = join(split(strSentence)) 


      위의 코드에서 strCopy와 strSentence는 동일한 값을 갖는다.

      지금까지 join과 split의 사용 방법에 대해 알아 보았다. 그렇다면 이 함수들은 언제 유용하게 사용될 수 있을까? 사실 ASP에서 문자열을 조작함에 있어 join과 split의 사용은 필수적이다. 하나의 예를 들기 위해 지난 시간에 살펴보았던 "AdRotator를 이용하여 배너 광고 로테이션 시키는 방법"에서 사용한 AdRotator.txt 파일을 살펴 보도록 하자. 그 파일에는 다음과 같은 형식의 데이터들이 저장되어 있다:


      Advertiser Name
      Advertiser URL
      Advertiser Category
      Banner ID
      Comment
      *
      Advertiser Name
      Advertiser URL
      Advertiser Category
      Banner ID
      Comment
      *
      Advertiser Name
      Advertiser URL
      Advertiser Category
      Banner ID
      Comment
      *

      ... 


      이런 텍스트 파일을 이용하여 작업을 할 때 제일 먼저 하는 일은 FileSystemObject 객체를 이용하여 전체 텍스트 내용을 하나의 문자열로 읽어 들이는 것이다. 그 문자열을 str이란 변수로 담았다고 한다면 다음으로 할 일은 recArray = split(str, "*")을 해주는 것이다.

      이렇게 함으로써 하나의 레코드 단위를 배열의 각 요소로 저장할 수가 있다. 마지막으로 레코드에 있는 각각의 요소를 얻으려면 elementArray = split(recArray(i), chr(13))이라고 해주면 된다. 여기서 chr(13)은 라인이 분리되어 있는 값을 의미한다.

      이런 과정을 거침으로써 텍스트 파일의 내용을 적절히 파싱(parsing)을 할 수 있게 된다.

      반응형

      'Information' 카테고리의 다른 글

      asp기본함수  (0) 2007.03.01
      전월세계약 6가지 포인트  (0) 2007.02.28
      정규식  (0) 2007.02.27
      봄 이사철을 앞두고 재계약을 앞둔 세입자들의 걱정이 커지고 있다. 2년 전보다 전·월세금이 오른 곳에서는 집주인들이 한꺼번에 전·월세금을 올려달라고 요구할 것으로 예상되기 때문이다. 재계약을 앞둔 세입자들이 반드시 알아두어야 할 것들을 살펴본다.

      1. 집주인에게 먼저 연락하지 말

      주택임대차보호법은 집주인이 계약 만기 한달 전까지 통보하지 않으면 기존 계약과 같은 조건으로 계약이 2년 연장된 것으로 간주한다. 따라서 계약 만기가 다가왔다고 해서 세입자가 집주인에게 먼저 연락할 필요는 전혀 없다. 계약을 연장할 것인지, 계약 조건을 바꿀 것인지는 어디까지나 집주인이 먼저 의사를 통보하는 게 순서다.

      2. 인상액을 월세로 돌릴 때는

      현행법상 2년의 전·월세 계약이 끝나 집주인들이 전·월세금을 대폭 인상하거나 집을 비워달라고 요구할 때 세입자가 대항할 방법은 없다. 전세금을 올려 줄 목돈이 없는 경우에는 인상되는 전세금을 월세로 돌려 내는 쪽으로 집주인과 합의하는 것이 하나의 방법이다. 이때 전환이율은 해당 지역의 월세 시세로 하는 게 원칙이다. 최근 전세금을 월세로 돌릴 때 적용되는 이율은 서울, 수도권의 경우 월 1%(연 12%) 수준이다. 전세금이 2천만원이면 월세는 20만원이 된다.

      3. 임차권 등기명령 활용해야

      이사하기로 했는데 전셋집이 빠지지 않아 보증금을 돌려받지 못하는 경우가 있을 수 있다. 이처럼 집주인이 계약 만기 후 보증금을 돌려주지 않을 경우에는 보증금 반환청구 소송을 제기하고 확정 판결을 받은 뒤 경매를 통해 보증금을 회수할 수밖에 없다. 다만 소송에 6개월 정도의 기간이 소요되고 경매절차도 6개월이 걸리는 점을 유의해야 한다. 이 경우 보증금을 돌려받지 못한 채 불가피하게 이사를 해야 할 경우가 생길 수 있다. 이때 주민등록을 옮기면 경매에서 우선순위를 확보할 권리인 ‘대항력’을 상실하기 때문에 주의해야 한다. 이런 경우에는 관할 법원에 임차권 등기명령 신청을 해 등기된 것을 확인한 뒤 주민등록을 옮겨야 대항력을 인정받는다.

      4. 집주인 바뀌었어도 종전 계약은 유효

      전세계약 기간 중 집주인이 바뀌어도 집을 비워줄 필요는 없다. 또 새 주인이 전세금을 올려달라고 할 때도 세입자는 이전 집주인과 계약한 내용을 바꾸는 계약을 맺을 의무가 없다. 다만, 전셋값이 주변 시세와 크게 차이가 나면 새 집주인이 보증금의 5% 범위에서 올려달라고 요구할 수는 있다. 이 경우라도 계약일로부터 1년이 경과해야 가능하다.

      5. 계약 해지하고 이사가려면

      세입자가 계약 기간이 남은 상태에서 임대차 계약을 해지할 때는 집 주인과 합의해야만 가능하다. 세입자가 개인 사정을 들어 일방적으로 계약을 해지할 수 없으며, 집주인은 계약기간 만료일까지는 보증금을 돌려줄 의무가 없다. 따라서 집주인에게 사정을 설명하고 다른 세입자를 구해 보증금을 받는다는 조건으로 서로 합의하는 게 현실적이다. 이 경우 중개수수료 등 이사 비용은 세입자가 부담해야 한다.

      6. 보증금 못 받았을땐 임차권 등기명령 활용

      건설교통부는 세입자들의 주거 안정을 위해 지난달 전·월세 지원센터(1577-3399)를 경기 수원시 국민임대주택 홍보관에 설치했다. 전·월세 계약과 관련해 궁금한 사항이 있으면 도움을 받을 수 있다.

      반응형

      'Information' 카테고리의 다른 글

      ASP에서 join과 split을 이용한 문자열 파싱(parsing)  (0) 2007.03.01
      정규식  (0) 2007.02.27
      용량계산기  (0) 2007.02.25
      또다시 오랜만 이군요...
      오늘은 정규표현식에 대해 간단하게 알아보는 시간을 갖도록 하겠습니다.

      정규표현식(Regular Expressions)라는 말은 자주들 들어 보셨을 겁니다.
      보통 정규식이라고 줄여서 부르기도 하는데요...
      이건 뭐 -_-a사람 이름도 아니고 말이죠....-.-규식아~~
      암튼...
      정규표현식이라는건 대체 뭘까요?

      말 그대로 어떤 내용에 대하여 정규화된 표현식을 말합니다.
      예를 들자면...

      abc
      def

      위와 같은 두개의 문자열이 있을때...
      위의 문자열들을 정규화하여 표현하자면 어떻게 될까요?

      * 알파벳으로 이루어져 있다

      맞습니까?
      맞죠...........당연한 말씀을 -_-a;;

      * 소문자 3자로 이루어져 있다

      역시 맞죠...
      대충 감이 오십니까?

      그럼이제 어떤 경우에 이 정규표현식이 쓰이는지 알아 볼까요?
      어떤 값을 입력받는데 있어서...
      반드시 영문 소문자와 숫자만을 이용하여 입력을 받아야 하는 경우가 있습니다.
      어떤경우죠?
      보통 회원가입에서 아이디 입력 등이 있겠군요...

      정규표현식으로 만들어 볼까요?

      * 영문 소문자와 숫자의 조합 이다
      * 4~12자 사이의 문자열 이다
      * 공백이 있어서는 안된다

      뭐 이정도면 될까요...

      이런 경우에 있어서 정규표현식이 사용되는데...
      이것을 이제 컴퓨터가 알아들을 수 있는 말로 바꾸어 주어야 하겠죠..
      이때 쓰이는 것이 바로 정규표현식 입니다.


      정규표현식을 사용하는데에는 여러가지 용도가 있겠죠...
      예를 들어 우리가 원하는 표현식과 일치 하는지 알아보기 위함이라던가...
      우리가 원하는 표현식에 해당하는 부분을 치환한다던가...
      아니면 우리가 원하는 표현식에 해당하는 부분을 경계로 문자열을 배열로 나눈다던가 말입니다.

      먼저 우리가 원하는 표현식과 일치 하는지를 알아보기 위해서는 ereg라는 함수가 사용 됩니다.
      형식은 아래와 같고요...

      $리턴값 = ereg("정규표현식","대상문자열");

      대상문자열이 정규표현식과 일치한다면 TRUE가 리턴되고...
      그렇지 않다면 FALSE가 리턴되겠죠...

      예를 들어 볼까요?

      <?
      echo ereg("b","abc");
      ?>

      실행 해보세요...
      결과는?

      1이 나올 것입니다...
      TRUE가 리턴된 것인데요...
      대상문자열 abc에 b가 포함되어 있느냐는 표현식이었습니다.
      물론 b가 포함되어 있으니 참이겠죠...

      그럼 이제 아래와 같이 해볼까요?

      <?
      echo ereg("B","abc");
      ?>

      결과는 FALSE가 되어 아무것도 출력되지 않을 것입니다.
      왜냐하면 abc에는 대문자B가 없기 때문이죠...
      그럼 함수를 ereg가 아닌 eregi로 바꾸어 볼까요?

      <?
      echo eregi("B","abc");
      ?>

      어라?
      결과는 다시 1 입니다.
      ereg에 i를 붙여 주었더니 대소문자를 구별하지 않는 군요...
      이때 i는 ignore겠죠...
      말그대로 대소문자 그런거 구분 하지 않겠다는 것입니다.
      대충 이해 가셨으리라 생각하고...

      슬슬 표현식을 구성하는 방법에 대해 알아보도록 하죠~


      정규표현식에서 가장 기본적인 것은...
      시작과 끝 입니다.
      시작은 ^이고 끝은 $로 표현하는데....

      * a로 시작되는 문자열

      위의 표현식은 아래와 같이 된다는 얘기 입니다.

      ^a

      그럼 c로 끝나는 문자열은 어떻게 될까요?

      c$

      이렇게죠...
      한번 확인해보도록 하죠...

      <?
      echo ereg("^a","abc");
      ?>

      결과는 당근 1 입니다.

      이때 abc이 이외에도 ^a라는 정규표현식에 해당하는 문자열에 대해서는
      모두 TRUE겠죠...

      a, aa, aaa, abb, abbbb, acccc

      위의 것 모두 TRUE입니다.
      모두 a로 시작하니까요...

      $도 같은 식으로 사용 하시면 되고요...
      만약 ^abc$와 같이 표현식을 주시면...
      abc라는 문자열만 TRUE가 됩니다...
      왜 인지는 잘 생각 해보시고요~


      * b가 없거나 한번이상 반복되는 문자열

      위의 문제는 조금 어렵죠...?
      b가 없거나 한번이상 반복되는 것은 어떤것을 말할까요?

      ac, abc, abbc, abbbc

      뭐 이런것들이겠죠...
      물론 acb나 acbb와 같은 것도 모두 맞습니다만...
      일단 위의 패턴만을 생각해보도록 하죠...
      위의 나열된 패턴은 a로 시작되어 c로 끝나면서..
      그 사이에 b가 없거나 한번이상 반복되는 것입니다.

      이때 b가 없거나 한번이상 반복되는 것은 *로 표현을 하는데요...

      b*와 같이 해주시면 되겠네요...
      이때 *는 없거나 한번이상 반복된다는 것을 말하는데요..
      바로 앖에 있는 문자만 해당합니다.

      말하자만 ab*과 같이 되어있을 경우에는...
      ab가 없거나 한번 이상...어쩌구가 아니라...
      a가 나오고 이어서 b가 없거나 한번이상...거시기라 그말이죠..

      그럼 다시 문제를 생각해볼때...

      a로 시작되어서........... -> ^a
      c로 끝나면서............. -> ^ac$
      b가 없거나 한번이상 반복. -> ^ab*c$

      쉽죠?^^
      정규표현식은...
      ac, abc, abbc, abbbc
      와 같은 문자열을 모두 포함합니다.

      이렇게 *와 같이 쓰이는 표현식중에 아래와 같은 것들도 있으니
      한번 눈여겨 보시고요~~~

      * -> 앞의 문자가 없거나 한번이상 반복
      + -> 앞의 문자가 반드시 한번이상 반복
      ? -> 앞의 문자가 없거나 한개만 있음

      위의 표현식들을 이용해보면 아래와 같은 결과들을 만들수 있습니다.

      ^ab*c$
      -> a로 시작되어 b가 없거나 한번이상 반복되고 c로 끝남
      -> ac, abc, abbc, abbbc 등등

      ^ab+c$
      -> a로 시작되어 b가 한번이상 반복되고 c로 끝남
      -> abc, abbc, abbbc 등등

      ^ab?c$
      -> a로 시작되어 b가 없거나 한개만 있고 c로 끝남
      -> ac, abc (두가지 뿐임)

      그런데 우리가 방금 배운 *, + ,?의 기능을 모두 해결해 줄수 있는
      표현식도 있습니다.
      바로 {와 }인데요...
      표현방법은 아래와 같습니다.

      {최소반복횟수,최대반복횟수}

      예를 들어 b{2,3}이라고 하였다면..
      b가 2번에서 3번 반복되는 것이라고 보시면 되고요...

      ^ab{2,3}c$

      위와 같은 식이라면...
      a로 시작하여 b가 2~3번 반복되고 c로 끝나는 문자열이 되겠네요..
      abbc, abbbc 이렇게 두가지경우가 있겠죠...
      그런데 이를 약간 변형하여...

      b{2}

      이렇게 써준다면..
      b는 반드시 2번 반복된다는 것이 되고...

      b{2,}

      이렇게 써준다면...
      b는 2번 이상이 되고...

      b{0,2}

      요건 2번 이하가 되겠죠....
      b{,2}가 아님에 주의 하세요...

      그럼 {와 }를 이용하여... *, +, ?를 흉내내 볼까요?-0-

      *은 앞의 문자가 없거나 한번이상 반복이기 때문에 -> {0,}
      + -> 앞의 문자가 반드시 한번이상 반복이기 때문에 -> {1,}
      ? -> 앞의 문자가 없거나 한개만 있음이기 때문에 -> {0,1}

      요롷게 됩니다...
      이해 안가시는 분들은 SHIFT+SPACE를 눌러 주세요 -_,-

      자 그럼....
      좀더 재미있는 것을 배워 볼까요?+_+/

      * a로 시작하여 d로 끝나는데...a와 d사이에는 bc가 두번에서 세번 나올수 있다

      위의 명제를 정규표현식으로 바꾸어 보도록 하죠...

      a로 시작하여 -> ^a
      d로 끝나는데 -> d$
      a와 d사이에는 bc가 두번에서 세번 나올수 있다 -> ?????? -_-a

      두번에서 세번은 {2,3}으로 하면 되겠는데...
      bc를 동시에 붙잡자니 막막 하시죠...

      이럴경우에 사용되는 것이 (와 )입니다. -_,-a알려드리는걸 깜박 했군요;;

      (bc) 요롷게 두개를 묶어주면...
      뒤에 붙을 {2,3}의 영향을 묶여서 받게 된다 그거죠...
      그러므로 (bc){2,3}과 같이 해주면...
      bc가 두번에서 세번 나온다가 됩니다.
      결국 완성된 식은....

      ^a(bc){2,3}c$

      이렇게 되겠죠...
      -_-a점점 결과물이 암호처럼 되어가는군요;;;

      허나...아직 우리가 배울것은 많이 남았습니다....


      * a로 시작하여 d로 끝나는데 b또는 c가 없거나 한번 나올수 있다

      후후 -_,- "없거나"... 요부분 걸리시죠?

      ^a    d$

      뭐 대충 요렇게는 짐작 하셨을 테고요...
      or의 역할을 하는 것으로 |이 있습니다.
      이거 어떻게 치느냐면요;;;-_-;;;
      키를 SHIFT를 누른채로 눌러 주시면 |가 이쁘게 나올겁니다;;;

      b또는 c라는 것은....

      b|c

      위와 같이 나타낼수 있다는 얘기죠...
      결국 표현식은...

      ^a(b|c)?d$

      이렇게 됩니다...
      (b|c)는 b또는 c가 되고...
      이를 ( )로 묶어서 ?를 붙여 주었는데요...
      b나 c중에 둘중 하나가 나오는데 ?가 있기 때문에..
      그것이 없을 수도 있고 한번 있을 수도 있다는 것이죠...

      물론 (b|c)?가 아닌 (b|c){0,1}와 같이 해주셔도 의미는 같습니다.


      * 세자로 이루어진 문자열

      -_-a이번문제는 좀 막막 하시죠;;;
      세자로 이루어졌다면야..
      {3} 요롷게 해주면 되겠는데...
      모든 문자열을 대상으로 하다보니...-_-a;;;

      이때 쓰이는 것은 . 입니다
      -_-a 쩜이죠......

      .는 정규표현식에서 어떤 한 문자열이라는 의미로 사용 되는데요...

      .{3}

      이렇게 하면 어떤 문자열이 세개가 있다는 것이되겠죠..
      그런데 위와 같이 하면...
      네자 또는 그 이상의 문자열도 모두 참이 됩니다...
      왜냐하면.....
      네자로 이루어진 문자열도 세자는 포함하고 있고...
      다섯자로 이루어진 문자열도 역시 세자 정도는 포함하고 있으니 말이죠..
      그렇기 때문에 딱 세자로만 이루어진 문자열을 표현하고자 한다면...
      아래와 같이 해주셔야 합니다.

      ^.{3}$

      왜 그래야만 하는지를 모르신다면...
      -_,- SHIFT+SPACE를...
       

      이렇게도 만들어 볼수가 있겠죠...

      * a로 시작하여 2~3개의 문자가 있고 c로 끝나는 문자열

      차근차근 살펴보죠....
      어려운건 아닙니다...

      a로시작하여 -> ^a
      2~3개의 문자가 있고 -> .{2,3}
      c로 끝나는 문자열 -> c$

      합쳐보면...

      ^a.{2,3}c$

      이렇게 됩니다...


      자 그럼 다음문제는...

      * 1부터 5까지중의 숫자로만 이루어진 문자열

      조금 난해하죠?;;

      먼저 1부터 5까지라면...
      (1|2|3|4|5)
      뭐 이렇게 하면 될까요...

      ^(1|2|3|4|5)$

      이렇게 해주면 1부터 5까지의 숫자중 하나의 숫자로
      이루어진 문자가 됩니다...맞죠?
      그런데 문제에서는 문자열이 될수 있다 하였으니...

      ^(1|2|3|4|5)+$

      이렇게 해주면 될것 같군요...
      +는 하나 또는 그 이상을 뜻하는 것이니...
      명제에 일치하는 식이 되겠죠...

      쉽네요^^
      그럼 다음 문제를 볼까요?

      * 영문소문자로만 이루어진 문자열

      -_-a;;;
      어쩌시렵니까...

      ^(a|b|c| 중간생략 |x|y|z)$

      뭐 이렇게 하실까요;;;

      -_,-이럴때 쓰는 간단한 방법이 있지요...

      이럴경우에 우리는 []를 사용하여...
      문자셋의 범위를 정해줄수가 있는데요...

      만약 0부터 5까지라고 하였다면...

      [0-5]

      이렇게만 해주면 됩니다.
      또한 영문소문자라면...

      [a-z]

      이렇게 되는거죠...
      결국 영문소문자로만 이루어진 문자열이라 하면...

      ^[a-z]+$

      이렇게 간단하게 끝나는 겁니다.
      쉽죠?^^

      아래 예제를 통해 어떤방식으로 []가 사용되는지 일단 살펴들 보시고요..

      [0-9] -> 0에서 9까지의 숫자
      [a-z] -> a에서 z까지의 소문자
      [A-Z] -> A에서 Z까지의 대문자
      [a-zA-Z] -> 소문자a부터 대문자Z까지
      [0-9a-z] -> 0에서 9까지 또는 a에서 z까지
      [0-9-] -> 0에서 9까지 또는 -
      [a-z_] -> a에서 z까지 또는 _

      위에서와 같이 []안에 포함되어 있는 문자 또는 범위에 대해
      어떤문자가 허용될 것인지를 정해줄수가 있는데요..
      만약 위에서와 같이 - 를 그 대상에 포함하려면...
      가장 처음이나 가장 마지막에 - 를 위치 시켜야만 합니다.


      * a,c,d,f중의 두문자로만 이루어진 문자

      답은?

      ^[acdf]{2}$

      이렇게 해도 된다는 것이죠...
      위의 정규표현식에는...
      aa,ac,dc,fa 모두 참이 됩니다.
      []안의 문자중에 있는 문자로 이루어진 2자의 문자열이면 모두 참이니까요..


      * 영문소문자 또는 숫자 또는 - 또는 _ 로만 이루어진 4자이상 12자 이하의 아이디


      이번 문제는 좀 복잡해 보이죠?
      뭐 근데 차근차근 보면 그리 어렵지 않을 겁니다...

      영문소문자 -> [a-z]
      또는 숫자 -> [a-z0-9]
      또는 -    -> [a-z0-9-]
      또는 _    -> [a-z0-9-_]

      그런데 이렇게 하면 에러 납니다-_-;;
      위에서 언급했듯이...
      -는 범위를 나타내는 기호가 되기 때문에...
      가장 처음이나 가장 끝에 위치 시켜야 합니다..
      그래서 아래와 같이 해주어야만 에러가 나지 않겠죠

      [a-z0-9_-]

      아래와 같이 해도 됩니다.

      [-a-z0-9_]

      4자이상 12자 이하이기 때문에...

      ^[a-z0-9_-]{4,12}$

      이렇게 되겠죠...
      위와 같은 정규표현식은...
      보통 회원아이디 가입시에 입력한 아이디의 형식을 체크할때 사용됩니다...

      <?
      $id="Navyism_1-1";
      echo eregi("^[a-z0-9_-]{4,12}$",$id);
      ?>

      위 소스를 실행해 보세요...
      결과는?-_,-

      어라 1이나오네요...-_-a이상하죠?
      분명 우리는 영문소문자를 허용하도록 해두었는데...
      $id에는 대문자 N이 있음에도 불구하고 TRUE값이 나왔습니다.

      왜 그랬을까요?

      문제는 eregi라는 함수에 있는것이죠...
      위에서 말씀드렸듯이..
      ereg는 대소문자를 구분하지만...
      eregi는 구분하지 않습니다.
      그렇기 때문에 우리는 정규표현식에 소문자를 허용하도록 해두었더라도
      함수 자체에서 그것을 무시해 보리기 때문에 이런 결과가 나오는 것이겠죠...

      <?
      $id="Navyism_1-1";
      echo ereg("^[a-z0-9_-]{4,12}$",$id);
      ?>

      위와 같이 eregi대신 ereg를 쓰시면 FALSE가 될겁니다.

      반대로 이메일주소나 홈페이지 주소와 같이...
      대소문자 구분이 필요 없을 경우에는 eregi함수를 사용하는 것이
      훨씬 더 유용하겠죠..
      굳이 정규표현식내에 대소문자를 모두 허용하도록 해줄 필요가 없을 테니 말이죠


      * a로 시작하고 c로 끝나면서 b를 포함하지 않는 4자의 문자열

      어떤 것들이 있을까요??

      aaac
      acdc
      adfc

      뭐 기타 등등 많겠죠...

      이번에 새로 등장한 부분은 무엇무엇을 포함하지 않는다 입니다.
      이것은 [^]로 표현할 수가 있는데요...

      [^와 ] 사이에 포함하지 않을 문자를 넣어 주면 됩니다.
      b를 포함하지 않는다고 하였으니...

      [^b]

      이렇게 해주면 되겠군요...

      a로 시작하고 -> ^a
      c로 끝나면서 -> ^ac$
      b를 포함하지 않으며 -> ^a[^b]c$
      4자의 문자열 -> ^a[^b]{2}c$

      a와 c가 각각 한자씩 모두 두자를 차지하고 있으니...
      b가 아닌 문자열은 두자가 되어 {2}를 적어준 것입니다.


      * 숫자를 포함하지 않는 문자열

      간단하죠?

      ^[^0-9]+$

      이렇게 됩니다...
      만약 앞의 ^과 뒤의 $를 적어주지 않는다면...

      1ab2

      위와 같은 문자열도 참이 됩니다.
      왜냐하면...

      [^0-9]+라는 것은...
      숫자가 아닌 문자가 한개 또는 그 이상이 있다는 것인데...

      1ab2안에는 ab라는...그 조건에 해당하는 문자가 포함되어 있기에
      결과는 참이 되는 것입니다.
      그것을 방지하기 위해...

      ^와 $를 넣어 처음부터 끝까지 라는 조건을 달아주면...

      1ab2 전체를 대상으로 보기 때문에...
      결과는 거짓이 되는 것이죠...


      * ?가 한개 또는 그이상 포함된 문자열

      문제에서....
      포함된 문자열이라는 것은...
      ^와 $를 사용할 필요가 없는다는 얘기 입니다.
      말 그대로 포함이기 때문에 그것이 문자열 전체가 아닐수도 있다는 것이죠.

      정답은?

      ?+

      이건가요?
      +는 한개 또는 그 이상을 말하기 때문에...
      ?가 한개 또는 그 이상이 있다 하였으니...
      ?+가 맞는것 같기는 한데...
      뭔가 좀 찜찜한 구석이 있죠...

      바로 ?가 그 자체로 없거나 한개 있을수 있다는 뜻을 갖고 있기 때문인데요..
      이렇게 정규표현식에 쓰이는 특수문자 자체를
      나타낼 때에는 를 앞에 붙여 escape 하도록 해줄수 있습니다.

      결국 위와 같이 ?+라고 하면 바로 에러 메세지를 만나실것 같고요...
      아래와 같이 를 사용하여 escape하자 그말이죠...

      ?+

      그 외에도...
      지금까지 정규표현식에 사용되었던...
      ^$[]().?+*{} 등의 문자들도 마찬가지로...
      그문자 자체를 나타내려면 앞에 를 붙여 주어야 합니다.
      반응형

      'Information' 카테고리의 다른 글

      전월세계약 6가지 포인트  (0) 2007.02.28
      용량계산기  (0) 2007.02.25
      JavaScript 키워드 정리  (0) 2007.02.24

      반응형

      'Information' 카테고리의 다른 글

      정규식  (0) 2007.02.27
      JavaScript 키워드 정리  (0) 2007.02.24
      JavaScript 모음  (0) 2007.02.23

      • 개체(Object) : 개체라는 말은 상당히 추상적이다. 이 개념을 알려면 "객체지향"을 공부해야 한다. 이 과에서 의미한 개체는 HTML 문서, 브라우저 윈도우, 날짜/시간과 같은 것을 의미하며 일반적으로 개체는 그 개체가 할 수 있는 일을 정의한 메소드와 그 개체의 특징을 나타내는 속성으로 구성된다.
        • date : date는 시스템의 날짜와 시간을 얻기 위한 개체이다. 이 개체를 생성하는 방법은 다음과 같다 :

      Nameofobject = new Date();
        • document : 이것은 해당 자바스크립트를 포함하고 있는 HTML 문서를 참조할 수 있는 개체를 의미한다.
        • history : history는 사용자가 방문했던 페이지를 기억하고 있는 개체이다. history 리스트의 크기는 특정 서핑 세션동안 사용자가 얼마나 많은 페이지를 방문했는지에 따라 틀릴 수 있다.
        • location : location은 특정 URL을 지칭하는 개체이다. 다음과 같은 형식으로 사용된다:

       

      parent.location='index.html'
      (location이란 속성도 있는데 사용법이 서로 틀리다는 것을 기억하기 바란다.)
        • navigator : navigator는 사용자의 브라우저를 지칭하는 개체이다. 이 개체를 통해 사용자 브라우저에 대한 간략한 정보를 얻을 수  있다.
        • window : window는 브라우저 화면을 참조할 수 있는 개체이다.
      • 메소드(Method) : 메소드는 어떤 개체로 하여금 어떻게 행동할지를 알려주는 하나의 명령을 의미한다.
        • alert() : alert는 window 개체 또는 하이퍼텍스트 링크내에서 대화 상자를 만들기 위해 사용되는 메소드이다. alert문의 괄호 안에 있는 텍스트를 대화 상자에 보여주고 OK 버튼이 함께 제공되며 사용자가 계속 진행하기 위해서는 이 버튼을 눌러야만 한다.
        • charAt() : (문자열 변수).charAt(i)를 하면 (문자열 변수)의 i번째 있는 값을 반환해 주는 메소드이다. 이 때 주의할 것은 i는 0부터 시작된다는 것이다. 예를 들어, zip이란 변수에 "123-456" 값이 들어 있다면 zip.charAt(0)은 "1"이고, zip.charAt(3)은 "-"이다.
        • clearTimeout() : Window 개체의 메소드로 실행되고 있는 setTimeout() 설정을 해제시켜준다.
        • close() : close는 window 개체의 메소드로 현재 브라우저 윈도우를 닫는다.
        • confirm() : confirm은 "확인"과 "취소" 버튼이 있는 대화 상자를 사용자에게 보여주는 메소드이다. 이 메소드는 대개 if...else문에서 주로 사용된다.
        • getMonth() : Date 개체의 메소드로 현재 월을 0~11 사이의 숫자로 반환한다.
        • getDate() : Date 개체의 메소드로 현재 날짜를 1~31 사이의 숫자로 반환한다.
        • getYear() : Date 개체의 메소드로 현재 연도를 0~99 사이의 숫자로 반환한다. (인터넷 익스플로러 5 이상에서는 4자리 숫자를 반환한다)
        • getFullYear() : Date 개체의 메소드로 현재 연도를 네자리 숫자로 반환한다. (넷스케이프 4.0 이상, 인터넷 익스플로러 3.x 이상에서 사용할 수 있다)
        • getDay() : Date 개체의 메소드로 현재 요일을 1~7 사이의 숫자로 반환한다.
        • getHours() : Date 개체의 메소드로 현재 시간을 0~23 사이의 숫자로 반환한다.
        • getMinutes() : Date 개체의 메소드로 현재 분을 0~59 사이의 숫자로 반환한다.
        • getSeconds() : Date 개체의 메소드로 현재 시간을 0~59 사이의 숫자로 반환한다.
        • indexOf() : (문자열 변수).indexOf(strVal)를 하면 (문자열 변수)에서 strVal이란 값을 찾아 그 값의 위치를 반환해 주는 메소드이다. 물론 그 위치는 0부터 시작된다. 예를 들어, zip이란 변수에 "123-456" 값이 들어 있다면 zip.indexOf("-")은 3을 반환한다.
        • open() : open은 window 개체의 메소드로 새로운 문서 또는 새로운 윈도우를 열어 준다.
        • prompt() : Prompt는 사용자가 데이터를 입력할 수 있도록 팝업 상자를 보여 주는 메소드이다. 사용자가 입력한 데이터를 활용하기 위해 prompt는 항상 그 결과 값을 변수에 담게 된다.
        • setTimeout() : Window 개체의 메소드로 타이머를 설정하고 일정 시간이 경과한 후 특정 명령 또는 함수를 실행시켜준다. setTimeout은 두 개의 인자를 취한다. 첫 번째는 일정 시간이 지나고 실행될 명령이나 함수를 문자열로 넘겨주는 것이고, 두 번째는 특정 명령을 실행 시킬 시간 주기를 밀리 초(mili seconds) 단위로 넘겨주는 것이다.
        • Write() : Write 메소드는 Document 개체가 웹 페이지 상에 텍스트를 표시할 수 있도록 해주는 메소드이다.
      • 반복(Loop) : 기본적으로 두 가지의 반복문이 있다. 하나는 "for"문이고 또 하나는 "while"문이다. for문은 일반적으로 반복 횟수를 알고 있을 때 사용하고, while 문은 반복 횟수를 알지 못할 때 사용한다.
        • for : 반복문이 몇 번 반복되어야 할지를 구체적으로 명시할 수 있는 명령어이다.
        • while : 반복문이 몇 번 반복되어야 할지를 구체적으로 명시할 수 없을 때 사용하는 명령어이다.
      • 배열(Array) : 일반적으로 변수는 한 번에 하나의 값만 저장할 수 있다. 하지만 때에 따라 여러 값을 가지고 있는 변수들의 집합을 이용해야할 때가 있다. 배열은 각각의 값을 가진 여러 변수들의 집합체라고 보면 된다.
      • 변수(Variable) : 변수는 데이터를 담을 수 있는 저장 공간이다. 상수(constant)는 값이 변할 수 없지만 변수는 그 안에 저장된 데이터 값이 바뀔 수 있다. 변수를 사용하면 여러 라인의 코드 결과를 한 단어의 변수로 표현할 수 있다. 예를  들어, document.write("오늘은 " + objDate.getYear() + "년 " + objDate.getMonth() + "월 " + objDate.getDate() + "일입니다.")라는 것을 웹 페이지 내에서 10번 이상 반복해서 작성해야 한다면 정말 번거로울 것이다. 이 때 "오늘은 " + objDate.getYear() + "년 " + objDate.getMonth() + "월 " + objDate.getDate() + "일입니다." 부분을 변수로 저장해 놓고 사용하면 훨씬 간편해 진다. 즉, strToday = "오늘은 " + objDate.getYear() + "년 " + objDate.getMonth() + "월 " + objDate.getDate() + "일입니다." 와 같은 형식으로 사용한다는 것이다.
        • 전역 변수(Global Variable) : 자바스크립트에서 전역 변수는 함수의 외부에 선언된 변수를 의미한다. 이 전역 변수는 어디서든 참조할 수가 있다. 만일 어떤 변수를 함수 내부에서 선언했다면 그 변수는 그 함수 내부에서만 사용할 수 있다.
      • 속성(Properties) : 속성은 개체의 한 특징 또는 그 개체의 일부를 의미한다. 예를 들어 브라우저 윈도우의 상태 표시줄은 window 개체의 속성이며 windows.status로 참조된다. (표시형식 : 개체이름.속성이름)
        • alinkColor : alinkColor는 document 개체의 속성이다. 이 alinkColor(active Link Color)속성은 하이퍼텍스트 링크가 활성화될 때 또는 클릭되는 순간의 색상을 나타내는 속성이다.
        • appCodeName : appCodeName는 navigator 개체의 속성이다. 이 속성은 브라우저 제조사에 의해 사용된 브라우저 코드 네임을 의미한다.
        • appName : appName은 navigator 개체의 속성이다. 이 속성은 Netscape 또는 Explorer와 같은 브라우저의 이름을 의미한다.
        • appVersion : appVersion은 navigator 개체의 속성이다. 이 속성은 브라우저의 플랫폼과 버전을 의미한다.
        • bgColor : bgColor는 document 개체의 속성으로 HTML 문서의 배경색을 의미한다.
        • defaultStatus : defaultStatus는 window 개체의 속성으로 window.status와 마찬가지로 브라우저의 상태표시줄을 의미한다. window.status는 HTML 태그의 이벤트 핸들러와 밀접하게 사용된다면 defaultStatus는 HTML 태그 밖에서 사용하게 된다. 최신 브라우저에서는 큰 차이점 없이 사용할 수 있기도 하다.
        • fgColor : fgColor는 document 개체의 속성으로 전경색 또는 텍스트 색상을 의미한다.
        • host : host는 location 개체의 속성이다. 이 속성은 텍스트 형식 또는 IP 번호 형식으로 호스트의 URL을 알려 준다. hostname 속성과의 차이점은 포트(port) 정보까지 알려준다는데 있다. 만일 어떤 페이지의 주소가 "http://korea.internet.com/channel/content.asp?nid=12804"라면 이 페이지의 호스트는 korea.internet.com이 된다(포트가 있다면 포트 정보까지 나타난다). 만일 포트가 null이거나 서버에게 있어서 포트가 중요하지 않다면 hostname과 동일한 결과를 제공한다.
        • hostname : hostname은 location 개체의 속성이다. 이 속성은 포트(port) 정보가 없다는 것을 빼고는 host 속성과 동일하다.
        • lastModified : lastModified 속성은 document 개체의 속성이다. 이 속성은 해당 웹 페이지가 마지막으로 서버에 업데이드된 날짜/시간 또는 마지막으로 디스크에 저장된 날짜/시간을 알려 준다.
        • length : length 는 history 개체의 속성이다. 이 속성은 브라우저의 history 파일에 있는 페이지 리스트 갯수를 알려 준다. 즉, 사용자가 현재 페이지를 방문하기 전에 방문했던 페이지들의 리스트 갯수이다.
        • linkColor : linkColor는 document 개체의 속성이다. 이 속성은 하이퍼텍스트 링크의 색상을 의미한다.
        • location : location은 document 개체의 속성이다. 이 속성은 웹 페이지의 URL을 의미한다. location이란 개체도 존재하는데 작동하는 방식이 다르다는데 주의해야 한다.
        • name : name은 개체에 붙여준 이름 속성이다. 예를 들어 <IMG> 태그에 name 속성을 부여했다면 문서 내에서 이 이미지를 참조하고 싶을 때에는 name 속성에 부여한 이름을 참조하면 된다. 즉, <IMG src="aaa.gif name="pic1">이라고 했다면 이 이미지에 대한 접근은 document.pic1로 할 수 있다는 것이다.
        • parent : parent는 특별히 프레임과 함께 자주 사용되는 속성으로 특정 프레임을 가리킬 때 사용된다. 만일 프레임 밖에서 사용된다면 브라우저 전체 윈도우를 가리키게 된다.
        • referrer : referrer는 document 개체의 속성이다. 사용자가 어떤 페이지에서 현재 페이지로 왔는지를 알려주는 속성으로 바로 전 페이지의 URL을 알려 준다.
        • self : self는 현재 윈도우를 의미하는 속성이다.
        • status : status는 window 개체의 속성으로 브라우저 화면의 왼쪽 하단에 위치한 상태 표시줄을 의미한다.
        • target : HREF 텍스트 링크와 함께 사용되며 링크로 걸린 사이트가 어떤 윈도우에 나타나야 할지를 표시해주는 속성이다.
        • title : title은 document 개체의 속성이다. 이 속성은 HTML 문서에서 <TITLE>과 </TITLE>태그 사이에 위치한 텍스트를 알려 준다.
        • userAgent : userAgent는 navigator 개체의 속성이다. 이 속성은 웹 서버에게 필요한 HTTP 헤더 정보를 알려 준다.
        • value : Value는 특정 시점에 어떤 내용이 들어있을 수도 있고 아닐 수도 있는 값 속성으로 생각하면 된다. 예를 들어, 체크박스(checkbox)는 사용자의 클릭에 따라 "on" 또는 "off" 값을 가질 것이다. 텍스트 필드의 경우 사용자가 입력한 값이 있을 수도 있고 없을 수도 있다. 만일 텍스트 필드에 있는 내용을 사용자에게 보이고 싶지 않다면 그 값을 "hidden"으로 할 수도 있다. 여기서 강조하는 것은 폼 개체의 특정 필드에 대한 값을 참조할 때는 Value 속성을 사용해야 한다는 것이다. 이 Value 속성이 중요한 것은 다른 곳에서도 이 값을 사용할 수 있기 때문이다.
        • vlinkColor : vlinkColor(visited Link Color)는 document 개체의 속성이다. 이 속성은 사용자가 방문했던 링크에 대한 하이퍼텍스트 링크 색상을 의미한다.
      • 에러(Error) : 에러 또는 오류 메시지 창은 스크립트 안에 뭔가 문제가 있을 경우 발생한다. 크게 두 가지 종류가 있는데 구문(Syntax) 오류와 런타임(RunTIme) 오류이다.
        • 구문 오류(Syntax Error) : 스크립트 안에 잘못된 철자가 있거나 컴퓨터가 인식하기 어려운 텍스트가 있을 경우, 자바스크립트 문법에 어긋난 경우 발생한다.
        • 런타임 오류(Run-Time Error) : 런타임 오류는 잘못된 자바스크립트 명령어를 사용했을 때 발생한다.
      • 이벤트 핸들러(Event Handlers) : 이벤트 핸들러는 HTML 코드에 내장되는 자바스크립트 명령어다. 사용자와 웹 페이지 사이의 상호 작용을 위해 HTML 코드와 함께 사용된다.
        • onBlur : onBlur는 사용자가 select, text, textarea 폼 요소에 있다가 그 요소에서 벗어나게 될 때 발생하는 이벤트 핸들러이다. 즉, 사용자가 그 아이템에 대한 포커스를 잃을 때 발생한다.
        • onChange : onChange는 사용자가 select, text, textarea 폼 요소에 있는 텍스트를 변경한 후 그 요소를 떠날 때 발생하게 된다.
        • onClick : onClick은 사용자가 링크와 같은 오브젝트를 클릭할 때 발생한다.
        • onFocus : onFocus는 사용자가 select, text, textarea 폼 요소를 선택할 때 발생한다. 즉 사용자가 그 폼 요소에 포커스를 맞출 때 발생한다.
        • onLoad : onLoad는 웹 페이지가 열릴 때 발생하는 이벤트로 HTML의 BODY 태그 안에서 사용된다.
        • onMouseOut : onMouseOut은 사용자가 마우스를 링크 위에 올려 놓았다가 떼는 순간에 발생하는 이벤트 핸들러이다.
        • onMouseOver : onMouseOver는 사용자가 링크 위에 마우스를 올려 놓았을 때 발생하는 이벤트 핸들러이다.
        • onSelect : onSelect는 사용자가 text, textarea 폼 요소에 있는 텍스트의 일부 또는 전체를 선택할 때 발생한다.
        • onSubmit : onSubmit은 submit 버튼 폼 요소를 사용자가 틀릭할 때 발생한다.
        • onUnLoad : onUnload는 사용자가 웹 페이지를 떠날 때 발생하는 이벤트로 HTML의 BODY 태그 안에서 사용된다.
      • 조건(Condition) : 조건은 IF 문과 함께 발견된다. 조건은 IF문 바로 다음에 나오는 괄호 안에 있는 내용을 일컫는다. IF 문에 있는 조건이 참일 때 IF 문에 있는 내용이 실행되고 거직일 때 ELSE문에 있는 내용이 실행된다.
      • 주석(Comment) : 주석은 더블 슬래쉬(//)로 표시한다. 주석 처리하고 싶은 텍스트의 왼쪽 옆에 "//" 표시를 해주면 된다. "//"는 // 표시의 오른 쪽에 있는 라인 전체를 주석 처리하는 것이다. 만일 주석 처리하고 싶은 줄이 여러 줄이라면 // 대신 시작을 "/*"로 끝을 "*/"로 막아 주면 된다. 즉, /*와 */ 사이에 있는 모든 내용이 주석 처리 된다는 것이다.
      • 컴마(comma : ",") : 자바스크립트 이벤트 핸들러를 동시에 여러 개 사용하고자 할 때 컴마(,)를 사용한다.
      • 특성(Features) : 특성(Features)은 자바스크립트 명령어의 어떤 속성들을 나타낸다. 가장 흔한 예는, 툴바(toolbar), 메뉴바(menubar), 스크롤바(scrollbars) 등의 특성들인데 , 이 특성들을 통해 새로운 윈도우의 모양, 크기 등을 조절할 수 있다.
        • config : config는 window.open() 메소드에서 사용되는 명령어로 이 다음에 새로 열릴 창의 특성들을 적어주면 된다.
        • directories : 연결 표시줄 유무를 결정하는 특성으로 가질 수 있는 값은 "yes" 또는 "no"이다.
        • height : 새로운 윈도우 또는 이미지의 높이를 픽셀로 표시한다.
        • location : 주소 표시줄 유무를 결정하는 특성으로 가질 수 있는 값은 "yes" 또는 "no"이다.
        • menubar : 메뉴바 유무를 결정하는 특성으로 가질 수 있는 값은 "yes" 또는 "no"이다.
        • resizable : 사용자가 윈도우의 크기를 조절할 수 있는지의 유무를 결정하는 특성으로 가질 수 있는 값은 "yes" 또는 "no"이다.
        • scrollbars : 스크롤바 표시 유무를 결정하는 특성으로 가질 수 있는 값은 "yes" 또는 "no"이다.
        • status : 상태 표시줄 유무를 결정하는 특성으로 가질 수 있는 값은 "yes" 또는 "no"이다.
        • toolbar : 표준 단추(툴바) 표시 유무를 결정하는 특성으로 가질 수 있는 값은 "yes" 또는 "no"이다.
        • width : 새로운 윈도우 또는 이미지의 폭을 픽셀로 표시한다.
      • 파라미터(parameter) : 함수의 입력 값을 의미하며 인자(아규먼트, argument) 또는 매개변수라고도 한다. 가령, function newcolor(color)라는 함수가 있을 때 color를 파라미터라고 부른다. 파라미터의 갯수는 원하는 대로 정의할 수 있다. 단, 그 갯수만큼 함수를 호출하는 쪽에서 그에 대응하는 실제 값을 넣어줘야 한다.
      • 함수(function) : 함수는 일련의 명령어들을 조합하여 원하는 역할, 기능을 담당하게 하는 것이다. 계속해서 반복되는 작업들을 함수로 만들어 놓음으로써 그런 기능이 필요할 때마다 여러 줄의 명령어들을 다시 작성하는 것이 아니라 함수를 한 번만 호출하여 원하는 결과를 얻을 수 있다.
        • eval() : eval()이란 함수는 텍스트를 숫자로 변경할 때 사용한다. prompt를 통해 사용자로부터 숫자를 입력받았을 때 그것은 문자로 인식될 수 있다. 이 때 eval()을 통해 확실히 숫자로 인식되도록 할 수 있다.
        • if...else 문 : If와 else는 사용자의 선택에 따라 서로 다른 행동을 할 수 있도록 한 조건문이다. if문은 조건 값이 참(true) 또는 예(yes)일 때 반응하고, else는 조건 값이 거짓(false) 또는 아니오(no)일 때 반응한다.

      반응형

      'Information' 카테고리의 다른 글

      용량계산기  (0) 2007.02.25
      JavaScript 모음  (0) 2007.02.23
      [팁] .NET 로딩페이지 구현하기  (0) 2007.02.23
      /*
      Text
      jsChangeComma( str ) ' -> ` 로 대치
      jsStrCheck(checkStr, checkOK)
        들어가서는 안되는 데이타(checkOK)가 checkStr에 포함되어있는지 체크
      jsMoveFocus( varTextObj, varLength, varFocusToObj )
        TextBox에서 조건이 만족하면 특정객체로 포커스를 이동
      jsCheckNull( toCheck ) toCheck의 값이 Null값인지를 체크
      jsDeleteComma( varNumber ) 컴마를 삭제하고 리턴
      jsDeleteChar( varText, varDelete ) 문자열에서 해당 character를 지우고 리턴
      CheckBox
      jsCheckBoxSelectedCnt( FormObj, checkBoxName )
        FormObj에서 checkBox 가 몇개 선택되었는지  리턴한다.
      jsToggle(FormObj, elemNm, checkYn)
        특정 폼안의 체크박스오브젝트를 전체선택하거나 전체반전시킴
       
      SelectBox
      jsCheckSelectBox ( sb ) SelectBox에서 선택된 값의 value를 리턴
      jsCheckSelectBoxNm ( sb ) SelectBox에서 선택된 값의 Text를 리턴
      cmInitSelectBox( varObjFullNm, varDeleteCnt )
        해당 SelectBox를 초기화 시킨다. varDeleteCnt가 1이면 첫번째값을 지우지 않는다.
      cmMakeSelectBox( varObjFullNm, varText, varValue ) 해당 selectBox에 하나의 값을 추가시킴
         
      날짜 
      jsCheckYYYY(toCheck) 년도를 체크
      jsCheckYYYYMM(toCheck) 년월을 체크
      jsCheckMM(toCheck) 월을 체크
      jsCheckDD(yyyy,mm,toCheck) 일을 체크
      jsCheckDate( dateVal ) 날짜를 체크
      jsAddYear( startDt, plusYear ) 날짜에 년수를 더함
      jsAddMonths( startDt, plusMonth ) 날짜에 월수를 더함
      jsGetBetweenDay( startDt, endDt ) 날짜와 날짜사이의 일수를 리턴
      jsCheckTime( toCheck ) 시간포맷인지를 체크
      jsMakeYyyyMm( varTextObj )
        해당 텍스트박스 객체필드에 YYYY/MM형식으로 [/]를 찍어서 채워준다.
      jsMakeYyyyMmString( varText ) 넘어온 값에 날짜형식으로 [/]를 찍어서 리턴.
      jsMakeDate( varTextObj ) 넘어온 Object의 값을 날짜형식으로 채워줌
      jsMakeDateString( varText )넘어온 값을 날짜형식으로 리턴
      toTimeString( varDateObj ) DateObj를 넘겨주면 년월일을 리턴  20030201
      jsAfterThisDate( varStdDate , varYYYY , varMM , varDD )
        날짜형식의 문자열에 특정 년, 월, 일을 더한값을 리턴

      날짜 체크 사용 예 호출하는 페이지에 다음 부분을 추가
      <input ... omKeyUp='jsChkDate(this,lottSearchForm.txtEdate)' omBlur='compareDate()'>
       
      function compareDate(){  
       if( jsCheckNull(document.forms[0].txtSdate.value) ||
           jsCheckNull(document.forms[0].txtEdate.value) )
           return;
       
       var from = document.forms[0].txtSdate.value.replace(/(,|.|-|/|:)/g,'');
       var to   = document.forms[0].txtEdate.value.replace(/(,|.|-|/|:)/g,'');
       if( jsGetBetweenDay(from,to) < 0 ) {
        alert("기간이 잘못 입력되었습니다. 다시입력하세요");
        document.forms[0].txtSdate.value = "";
        document.forms[0].txtEdate.value = "";
        document.forms[0].txtSdate.focus();
        return ;
       }
      }
      function jsChkDate( valObj, nextPos ){
       if( valObj.value.length == 8 ) {
        if( !jsCheckDate( valObj.value ) ) {
         alert("일자 입력오류입니다. 다시 입력해 주십시요.");
         valObj.value = '';
         valObj.focus();
         return;
        } 
        jsMakeDate( valObj );
        nextPos.focus();
       }
      }
                  
        
      주민등록번호
      jsCheckJumin(toCheck) 주민등록번호 체크
      사업자등록번호
      jsCheckSaupJa(toCheck) 사업자등록번호 체크
      문자열길이 체크
      getByteLength(s) 한글2바이트, 영문 1바이트로 바이트수를 리턴
      쿠키
      setCookie( name, value, expireFlag ) Set Cookie
      getCookie( name ) get Cookie
      숫자
      jsParseInt( varStr ) 문자를 숫자로 변환 null일때
      jsConvertNumberToHangul( varNum ) 숫자를 한글로 변환
      jsMakeCurrency( varTextObj ) 넘어온 숫자에 컴마를 찍어서 리턴 소숫점 허용안함
      jsMakeForeignCurrency( varTextObj ) 넘어온 숫자에 컴마를 찍어서 리턴 소숫점 허용함
      jsOnlyNumber( varTextObj ) 해당 텍스트박스 객체에 숫자만 입력받을수 있도록
      jsOnlyFloat( varTextObj ) 해당 텍스트박스 객체에 숫자와 1개의 point만을 입력받게 해준다.
      jsAddComma( varNumber )
        숫자를 받아서 comma를 찍어서 리턴한다 소수점 인식 숫자가 아닌값 -1을 리턴 음수표현가능
      jsAddCommaAndZero( varNumber )
        숫자를 받아서 comma를 찍어서 리턴한다 소수점 인식 숫자가 아닌값 -1을 리턴 음수표현 불가능
      jsCheckFloat(toCheck) Folat형인지를 체크 정수도 Float으로 인식
      jsCheckPoint( toCheck , Positive , Negative ) 자리수 체크 정수 몇자리 소수 몇자리
      jsCheckNumber(toCheck) Number타입인지 체크, 소수점은 Number타입으로 인식하지 않음 
      getCutNumber(num, place) 소수점 아래 몇자리 이하 절삭
      jsOnlyNumberKey() text 입력시 숫자이외의 키를 눌렀을때 무효화시킨다.
      jsCheckFloatType( varNum, varLeft, varRight ) 정수부분자리수 소수부분자리수 체크 
       
      기타
      jsSplitCode(varString, varSplitChar, varIndex) 구분자로 구분해서 index의 문자를 리턴
      jsCheckIp(toCheck) toCheck값이 정확한 IP Address인지 체크
      jsCheckEmail( emailVal ) 이메일을 체크 - 보완요망
      jsShowHelp( helpfile ) helpfile를 팝업으로 오픈
      jsGetObjCnt( FormObj, varObjName ) 특정폼에서 해당오브젝트가 몇개인지를 리턴
      jsClearFrame( fr ) 특정프레임에 공백 jsp를 띄워줌
      jsDeleteCharAll( FormObj )
        해당 폼에 해당하는 모든 오브젝트의 값들에서 ',' and '/'문자를 지워준다.   
      isAlphaNum(input) 영문과 숫자로만 이루어졌는지를 체크
      IsHangul(field) 입력값에 한글이 있는지 체크
      containsCharsOnly(input,chars) 입력값이 특정 문자(chars)만으로 되어있는지 체크
      popup1( varAction, varWinName, varWidth, varHeight ) 팝업을 호출
      jsBack() 이전 페이지로 이동
      jsVisible( str ) 특정조건에 해당하면 모래시계를 보여줌
      jsRunAfterTime() 설정한 시간뒤에 특정 function을 호출
      trim(text) ltrim(text) rtrim(text) text의 좌우측, 좌측, 우측의 공백을 제거해서 리턴
      */

      /*--------------------------------------------------
        기능   : Cookie Setting
        INPUT  : name, value
                 expireFg : 'Y' : 2020년 까지 쿠키저장
                 expireFg : 'N' : session이 끊어질때 쿠키지움
        RETURN : NONE
      ----------------------------------------------------*/
      function setCookie( name, value, expireFg ) {
          var expireDate = new Date ( 2020, 1, 1, 1, 1, 1 ) ;
          if ( expireFg = 'Y' )
              document.cookie = name + "=" + value + "; expires=" + expireDate.toGMTString() ;
          else
              document.cookie = name + "=" + value + ";" ;
      }
      /*--------------------------------------------------
        기능   : Cookie Get
        INPUT  : name
        RETURN : 쿠키값( 없으면 "" )
      ----------------------------------------------------*/
      function getCookie( name ) {
          var cookieFound = false ;
          var start = 0 ;
          var end   = 0 ;
          var cookieString = document.cookie ;
          var i = 0 ;
          // name에 해당되는 cookie를 찾는다.
          while ( i <= cookieString.length ) {
              start = i ;
              end = start + name.length ;
              if ( cookieString.substring( start, end ) == name ) {
                  cookieFound = true ;
                  break ;
              }
              i++ ;
          }
          // cookie를 찾았으면 해당하는 값을 그렇지 않으면 ""을 return ;
          if ( cookieFound ) {
              start = end + 1 ;
              end   = document.cookie.indexOf(";",start) ;
              if ( end < start )
                  end = document.cookie.length ;
              return document.cookie.substring( start, end ) ;
          }
          return "" ;
      }
      /*-----------------------------------------------
       ' ->문자를 쿼리문에 사용시 에러가 발생하므로 `로 대치
       INPUT  : str
       RETURN : 문자열안의 문자중 ' 문자를 ` 로 변경한 문자열
      -------------------------------------------------*/
      function jsChangeComma( str ){
       while( str.indexOf("'") != -1 ){
        str = str.replace("'","`");
       }
         return str;
      }
      /*----------------------------------------------------------
        기능   : Split Code RETURN Splited code by varSplitChar
        INPUT  : varString 문자
           : varSplitChar 구분자
         : varIndex 구분자의 위치
        RETURN : Splited code by varSplitChar
        예     : jsSplitCode( "111^222^333", "^", 2 ) == "222"
      -----------------------------------------------------------*/
      function jsSplitCode(varString, varSplitChar, varIndex) {
       var varArray = varString.split(varSplitChar) ;
       return varArray[eval(varIndex)-1];
      }
      /*--------------------------------------------------
        기능   : Check Null RETURN T/F
        INPUT  : check  data
        RETURN : true  -> NULL
                 false -> NOT NULL
      ----------------------------------------------------*/
      function jsCheckNull( toCheck )
      {
           var chkstr = toCheck + "";
           var is_Space = true ;
           if ( ( chkstr == "") || ( chkstr == null ) )
          return( true );
           for ( j = 0 ; is_Space && ( j < chkstr.length ) ; j++)
           {
            if( chkstr.substring( j , j+1 ) != " " )
               {
              is_Space = false ;
               }
           }
           return ( is_Space );
      }
      /*--------------------------------------------------
        기능   : Check IP address RETURN T/F
        INPUT  : toCheck  -> check data
        RETURN : true  -> IP address
                 false -> not IP address
      ----------------------------------------------------*/
      function jsCheckIp(toCheck)
      {
           var chkstr = toCheck+"" ;
           var isIp = true ;
           if ( jsCheckNull(toCheck) )
                return false;
           for (j = 0 ; isIp && (j < toCheck.length) ; j++)
           {
                if ((toCheck.substring(j,j+1) < "0") || (toCheck.substring(j,j+1) > "9"))
                {
                    if ( toCheck.substring(j,j+1) == "." )
                        if ( j == 0 )
                            isIp = false ;
                    else
                        isIp = false ;
                }
           }
           return isIp;
      }
      /*--------------------------------------------------
        기능   : Check Number RETURN T/F ( 소수점"."은 Number로 취급안함 )
        INPUT  : toCheck  -> check data
        RETURN : true  -> number ( "."이 포함안됨 )
                 false -> not number
      ----------------------------------------------------*/
      function jsCheckNumber(toCheck)
      {
           var chkstr = toCheck+"" ;
           var isNum = true ;
           if ( jsCheckNull(toCheck) )
                return false;
           for (j = 0 ; isNum && (j < toCheck.length) ; j++)
           {
                if ((toCheck.substring(j,j+1) < "0") || (toCheck.substring(j,j+1) > "9"))
                {
                   if ( toCheck.substring(j,j+1) == "-" || toCheck.substring(j,j+1) == "+")
                   {
                      if ( j != 0 )
                      {
                         isNum = false;
                      }
                   }
                   else
             isNum = false;
           }
           }
           if (chkstr == "+" || chkstr == "-") isNum = false;
           return isNum;
      }
      /*--------------------------------------------------
        기능   : Check data RETURN T/F
        INPUT  : toCheck  -> check data
                 checkOK  -> 들어가서는 안되는 data
        RETURN : false -> 들어가서는 안되는 data가 없다
                 true  -> 들어가서는 안되는 data가 있다.
        예1    : jsStrCheck( '12345', 'ABab' )
                 string '12345'에는 'ABab'가 없으므로
                 false를 리턴
        예2    : jsStrCheck( '12$45', 'ABab$#%' )
                 string '12$45'에는 '$'가 있으므로
                 true를 리턴
      ----------------------------------------------------*/
      function jsStrCheck(checkStr, checkOK) {
          for (i = 0; i < checkStr.length; i++) {
              ch = checkStr.charAt(i);
              for (j = 0; j < checkOK.length; j++)
              if (ch == checkOK.charAt(j))
                 break;
              if (j == checkOK.length) {
                      return false;
                      break;
              }
          }
          return true;
      }
      /*--------------------------------------------------
        기능   : Check Float RETURN T/F (정수도 Float로 취급)
        INPUT  : toCheck  -> check data
        RETURN : true  -> number
                 false -> not number
      ----------------------------------------------------*/
      function jsCheckFloat(toCheck)
      {
           var chkstr = toCheck+"" ;
           var isFloat = true;
           var chkPoint = false;
           var chkMinus = false;
           if ( jsCheckNull(toCheck) )
           {
                 return false;
           }
           for (j = 0 ; isFloat && (j < toCheck.length); j++)
           {
               if ( (toCheck.substring(j,j+1) < "0") || (toCheck.substring(j,j+1) > "9"))
               {
                  if ( toCheck.substring(j,j+1) == "." )
                  {
                     if ( !chkPoint ) chkPoint = true ;
                     else  isFloat = false ;
                  }
                  else if ( toCheck.substring(j,j+1) == "-" || toCheck.substring(j,j+1) == "+")
                  {
                     if ( ( j == 0 ) && ( !chkMinus ) ) chkMinus = true ;
                     else isFloat = false;
                  }
                  else isFloat = false;
              }
          }
          return isFloat;
      }
      /*--------------------------------------------------
        기능   : 자릿수 check RETURN T/F
        INPUT  : toCheck  -> check data
        RETURN : true  -> number
                 false -> not number
      ----------------------------------------------------*/
      function jsCheckPoint( toCheck , Positive , Negative )
      {
           var strPos = toCheck + "" ;
           var isPoint = true ;
           if ( jsCheckFloat ( toCheck ) )
           {
               var inx = strPos.indexOf(".") ;
               if ( inx == -1 )
               {
                    if ( strPos.length > parseInt(Positive) )
                       isPoint = false ;
                    else
                       isPoint = true ;
                }
                else
                {
                     var pos = strPos.substring( 0, inx ) ;
                     var nev = strPos.substring(inx + 1) ;
                     if ( pos.length > parseInt(Positive) )
                           isPoint = false ;
                     else if ( nev.length > parseInt(Negative) )
                           isPoint = false ;
                     else
                           isPoint = true ;
                }
            }
            else if ( jsCheckNumber (toCheck) )
                  isPoint = true  ;
            else
                  isPoint = false ;
            return isPoint ;
      }
      ////////////////////////////////////////////////////////////////n
      ////////////    DATE  VALIDATION  CHECK    //////////////////////
      /////////////////////////////////////////////////////////////////
      /*--------------------------------------------------
        기능   : calender에서 사용할 월별 배열를 만든다.
        INPUT  : 각 인자의 값
      ----------------------------------------------------*/
      function jsMonthArray(m0,m1,m2,m3,m4,m5,m6,m7,m8,m9,m10,m11)
      {
            this[0] = m0;
            this[1] = m1;
            this[2] = m2;
            this[3] = m3;
            this[4] = m4;
            this[5] = m5;
            this[6] = m6;
            this[7] = m7;
            this[8] = m8;
            this[9] = m9;
            this[10] = m10;
            this[11] = m11;
      }

      /*--------------------------------------------------
        기능   : 년도를 check한다.
        INPUT  : toCheck
        RETURN : NONE
           MSG :
      ----------------------------------------------------*/
      function jsCheckYYYY(toCheck)
      {
         return ( ( toCheck.length == 4) && ( jsCheckNumber(toCheck)  ) && ( toCheck != "0000") );
      }
      /*--------------------------------------------------
        기능   : 년월을 check한다.
        INPUT  : toCheck
        RETURN : NONE
           MSG :
      ----------------------------------------------------*/
      function jsCheckYYYYMM(toCheck)
      {
           var isDate  = true ;
           if ( toCheck.length != 6 )
           {
                isDate = false ;
           }
           else
           {
                 var yy = toCheck.substring(0,4) +"" ;
                 var mm = toCheck.substring(4,6) +"" ;
                 if ( !jsCheckYYYY(yy) )
                    isDate = false ;
                 else if ( !jsCheckMM(mm) )
                    isDate = false ;
           }
           return isDate ;
      }
      /*--------------------------------------------------
        기능   : 월을 check한다.
        INPUT  : toCheck
        RETURN :
          MSG  :
      ----------------------------------------------------*/
      function jsCheckMM(toCheck)
      {
            return ((toCheck.length > 0) && (jsCheckNumber(toCheck)) && (0< eval(toCheck)) && (eval(toCheck) < 13));
      }
      /*--------------------------------------------------
        기능   : 일을 check한다.
        INPUT  : toCheck
        RETURN : NONE
           MSG :
      ----------------------------------------------------*/
      function jsCheckDD(yyyy,mm,toCheck)
      {
            var isYMD  = false;
            var monthDD= new jsMonthArray(31,28,31,30,31,30,31,31,30,31,30,31);
            var im     = eval(mm) - 1;
            if ( toCheck.length == 0 )  return false;
            if ( !jsCheckNumber(toCheck)  )  return false;
            var dd     = eval(toCheck);
            if ( ( (yyyy%4 == 0) && (yyyy%100 != 0) ) || (yyyy%400 == 0) )
            {
                 monthDD[1] = 29;
            }
            if ( (0 < dd) && (dd <= monthDD[im]) ) isYMD = true;
                 return isYMD;
      }
      /*--------------------------------------------------
        기능   : 날짜를 check한다.
        INPUT  : dateVal '20030321'
        RETURN : NONE
           MSG :
      ----------------------------------------------------*/
      function jsCheckDate( dateVal )
      {
           var isDate  = true ;
           if ( dateVal.length != 8 )
           {
                isDate = false ;
           }
           else
           {
                 var yy = dateVal.substring(0,4) +"" ;
                 var mm = dateVal.substring(4,6) +"" ;
                 var dd = dateVal.substring(6,8) +"" ;
                 if ( !jsCheckYYYY(yy) )
                    isDate = false ;
                 else if ( !jsCheckMM(mm) )
                    isDate = false ;
                 else if ( !jsCheckDD (yy,mm,dd) )
                    isDate = false ;
           }
           return isDate ;
      }
      /*--------------------------------------------------
        기능   : 날짜에 년수를 더한다.
        INPUT  : startDt(YYYYMMDD), year
        RETURN : rtnValue : 날짜에 년수를 더한 날짜
                 -1       : ERROR..!
                 예) 20000110 + 1년 = 20010110
                 예) 20000229 + 1년 = 20010228
           MSG :
      ----------------------------------------------------*/
      function jsAddYear( startDt, plusYear ) {
       var rtnValue = -1 ;
       // input date의 날짜 체크
       if ( !jsCheckDate(startDt) || !jsCheckNumber(plusYear) ) {
        rtnValue = -1 ;
        return rtnValue ;
       }
       var yyyy = startDt.substring(0,4) +"" ;
       var mm   = startDt.substring(4,6) +"" ;
       var dd   = startDt.substring(6,8) +"" ;
       var newYyyy = (eval(yyyy) + eval(plusYear)) ;
       // 윤달(29일) 인 경우 28일로 고침
       // 예) 20000229 에 1년을 더하면 20000228
       var isYoonYear = false ;
       // 4 로 나누어 떨어지면 윤년
       // 100 으로 나누어 떨어지면 윤년 아님
       // 400 으로 나누어 떨어지면 윤년
       if ( (eval(newYyyy)%4) == 0 ) isYoonYear = true ;
       if ( (eval(newYyyy)%100) == 0 ) isYoonYear = false ;
       if ( (eval(newYyyy)%400) == 0 ) isYoonYear = true ;
       if ( (mm == '02') && (dd == '29') && !isYoonYear ) dd = '28' ;
       rtnValue = newYyyy + mm + dd ;
       return rtnValue ;
      }
      /*--------------------------------------------------
        기능   : 날짜에 월수를 더한다.
        INPUT  : startDt(YYYYMMDD), year
        RETURN : rtnValue : 날짜에 월수를 더한 날짜
                 -1       : ERROR..!
                 예) 20000110 + 3월  = 20000410
                 예) 20000229 + 12월 = 20000228
           MSG :
      ----------------------------------------------------*/
      function jsAddMonths( startDt, plusMonth ) {
       var rtnValue = -1 ;
       // input date의 날짜 체크
       if ( !jsCheckDate(startDt) || !jsCheckNumber(plusMonth) ) {
        rtnValue = -1 ;
        return rtnValue ;
       }
       var yyyy = startDt.substring(0,4) +"" ;
       var mm   = startDt.substring(4,6) +"" ;
       var dd   = startDt.substring(6,8) +"" ;
       var newMm = null;
       // 월수를 더하여 1년이 넘는 경우
       if ( (eval(mm) + eval(plusMonth)) > 12 ) {
        yyyy  = eval(yyyy) + 1 ;
        newMm = eval(mm) + eval(plusMonth) - 12 ;
       } else {
        newMm = eval(mm) + eval(plusMonth) ;
       }
       // 윤년 처리
       var isYoonYear = false ;
       // 4 로 나누어 떨어지면 윤년
       // 100 으로 나누어 떨어지면 윤년 아님
       // 400 으로 나누어 떨어지면 윤년
       if ( (eval(yyyy)%4) == 0 ) isYoonYear = true ;
       if ( (eval(yyyy)%100) == 0 ) isYoonYear = false ;
       if ( (eval(yyyy)%400) == 0 ) isYoonYear = true ;
       // 윤년인 경우
       if ( isYoonYear ) {
        if ( (newMm == '02') && ( dd=='30' || dd=='31' ) ) dd = '29' ;
       // 평년인 경우
       } else {
        if ( (newMm == '02') && ( dd=='29' || dd=='30' || dd=='31' ) ) dd = '28' ;
       }
       // 월의 자리수를 맞춘다. ( 2 월 -> 02 )
       if ( eval(newMm) < 10 ) { newMm = "0" + newMm  } ;
       rtnValue = yyyy + newMm + dd ;
       return rtnValue ;
      }
      /*--------------------------------------------------
        기능   : 날짜와 날짜 사이의 일수를 리턴한다.
        INPUT  : startDt(YYYYMMDD), endDt(YYYYMMDD)
        RETURN : rtnValue : 날짜와 날짜 사이의 일수
                 -1       : ERROR..!
           MSG :
      ----------------------------------------------------*/
      function jsGetBetweenDay( startDt, endDt )
      {
           var rtnValue = 0 ;
           // input date의 날짜 체크
           if ( !jsCheckDate(startDt) || !jsCheckDate(endDt) ) {
            rtnValue = -1 ;
           }
           else {
                 var yyyy = startDt.substring(0,4) +"" ;
                 var mm   = startDt.substring(4,6) +"" ;
                 var dd   = startDt.substring(6,8) +"" ;
                 var startDate = new Date(yyyy,(eval(mm)-1),dd) ; // 달 은 한달이 느리므로 1을 빼준다.
                 yyyy = endDt.substring(0,4) +"" ;
                 mm   = endDt.substring(4,6) +"" ;
                 dd   = endDt.substring(6,8) +"" ;
                 var endDate = new Date(yyyy,(eval(mm)-1),dd) ;
                 // 1000분의 1초 단위를 일 단위로 바꾸기
                 rtnValue = ((endDate-startDate)/60/60/24/1000) ;
           }
           return rtnValue ;
      }
      /*--------------------------------------------------
        기능   : Check Time RETURN T/F
        INPUT  : check  time
        RETURN : true  -> TIME
                 false -> NOT TIME
      ----------------------------------------------------*/
      function jsCheckTime( toCheck )
      {
           var chkstr  = toCheck + "";
           if ( ( chkstr == "") || ( chkstr == null ) )
          return( false );
           var mm = chkstr.substring( 0 ,2 );
           var ss = chkstr.substring( 3 ,5 );
           if (( mm <= "23" ) && ( mm >= "00" ))
           {
               if (( ss <= "60" ) && ( ss >= "00" ))
               {
                   if ( chkstr.substring( 2 ,3 ) == ":")
                   {
                    return( true );
                   }
               }
           }
           return( false );
      }
      /*--------------------------------------------------
        기능   : Check 주민등록번호 RETURN T/F
        INPUT  : toCheck
        RETURN : true  -> 올바른 번호
                 false ->
      ----------------------------------------------------*/
      function jsCheckJumin(toCheck) {
          var isJumin = true;
          if ( jsCheckNull(toCheck) ) {
                return false;
          } else if ( toCheck.length < 13 || toCheck.length > 13 ) {
                return false;
          } else if ( toCheck.substring(2,3) > "1" || toCheck.substring(6,7) > "2" || toCheck.substring(6,7) == "0" ) {
                return false;
          } else if ( toCheck.substring(2,3) == "1" && toCheck.substring(3,4) > "2" ){
                return false;
          } else if (!(toCheck.substring(4,6) >= "01" && toCheck.substring(4,6) <= "31")){
                return false;
          }
         for (j = 0; isJumin && (j < toCheck.length); j++) {
             if ( ( (toCheck.substring(j,j+1) < "0") || (toCheck.substring(j,j+1) > "9")) ) {
                 isJumin = false;
             }
         }

        var a1=toCheck.substring(0,1)
        var a2=toCheck.substring(1,2)
        var a3=toCheck.substring(2,3)
        var a4=toCheck.substring(3,4)
        var a5=toCheck.substring(4,5)
        var a6=toCheck.substring(5,6)
        var check_digit=a1*2+a2*3+a3*4+a4*5+a5*6+a6*7
        var b1=toCheck.substring(6,7)
        var b2=toCheck.substring(7,8)
        var b3=toCheck.substring(8,9)
        var b4=toCheck.substring(9,10)
        var b5=toCheck.substring(10,11)
        var b6=toCheck.substring(11,12)
        var b7=toCheck.substring(12,13)
        var check_digit=check_digit+b1*8+b2*9+b3*2+b4*3+b5*4+b6*5
        check_digit = check_digit%11
        check_digit = 11 - check_digit
        check_digit = check_digit%10
        if (check_digit != b7){
         isJumin = false;
        }
         return isJumin;
      }
      /*--------------------------------------------------
        기능   : Check 사업자 등록번호 RETURN T/F
        INPUT  : toCheck
        RETURN : true  -> 올바른 번호
                 false ->
      ----------------------------------------------------*/
      function jsCheckSaupJa(toCheck) {
          var isSaupJa = true;
          if ( jsCheckNull(toCheck) ) {
                return false;
          } else if ( toCheck.length < 10 || toCheck.length > 10 ) {
                return false;
          }
          for (j = 0; isSaupJa && (j < toCheck.length); j++) {
             if ( ( (toCheck.substring(j,j+1) < "0") || (toCheck.substring(j,j+1) > "9")) ) {
                 isSaupJa = false;
             }
          }
          return isSaupJa;
      }
      /*--------------------------------------------------
        기능   : E-Mail를 check한다.
        INPUT  : emailVal
        RETURN : NONE
           MSG :
      ----------------------------------------------------*/
      function jsCheckEmail( emailVal )
      {
           if ( jsCheckNull(emailVal) ) return true;
           var inx = emailVal.indexOf("@") ;
           if ( inx <= 0 || inx==emailVal.length-1 ) return false;
           return true ;
      }
      /*--------------------------------------------------
        기능   :
        INPUT  : varNum : 실수
             varLeft : 정수부분 자리수
             varRight : 소수부분 자리수
        RETURN : true : 실수가 정/소수부분의 자리수를 초과하지 않는다.
             false : 실수가 정/소수부분의 자리수를 초과한다.
      ----------------------------------------------------*/
      function jsCheckFloatType( varNum, varLeft, varRight ) {
       var resultFlag = true ;
       if ( varNum.charAt(0) == "-" ){
        varNum = varNum.substring(1,varNum.length);
       }
       var PointIndex = varNum.indexOf(".");
       if ( PointIndex < 0 ){
        if ( varNum.length > varLeft )
         resultFlag = false ;
       }else{
        var LeftLength = varNum.substring(0,PointIndex).length;
        var RightLength = varNum.substring(PointIndex+1, varNum.length ).length;
        if ( (LeftLength > varLeft) || (RightLength > varRight) )
         resultFlag = false ;
       }
       return resultFlag ;
      }
      /*--------------------------------------------------
        기능   :
        INPUT  : helpfile
        RETURN :
      ----------------------------------------------------*/
      function jsShowHelp( helpfile )
      {
            var helpstr = helpfile + "" ;
            var URL     = "" ;
            var cWin ;
            URL = "/help/"+helpfile+".html" ;
            cWin = window.open(URL,"help","toolbar=0,location=0,directories=0,status=0,menubar=1,scrollbars=1,resizable=1,width=560,height=320");
            cWin.focus();
      }
      /*--------------------------------------------------
        기능   : 한글이든 영문이든 제대로 갯수 체크를 해준다.
        INPUT  : String
        RETURN :
      ----------------------------------------------------*/
      function getByteLength(s){
         var len = 0;
         if ( s == null ) return 0;
         for(var i=0;i<s.length;i++){
            var c = escape(s.charAt(i));
            if ( c.length == 1 ) len ++;
            else if ( c.indexOf("%u") != -1 ) len += 2;
            else if ( c.indexOf("%") != -1 ) len += c.length/3;
         }
         return len;
      }
      /*--------------------------------------------------
        기능   : FormObj에서 varObjName이 몇개 존재하는지 리턴한다.
        INPUT  : FormObj : FormName
           : varObjName : 객체명
        RETURN :
      ----------------------------------------------------*/
      function jsGetObjCnt( FormObj, varObjName ){
       var cnt = 0 ;
         for(var inx = 0; inx < FormObj.elements.length ; inx++ ) {
            if ( FormObj.elements[inx].name == varObjName ) {
             cnt++ ;
            }
         }
         return cnt;
      }
      /*--------------------------------------------------
        기능   :  SELECT OPTION BOX의 값을 RETURN 한다.
        INPUT  : sb = selectBoxName
        RETURN :
      ----------------------------------------------------*/
      function jsCheckSelectBox ( sb )
      {
          var temp = sb.options[sb.selectedIndex].value ;
          return ( temp );
      }
      function jsCheckSelectBoxNm ( sb )
      {
          var temp = sb.options[sb.selectedIndex].text ;
          return ( temp );
      }
      /*--------------------------------------------------
        기능   :  해당 Frame을 공백페이지로 변경
        INPUT  : fr : FrameName
        RETURN :
      ----------------------------------------------------*/
      function jsClearFrame( fr ) {
          fr.location = "/common/blank.jsp";
      }
      /*--------------------------------------------------
        기능   : checkBox를 전체선택 및 해제를 할수 있게 한다.
        INPUT  : FormObj FormName
             elemNm CheckBox name
             checkYn boolean
        RETURN :
      ----------------------------------------------------*/
      function jsToggle(FormObj, elemNm, checkYn){
       var i =0;
       while (i < FormObj.elements.length)
       {
        if (FormObj.elements[i].name== elemNm )
        {
         FormObj.elements[i].checked= checkYn;
        }
        i++;
       }
      }
      /*--------------------------------------------------
        기능   : focus 옮기기
        INPUT  : varTextObj : TextBox 객체명
             varLength  : 조건에 맞는 textLength
             varFocusToObj : Focus를 옮겨갈 객체명
        RETURN :
      ----------------------------------------------------*/
      function jsMoveFocus( varTextObj, varLength, varFocusToObj ) {
       if ( varTextObj.value.length == varLength ) {
        varFocusToObj.focus() ;
        varFocusToObj.select() ;
        return ;
       }
      }
      /*--------------------------------------------------
        기능   : 문자를 숫자로 convert 한다. 단,
             parseFloat 와 다른 점은 null 이 올때 0 으로 인식한다.
        INPUT  :
        RETURN :
      ----------------------------------------------------*/
      function jsParseInt( varStr ) {
       if ( varStr == null || varStr == "" )
        return 0 ;
       else
        return parseInt(varStr) ;
      }
      /*--------------------------------------------------
        기능   : 숫자를 한글로 변환한다.
         예) 450,000,000 -> 사억오천만
        INPUT  :
        RETURN :
      ----------------------------------------------------*/
      function jsConvertNumberToHangul( varNum )
      {
       // 리턴할 문자열
       var returnStr = "" ;
       // 음수일 때는 에러
       if ( eval(varNum) < 0 ) {
        return returnStr ;
       }
       // 넘어온 숫자를 문자로 변환
       var numLen = varNum.length ;
       // 변환된 문자를 앞에서 부터 한자씩 잘라서 보관할 변수
       var oneChar = null ;
       var isDone1 = true ;
       var isDone2 = true ;
       var isDone3 = true ;
       var isDone4 = true ;
       var isDone5 = false ;
       for ( var inx = 0 ; inx < numLen ; inx++ ) {
        oneChar = varNum.substring( inx, inx+1 ) ;
        isDone5 = false ;
        if ( oneChar == "0" ) {
         // 아무일도 안함
        } else if ( oneChar == "1" ) {
         returnStr = returnStr + "일" ;
         isDone5 = true ;
        } else if ( oneChar == "2" ) {
         returnStr = returnStr + "이" ;
         isDone5 = true ;
        } else if ( oneChar == "3" ) {
         returnStr = returnStr + "삼" ;
         isDone5 = true ;
        } else if ( oneChar == "4" ) {
         returnStr = returnStr + "사" ;
         isDone5 = true ;
        } else if ( oneChar == "5" ) {
         returnStr = returnStr + "오" ;
         isDone5 = true ;
        } else if ( oneChar == "6" ) {
         returnStr = returnStr + "육" ;
         isDone5 = true ;
        } else if ( oneChar == "7" ) {
         returnStr = returnStr + "칠" ;
         isDone5 = true ;
        } else if ( oneChar == "8" ) {
         returnStr = returnStr + "팔" ;
         isDone5 = true ;
        } else if ( oneChar == "9" ) {
         returnStr = returnStr + "구" ;
         isDone5 = true ;
        }
        if ( ((numLen-inx) % 4) == 0 && oneChar != "0" ) {
         returnStr = returnStr + "천" ;
        } else if ( ((numLen-inx) % 4) == 3 && oneChar != "0" ) {
         returnStr = returnStr + "백" ;
        } else if ( ((numLen-inx) % 4) == 2 && oneChar != "0" ) {
         returnStr = returnStr + "십" ;
        } else if ( ((numLen-inx) % 4) == 1 ) {
         if ( numLen >= 17 && isDone1 && isDone5 ) {
          returnStr = returnStr + "경" ;
          isDone1 = false ;
         } else if ( numLen >= 13  && isDone2 && isDone5 ) {
          returnStr = returnStr + "조" ;
          isDone2 = false ;
         } else if ( numLen >= 9  && isDone3 && isDone5 ) {
          returnStr = returnStr + "억" ;
          isDone3 = false ;
         } else if ( numLen >= 5  && isDone4 && isDone5 ) {
          returnStr = returnStr + "만" ;
          isDone4 = false ;
         }
        }
       }
       return returnStr ;
      }
      /*--------------------------------------------------
        기능   : 파라메터로 넘어온 필드에 comma를 찍어서 comma 를 찍어서 채워준다.
            소수점 허용 안함
          예) 1000.00 -> 1,000   
        INPUT  :
        RETURN :
      ----------------------------------------------------*/
      function jsMakeCurrency( varTextObj ) {
       varTextObj.value = jsDeleteComma( varTextObj.value ) ;
       var varLength = varTextObj.value.length ;
       var varText   = "" ;
       var isPointed = false ;
       for ( var inx = 0 ; inx < varLength ; inx++ ) {
        if ( jsCheckNumber(varTextObj.value.substring(inx, inx+1)) ) {
         varText = varText + varTextObj.value.substring(inx, inx+1) ;
        }
       }
       varTextObj.value = jsAddComma( varText ) ;
      }

      /*--------------------------------------------------
        기능   : 파라메터로 넘어온 필드에 comma를 찍어서 comma 를 찍어서 채워준다.
            소수점 허용 함   
          예) 1000.00 -> 1,000.00   
        INPUT  :
        RETURN :
      ----------------------------------------------------*/
      function jsMakeForeignCurrency( varTextObj ) {
       varTextObj.value = jsDeleteComma( varTextObj.value ) ;
       var varLength = varTextObj.value.length ;
       var varText   = "" ;
       var isPointed = false ;
       for ( var inx = 0 ; inx < varLength ; inx++ ) {
        if ( jsCheckNumber(varTextObj.value.substring(inx, inx+1)) || (varTextObj.value.substring(inx, inx+1)=='.') ) {
         // 점이 안찍히고 처음으로 점이 들어왔을때
         if ( !isPointed && varTextObj.value.substring(inx, inx+1)=='.' ) {
          isPointed = true ;
          varText = varText + varTextObj.value.substring(inx, inx+1) ;
         // 숫자 일때
         } else if ( jsCheckNumber(varTextObj.value.substring(inx, inx+1)) ) {
          varText = varText + varTextObj.value.substring(inx, inx+1) ;
         }
        }
       }
       varTextObj.value = jsAddComma( varText ) ;
      }
      /*--------------------------------------------------
        기능   : 파라메터로 넘어온 객체필드에 숫자만을 입력받게 해준다.
        INPUT  :
        RETURN :
      ----------------------------------------------------*/
      function jsOnlyNumber( varTextObj ) {
       var varLength = varTextObj.value.length ;
       var varText   = "" ;
       for ( var inx = 0 ; inx < varLength ; inx++ ) {
        if ( jsCheckNumber(varTextObj.value.substring(inx, inx+1)) ) {
         varText = varText + varTextObj.value.substring(inx, inx+1) ;
        }
       }
       // 앞에 붙은 0 없애기 (예) 00200 -> 200
       varLength = varText.length ;
       var varTempReturnNumber = varText;
       var varReturnNumber = "" ;
       for ( var inx = 0 ; inx < varLength ; inx++ ) {
        if ( varTempReturnNumber.substring(inx, inx+1) == '0' ) {
         // '0' 이 넘어왔을 경우 '0'을 그대로 리턴해야 한다.
         if ( varLength == 1 ) varReturnNumber = "0" ;
         else if ( eval(jsDeleteComma(varTempReturnNumber)) == '0' ) {
          varReturnNumber = "0" ;
          break ;
         }
        } else {
         varReturnNumber = varTempReturnNumber.substring(inx, varLength+1) ;
         break ;
        }
       }
       varTextObj.value = varReturnNumber;
      }
      /*--------------------------------------------------
        기능   : 파라메터로 넘어온 필드에 숫자와 1개의 point만을 입력받게 해준다.
        INPUT  :
        RETURN :
      ----------------------------------------------------*/
      function jsOnlyFloat( varTextObj ) {
       varTextObj.value = jsDeleteComma( varTextObj.value ) ;
       var varLength = varTextObj.value.length ;
       var varText   = "" ;
       var isPointed = false ;
       for ( var inx = 0 ; inx < varLength ; inx++ ) {
        if ( jsCheckNumber(varTextObj.value.substring(inx, inx+1)) || (varTextObj.value.substring(inx, inx+1)=='.') ) {
         // 점이 안찍히고 처음으로 점이 들어왔을때
         if ( !isPointed && varTextObj.value.substring(inx, inx+1)=='.' ) {
          isPointed = true ;
          varText = varText + varTextObj.value.substring(inx, inx+1) ;
         // 숫자 일때
         } else if ( jsCheckNumber(varTextObj.value.substring(inx, inx+1)) ) {
          varText = varText + varTextObj.value.substring(inx, inx+1) ;
         }
        }
       }
       // 앞에 붙은 0 없애기 (예) 00200 -> 200
       varLength = varText.length ;
       var varReturnNumber = "" ;
       for ( var inx = 0 ; inx < varLength ; inx++ ) {
        if ( varText.substring(inx, inx+1) == '0' ) {
         // '0' 이 넘어왔을 경우 '0'을 그대로 리턴해야 한다.
         if ( varLength == 1 ) varReturnNumber = "0" ;
         else if ( eval(jsDeleteComma(varText)) == '0' ) {
          varReturnNumber = "0" ;
          break ;
         }
        } else {
         varReturnNumber = varText.substring(inx, varLength+1) ;
         break ;
        }
       }
       varTextObj.value = varReturnNumber ;
      }
      /*--------------------------------------------------
        기능   : 파라메터로 넘어온 필드에 YYYY/MM형식으로 [/]를 찍어서 채워준다.
        INPUT  :
        RETURN :
      ----------------------------------------------------*/
      function jsMakeYyyyMm( varTextObj ) {
       varTextObj.value = jsDeleteChar( varTextObj.value, '/' ) ;
       var varLength = varTextObj.value.length ;
       var varText   = "" ;
       for ( var inx = 0 ; inx < varLength ; inx++ ) {
        if ( jsCheckNumber(varTextObj.value.substring(inx, inx+1)) ) {
         varText = varText + varTextObj.value.substring(inx, inx+1) ;
        }
       }
       if ( varText.length < 6 ) {
        varTextObj.value = varText ;
       } else {
        varTextObj.value = varText.substring(0,4) + "/" + varText.substring(4,6) ;
       }
      }
      /*--------------------------------------------------
        기능   : 파라메터로 넘어온 String에 날짜형식으로 [/]를 찍어서 리턴.
          예) 200103 -> 2001/03
        INPUT  :
        RETURN :
      ----------------------------------------------------*/
      function jsMakeYyyyMmString( varText ) {
       if ( varText.length != 6 || !jsCheckNumber( varText ) ) {
        return varText ;
       }
       var varReturnText   = "" ;
       varReturnText = varText.substring(0,4) + "/" + varText.substring(4,6) ;
       return varReturnText
      }
      /*--------------------------------------------------
        기능   : 파라메터로 넘어온 필드에 날짜형식으로 [/]를 찍어서 채워준다.     
          예) 20010301 -> 2001/03/01         
        INPUT  : Text Object
        RETURN :
      ----------------------------------------------------*/
      function jsMakeDate( varTextObj ) {
       varTextObj.value = jsDeleteChar( varTextObj.value, '/' ) ;
       var varLength = varTextObj.value.length ;
       var varText   = "" ;
       for ( var inx = 0 ; inx < varLength ; inx++ ) {
        if ( jsCheckNumber(varTextObj.value.substring(inx, inx+1)) ) {
         varText = varText + varTextObj.value.substring(inx, inx+1) ;
        }
       }
       if ( varText.length < 8 ) {
        varTextObj.value = varText ;
       } else {
        varTextObj.value = varText.substring(0,4) + "/" + varText.substring(4,6) + "/" + varText.substring(6,8) ;
       }
      }
      /*--------------------------------------------------
        기능   : 파라메터로 넘어온 String에 날짜형식으로 [/]를 찍어서 채워준다.     
          예) 20010301 -> 2001/03/01         
        INPUT  :
        RETURN :
      ----------------------------------------------------*/
      function jsMakeDateString( varText ) {
       if ( varText.length != 8 || !jsCheckNumber( varText ) ) {
        return varText ;
       }
       var varReturnText   = "" ;
       varReturnText = varText.substring(0,4) + "/" + varText.substring(4,6) + "/" + varText.substring(6,8) ;
       return varReturnText
      }
      /*--------------------------------------------------
        기능   : 숫자를 받아서 comma를 찍어서 리턴한다. 음수도 표현가능
          예) 1000.00 -> 1,000.00
          예) 숫자가 아닌 값 -> -1 리턴     
        INPUT  :
        RETURN :
      ----------------------------------------------------*/
      function jsAddComma( varNumber ){
       // 숫자가 아니면 -1을 리턴한다.
       if ( jsCheckNull(varNumber) ) return "" ;
       if ( !jsCheckFloat(varNumber) ) {
        return -1 ;
       }
       // 소수 이상, 이하 부분을 따로 보관.
       var PointIndex = varNumber.indexOf(".") ;
       var varUnderPoint = "" ;
       var isPointed = false ;
       // 소수 이하가 없을때
       if ( PointIndex < 0 ) {
        isPointed = false ;
        // 소수 이하 부분
        varUnderPoint = "" ;
        // 소수 이상 부분
        varOverPoint = varNumber ;
       // 소수 이하가 있을때
       } else {
        isPointed = true ;
        // 소수 이하 부분
        varUnderPoint = varNumber.substring(PointIndex+1, varNumber.length ) ;
        // 소수 이상 부분
        varOverPoint = varNumber.substring(0, PointIndex) ;
       }
       // 음수일때 앞의 "-" 따로 보관
       var negativeFlag = false ;
       if ( varOverPoint.substring(0,1) == "-" ) {
        negativeFlag = true ;
        varOverPoint = varOverPoint.substring(1,varOverPoint.length+1) ;
       }
       // 소수 이상 부분에 comma 넣기
       var varLength = varOverPoint.length ;
       var varCnt = 0 ;
       var varTempReturnNumber = "" ;
       for ( var inx = varLength-1 ; inx >= 0 ; inx-- ) {
        varCnt++ ;
        // 소수점 찍기
        if ( varCnt == 4 ) {
         varTempReturnNumber = varOverPoint.substring( inx, inx+1 ) + "," + varTempReturnNumber ;
         varCnt = 1 ;
        // 소수점 안찍기
        } else {
         varTempReturnNumber = varOverPoint.substring( inx, inx+1 ) + varTempReturnNumber ;
        }
       }
       // 앞에 붙은 0 없애기 (예) 00200 -> 200
       varLength = varTempReturnNumber.length ;
       var varReturnNumber = "" ;
       for ( var inx = 0 ; inx < varLength ; inx++ ) {
        if ( varTempReturnNumber.substring(inx, inx+1) == '0' ) {
         // '0' 이 넘어왔을 경우 '0'을 그대로 리턴해야 한다.
         if ( varLength == 1 ) varReturnNumber = "0" ;
         else if ( eval(jsDeleteComma(varTempReturnNumber)) == '0' ) {
          varReturnNumber = "0" ;
          break ;
         }
        } else {
         varReturnNumber = varTempReturnNumber.substring(inx, varLength+1) ;
         break ;
        }
       }
       // 소수점 이하 붙이기
       if ( isPointed ) {
        varReturnNumber = varReturnNumber + "." + varUnderPoint ;
       }
       // 음수 붙이기
       if ( negativeFlag ) {
        varReturnNumber = "-" + varReturnNumber ;
       }
       return varReturnNumber ;
      }
      /*--------------------------------------------------
        기능   : 숫자를 받아서 comma를 찍어서 리턴한다.
          예) 1000 -> 1,000.00
          예) 숫자가 아닌 값 -> -1 리턴  
        INPUT  :
        RETURN :
      ----------------------------------------------------*/
      function jsAddCommaAndZero( varNumber ){
       // 숫자가 아니면 -1을 리턴한다.
       if ( jsCheckNull(varNumber) ) return "" ;
       if ( !jsCheckFloat(varNumber) ) {
        return -1 ;
       }
       // 소수 이상, 이하 부분을 따로 보관.
       var PointIndex = varNumber.indexOf(".") ;
       var varUnderPoint = "" ;
       // 소수 이하가 없을때
       if ( PointIndex < 0 ) {
        // 소수 이하 부분
        varUnderPoint = "" ;
        // 소수 이상 부분
        varOverPoint = varNumber ;
       // 소수 이하가 있을때
       } else {
        // 소수 이하 부분
        varUnderPoint = varNumber.substring(PointIndex+1, varNumber.length ) ;
        // 소수 이상 부분
        varOverPoint = varNumber.substring(0, PointIndex) ;
       }
       // 소수 이상 부분에 comma 넣기
       var varLength = varOverPoint.length ;
       var varCnt = 0 ;
       var varTempReturnNumber = "" ;
       for ( var inx = varLength-1 ; inx >= 0 ; inx-- ) {
        varCnt++ ;
        // 소수점 찍기
        if ( varCnt == 4 ) {
         varTempReturnNumber = varOverPoint.substring( inx, inx+1 ) + "," + varTempReturnNumber ;
         varCnt = 1 ;
        // 소수점 안찍기
        } else {
         varTempReturnNumber = varOverPoint.substring( inx, inx+1 ) + varTempReturnNumber ;
        }
       }
       // 앞에 붙은 0 없애기 (예) 00200 -> 200
       varLength = varTempReturnNumber.length ;
       var varReturnNumber = "" ;
       for ( var inx = 0 ; inx < varLength ; inx++ ) {
        if ( varTempReturnNumber.substring(inx, inx+1) == '0' ) {
        } else {
         varReturnNumber = varTempReturnNumber.substring(inx, varLength+1) ;
         break ;
        }
       }
       // 소수점 이하 붙이기
       if ( varUnderPoint.length == 0 ){
        varReturnNumber = varReturnNumber + "." + "00" ;
       }else if ( varUnderPoint.length == 1 ){
        varReturnNumber = varReturnNumber + "." + varUnderPoint + "0";
       }else if ( varUnderPoint.length == 2 ){
        varReturnNumber = varReturnNumber + "." + varUnderPoint ;
       }
       return varReturnNumber ;
      }
      /*--------------------------------------------------
        기능   : 숫자를 받아서 comma를 없애고 리턴한다
          예) 1,000.00 -> 1000.00    
        INPUT  :
        RETURN :
      ----------------------------------------------------*/
      function jsDeleteComma( varNumber ){
       var varLength = varNumber.length ;
       varReturnNumber = "" ;
       for ( var inx = 0 ; inx < varLength ; inx++ ) {
        if ( varNumber.substring( inx, inx+1 ) != "," ) {
         varReturnNumber = varReturnNumber + varNumber.substring( inx, inx+1 ) ;
        }
       }
       return varReturnNumber ;
      }
      /*--------------------------------------------------
        기능   : 글자를 받아서 param를 없애고 리턴한다.
          예) 2001/01/01 -> 20010101    
        INPUT  : varText 문자열 varDelete 삭제하고자하는 Character
        RETURN :
      ----------------------------------------------------*/
      function jsDeleteChar( varText, varDelete ){
       var varLength = varText.length ;
       varReturnText = "" ;
       for ( var inx = 0 ; inx < varLength ; inx++ ) {
        if ( varText.substring( inx, inx+1 ) != varDelete ) {
         varReturnText = varReturnText + varText.substring( inx, inx+1 ) ;
        }
       }
       return varReturnText ;
      }
      /*--------------------------------------------------
        기능   : 폼 이름을 받아서 모든 text,hidden값에 comma, / 문자를 없애준다
        INPUT  :
        RETURN :
      ----------------------------------------------------*/
      function jsDeleteCharAll( FormObj ) {
       for ( i=0; i<FormObj.elements.length; i++ ) {
        if ( FormObj.elements[i].type == "text" || FormObj.elements[i].type == "hidden" ) {
         if ( !jsCheckNull(FormObj.elements[i].value) && jsCheckFloat(jsDeleteComma(FormObj.elements[i].value)) ) {
          FormObj.elements[i].value = jsDeleteComma(FormObj.elements[i].value);
         } else if ( !jsCheckNull(FormObj.elements[i].value) && jsCheckDate(jsDeleteChar(FormObj.elements[i].value,'/')) ) {
          FormObj.elements[i].value = jsDeleteChar( FormObj.elements[i].value, '/' );
         }
        }
       }
      }
      /*--------------------------------------------------
        기능   : FormObj에서 checkBox 가 몇개 선택되었는지  리턴한다.
        INPUT  :
        RETURN :
      ----------------------------------------------------*/
      function jsCheckBoxSelectedCnt( FormObj, checkBoxName ){
         var cnt = 0 ;
         for(var inx = 0; inx < FormObj.elements.length ; inx++ ) {
            if ( FormObj.elements[inx].name == checkBoxName && FormObj.elements[inx].checked ) {
             cnt++ ;
            }
         }
         return cnt;
      }
      /*--------------------------------------------------
        기능   : 영문 과 숫자로만 이루어 졌는지  체크를 해준다.
        INPUT  :
        RETURN :
      ----------------------------------------------------*/
      function isAlphaNum(input) {
          var chars = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
          return containsCharsOnly(input,chars);
      }
       
      //입력값이 한글이 포함되어있는지 체크
      function IsHangul(field)
      {
       if ( field == "" ) return false;
          var rtnLen = 0 ;
       
          for (i=0; i<field.length; i++)
          {  
              // 한글인 경우 길이가 UniCode 값은 10000 이상이다.
              if(field.charCodeAt(i) > 10000 )
              {
               rtnLen++;
              }
          }
         
          if ( rtnLen > 0 )
           return true;
          else
           return false;
      }
       
      /*----------------------------------------------------
        입력값이 특정 문자(chars)만으로 되어있는지 체크
        특정 문자만 허용하려 할 때 사용
        ex) if (!containsCharsOnly(form.blood,"ABO")) {
                alert("혈액형 필드에는 A,B,O 문자만 사용할 수 있습니다.");
            }
      ------------------------------------------------------*/
      function containsCharsOnly(input,chars) {
          for (var inx = 0; inx < input.value.length; inx++) {
             if (chars.indexOf(input.value.charAt(inx)) == -1)
                 return false;
          }
          return true;
      }
      /*--------------------------------------------------
        기능   : POPUP OPEN Script
        INPUT  :
        RETURN :
      ----------------------------------------------------*/
      function popup1( varAction, varWinName, varWidth, varHeight ){
       var win = window.open( varAction, varWinName , "toolbar=0,location=0,directories=0,status=1,menubar=0,scrollbars=1,resizable=1, width=" + varWidth + ",height=" + varHeight + ", left=50,top=50");
       return win;
       
       //var FormObj = document.dataForm;
       //FormObj.target = varWinName ;
       //FormObj.action = varAction ;
       //FormObj.submit() ;
      }

      function toTimeString( varDateObj ) { //formatTime(date)
          var year  = varDateObj.getFullYear();
          var month = varDateObj.getMonth() + 1; // 1월=0,12월=11이므로 1 더함
          var day   = varDateObj.getDate();
          if (("" + month).length == 1) { month = "0" + month; }
          if (("" + day).length   == 1) { day   = "0" + day;   }
          return ("" + year + month + day );
      }
      function jsAfterThisDate( varStdDate , varYYYY , varMM , varDD ) {
          var varDateObj = new Date();
          varStdDate = jsDeleteChar( varStdDate, "/" );
          var yyyy = varStdDate.substring(0,4) +"" ;
          var mm   = varStdDate.substring(4,6) +"" ;
          var dd   = varStdDate.substring(6,8) +"" ;
          var startDate = new Date(yyyy,(eval(mm)-1),dd) ; // 달 은 한달이 느리므로 1을 빼준다.
          varDateObj.setFullYear(startDate.getFullYear() + eval(varYYYY) ); //년을 더함
          varDateObj.setMonth(startDate.getMonth() + eval(varMM) );       //월을 더함
          varDateObj.setDate(startDate.getDate() + eval(varDD)  );         //일을 더함
          return toTimeString(varDateObj);
      }
      /*--------------------------------------------------
        기능   : text 입력시 숫자이외의 키를 눌렀을때 무효화시킨다.
        INPUT  : 없음
        RETURN : 이벤트 무효화
        주의!  : onKeypress 이벤트만 사용할것
                예) <input type="text" omKeypress="jsOnlyNumberKey();">
      ----------------------------------------------------*/
      function jsOnlyNumberKey() {
          if ( event != null) {
            if ( event.keyCode < 48 || event.keyCode > 57 ) {
              event.returnValue = false;
            }
          }
      }
      /* 이전페이지로 이동 */
      function jsBack(){
       history.go(-1);
      }
      /* 모래시계 보이게 하기 */
      function jsVisible( str ){
       if( str == '1' )
        document.body.style.cursor='wait'
       else
        document.body.style.cursor='auto'
      }
      /* 15초후에 jsRefresh()라는 function을 호출 */
      var timeId   = null ;
      function jsRunAfterTime() {
       //15초 후에 Refresh
       timeId = setTimeout( "jsRefresh()", 15000 ) ;
      }
      /**
       * 소수점 아래 몇자리 이하 절삭.
       *
       * @param num 숫자
       * @param place 자리수
       * @return 절삭된 숫자
       */
      function getCutNumber(num, place) {
       var returnNum;
       var str = "1";
       return Math.floor( num * Math.pow(10,parseInt(place,10)) ) / Math.pow(10,parseInt(place,10));
      }
      /* text의 좌우 공백을 제거해서 리턴*/
      function trim(text) {
       if (text == "") {
        return text;
       }
       var len = text.length;
       var st = 0;
       while ((st < len) && (text.charAt(st) <= ' ')) {
        st++;
       }
       while ((st < len) && (text.charAt(len - 1) <= ' ')) {
        len--;
       }
       return ((st > 0) || (len < text.length)) ? text.substring(st, len) : text;
      }
      /* text의 좌측의 공백을 제거해서 리턴*/
      function ltrim(text) {
       if (text == "") {
        return text;
       }
       var len = text.length;
       var st = 0;
       while ((st < len) && (text.charAt(st) <= ' ')) {
        st++;
       }
       return (st > 0) ? text.substring(st, len) : text;
      }
      /* text의 우측의 공백을 제거해서 리턴*/
      function rtrim(text) {
       if (text == "") {
        return text;
       }
       var len = text.length;
       var st = 0;
       while ((st < len) && (text.charAt(len - 1) <= ' ')) {
        len--;
       }
       return (len < text.length) ? text.substring(st, len) : text;
      }
      /*--------------------------------------------------
        기능   : select box 를 CLEAR 시킨다.
        INPUT  : varObjFullNm : select box 객체
                 varDeleteCnt : 첫번째 아이템 삭제 여부 결정
        RETURN : NONE
      ----------------------------------------------------*/
      function cmInitSelectBox( varObjFullNm, varDeleteCnt ) {
       varObj = eval( varObjFullNm ) ;
       varObj.length = varDeleteCnt ;
      }
      /*--------------------------------------------------
        기능   :  select box 를 만든다.
        INPUT  : varObjFullNm :  select box 객체
                 varText      :
                 varValue     : 
        RETURN : NONE
      ----------------------------------------------------*/
      function cmMakeSelectBox( varObjFullNm, varText, varValue ) {
       varObj = eval( varObjFullNm ) ;
       
       var empOption = null ;
       empOption = document.createElement("OPTION");
       empOption.text = varText ;
       empOption.value = varValue ;
       varObj.options.add(empOption);
      }
      반응형

      'Information' 카테고리의 다른 글

      JavaScript 키워드 정리  (0) 2007.02.24
      [팁] .NET 로딩페이지 구현하기  (0) 2007.02.23
      SOA(Site Open API) 활용법  (1) 2007.02.17

      간만에 팁에 대한 글을 올리게 되네요. 어려운것도 아니지만, 대부분 이런 페이지를 구현하리라 생각은 했을 거라고 판단됩니다. 저두 의외로 쉬운 부분 같은데 아이디어가 잘 안 떠오르더라구요. 근데 이렇게 구현하니깐 상당히 이쁜 페이지가 되네요. 그럼 본론으로 들어가서...

       

      페이지가 로딩될때 모든 데이터가 바인딩 되기전에 “페이지 로딩중...” 이런식으로 표현으로 먼저 보여주고 모든 데이터의 바인딩이 끝나게 되면 사라지게 되는거죠. 비스타에서도 이런 부분이 많이 적용된 걸로 알고 있는데요, 아직 많이 사용해보지 않아서 확답은 못하겠네요.

       

      그래서 오늘 소개할 것은 비스타 처럼 페이지의 모든 데이터가 바인딩되기 전에 페이지 중간에 비스타에서 적용되는 이미지(동그랗게 돌아가는 gif 이미지죠)를 사용하여 구현해 볼까 합니다. 스텝바이스텝으로 가겠습니다. 죄송하지만 캡처는 귀차니즘이 발동하여 생략하겠습니다.

       

      그럼 시작하도록 하죠.

       

      참고로, 다음은 ASP.NET 1.1 with C# 기준입니다.

       

       

      1. 아무런 이름으로 ASP.NET 프로젝트를 하나 만듭니다. 저는 LodingProject라고 하겠습니다.

       

      2. Loading.aspx를 하나 만듭니다.

       

      3. Loading.aspx에서는 아무런 작업을 할 필요가 없고, Loading.aspx.cs 파일을 열어봅니다.

       

      4. 기본적으로 cs파일의 자동으로 만들어지는 코드에 굵게 된 부분을 주목하여 바꿔주세요.

       

      using System;

      using System.Collections;

      using System.ComponentModel;

      using System.Data;

      using System.Drawing;

      using System.Web;

      using System.Web.SessionState;

      using System.Web.UI;

      using System.Web.UI.WebControls;

      using System.Web.UI.HtmlControls;

       

      namespace LoadingProject

      {

                   /// <summary>

                   /// Loading에 대한 요약 설명입니다.

                   /// </summary>

                   public class Loading : PageBase

                   {

                                 private void Page_Load(object sender, System.EventArgs e)

                                 {

                                              // 여기에 사용자 코드를 배치하여 페이지를 초기화합니다.

                                 }

       

                                 #region Web Form 디자이너에서 생성한 코드

                                 override protected void OnInit(EventArgs e)

                                 {

                                              //

                                              // CODEGEN: 이 호출은 ASP.NET Web Form 디자이너에 필요합니다.

                                              //

                                              InitializeComponent();

                                              base.OnInit(e);

                                 }

                                

                                 /// <summary>

                                 /// 디자이너 지원에 필요한 메서드입니다.

                                 /// 이 메서드의 내용을 코드 편집기로 수정하지 마십시오.

                                 /// </summary>

                                 private void InitializeComponent()

                                 {   

                                              this.Load += new System.EventHandler(this.Page_Load);

                                 }

                                 #endregion

                   }

      }

       

       

      5. PageBase라는 것은 System.Web.UI.Page를 상속받는 클래스입니다. 따라서 PageBase라는 클래스를 하나 만듭니다.

       

       

      6. 만들어진 PageBase 클래스에 다음과 같이 코드를 바꿔주세요

       

       

      using System;

       

      namespace LoadingProject

      {

                   /// <summary>

                   /// PageBase에 대한 요약 설명입니다.

                   /// </summary>

                   public class PageBase : System.Web.UI.Page

                   {

                                 public PageBase()

                                 {

                                              //

                                              // TODO: 여기에 생성자 논리를 추가합니다.

                                              //

                                 }

       

                                 protected override void Render(System.Web.UI.HtmlTextWriter writer)

                                 {

                                              // 로딩이미지 설정

                                              Response.Write("<table id='waiting' width='100%' height='100%' style='position:absolute;visibility:hidden;' cellpadding=0 cellspacing=0 bgcolor='#ffffff'> ");

                                              Response.Write("<tr><td align=center valign='middle' width=100% height=100%>);

                                              Response.Write("<img src='img/loading01.gif' align='absmiddle' border=0>");

                                              Response.Write("</td></tr></table> ");

       

                                              //로딩중 이미지 보여주기

                                              Response.Write("<script language='Javascript'> ");

                                              Response.Write("waiting.style.visibility='visible' ");

                                              Response.Write("</script>") ;

                                             

                                              base.Render(writer);

                                

                                              //로딩중 이미지 숨기기

                                              Response.Write("<script language='Javascript'> ");

                                              Response.Write("waiting.style.visibility='hidden' ");

                                              Response.Write("</script>") ;

                                 }

                   }

      }

       

      7. 이미지가  지금 없기 때문에 “img”라는 폴더를 하나 만들어 첨부된 이미지를 그 폴더에 저장합니다.

       

      이걸로 모든 준비는 끝났습니다. 그런데 테스트를 해보면 로딩 이미지가 보이지 않을 겁니다. 바인딩 될 데이터가 워낙에 없어서 그렇습니다. 작업하실때 위와같이 System.Web.UI.Page를 상속받는 PageBase라는 것을 만들어서 모든 aspx.cs파일은 상속을 받아서 사용하게 합니다. 이건 데이터가 많을 경우 아주 잘 보여질겁니다. 안된다고 상심마시고 바인딩이 많이 되는 페이지에 적용시켜 보세요. 아주 이쁘게 잘 나옵니다.

      반응형

      'Information' 카테고리의 다른 글

      JavaScript 모음  (0) 2007.02.23
      SOA(Site Open API) 활용법  (1) 2007.02.17
      53 CSS Techniques you couldnt live without.  (0) 2007.02.17

      [*] 문서

      문서: SOA(Site Open API) 활용법
      제작: ky (thruthesky) <thruthesky@yahoo.co.kr>, Korean
      연락: thruthesky@yahoo.co.kr http://jangnans.com
      날짜: 2006년 12월 초(배포 2007년 1월 초)
      요약: 본 문서를 통해서 블로그와 Open API 가 무엇인지, 그리고 Open API 구체적인 산물인 SOA의 활용에 대해서 설명합니다. (특히, 원격 블로깅에 대해서 초점을 맞추어서 설명을 합니다.)
      요약: Web2.0 의 주요 기능 중 하나인 Open API 와 그 한 종류인 Site Open API 에 대해서 설명합니다. SOA 는 개인의 웹사이트에서 직접 제공할 수 있는 막강한 Open API 입니다. 이제 Open API 는 더 이상 대형 웹 사이트의 전유물이 아닙니다.
      대상: 웹 서핑의 초보자에게는 블로그와 원격 블로깅에 대해서 설명을 합니다. 고급자에게는 Open API 와 SOA 의 전반적인 소개와 활용에 대해서 안내를 합니다.
      문서의 시작 위치: http://jangnans.com
      참고: http://siteapi.kldp.net
      기타: 본 문서의 배포 시작 위치는 http://jangnans.com 입니다. 본 문서의 변동 사항은 이 곳에서 확인을 하실 수 있습니다. 본 문서를 재 배포하시는 것은 고마우나 이 주소를 삭제하시면 이 글을 읽는 분이 새로운 내용을 확인하지 못할 수 있으니, 본 주소는 삭제하지 마세요.
      기타: Open API 에 대해서 많은 내용이 있습니다. 보다 자세한 정보를 제공하기 위해서 여러곳으로 링크를 통해 웹 페이지를 연결해 놓았습니다. 링크가 잘못된 것이 있거나 수정해야할 부분이 있으면 연락 주십시오.  (원격 편집을 바탕으로 블로그 관련 Open API 와 SOA 대해서 설명을 합니다.)

      [-] 성질 급하신 분들을 위한 간추림

      본 문서는 원격 블로깅과 중/소형 사이트를 위한 Site Open API 에 대해서 설명을 합니다.
      원격 블로깅 실제 예제와 체험을 원하시면, http://jangnans.com/?cate=bbs&mode=read&idx=290 페이지를 참고하십시오. 원격 블로깅이 무엇인지 모르는 분은 꼭 이 링크를 따라서 체험을 해 보시길 권합니다. http://memories24.cafe24.com/zb5/tt2zb5.php?article_srl=827&PHPSESSID=96e93768e0179b071d4a117b27b3975a
      Site Open API 에 대해서 알고 싶다면, http://siteapi.kldp.net 을 참고하십시오.
      XML-RPC 에 대해서 알고 싶다면, http://xmlrpc.com 을 참고하십시오.
      Blogger API, Meta Weblog API, Movable Type API 에 대해서 알고 싶다면, http://www.xmlrpc.com/metaWeblogApi 를 참고하십시오.
      혹시 XML-RPC 나 Site Open API 와 관련하여 개발에 관심이 있다면, http://phpxmlrpc.sourceforge.net/
      Site Open API 는 중,소형 사이트(홈페이지)에 강력한 Open API를 제공합니다. SOA 버젼 0.4에는 Blogger API, Meta Weblog API 를 포함합니다.
      2006 년 말 현제 Site Open API 를 사용가능 한 홈페이지는 제로보드4 로 제작된 홈페이지, 제로보드5 로 제작된 홈페이지, 그누보드4로 제작된 홈페이지, 알지보드로 제작된 홈페이지, 장난-홈툴즈로 제작된 홈페이지 들입니다.
      Site Open API 와 호환이 가능한 윈도우즈 응용 소프트웨어는 무궁무진합니다. 본 문서의 관련 항목을 참조하십시오.


      [-] 문서에 대해서
      본 문서는 본인이 생각하는 Open API와 Site Open API 에 대해서 개인적인 생각을 기록했습니다. 물론 많은 분들에게 도움이 되기를 바랍니다.
      혹시나 본 문서에 대해서 고쳐야할 점이 발견되면 꼭 연락을 주십시오.
      카이(ky, thruthesky, <thruthesky@yahoo.co.kr>, http://jangnans.com)


      [*] 서문
      본 문서는 홈페이지의 정보를 이용하는데에 웹브라우저가 전부라는 것에 대한 개념을 깨뜨리고 그 보다 편하고 낳은 방법으로 인터넷을 즐기는 또 다른 방법에 대해서 가르켜줍니다.
      뿐만 아니라 여러분의 홈페이지 방문자(사용자,회원)가 어떻게 더 낳은 방법으로 홈페이지의 정보를 이용할 수 있는지에 대해서 알려드립니다. 이 방법을 통해서 여러분의 홈페이지에 많은 극성팬이 생겨나기를 바랍니다.

      어느 리서치에서 블로깅을 하는데에 사용하는 툴 중 60.9% 가 웹브라우저이고 나머지가 데스크탑 응용프로그램이라고 합니다. 상당히 부풀려진 결과라 생각합니다.
      본인은 블로거들 중 90% 이상이 웹브라우저로 블로깅을 즐기고 있다고 판단합니다.
      그러나 원격 블로깅 툴의 열기는 계속해서 급 상승 중입니다.

      본 문서는 블로그와 관련된 개념의 정립과 블로깅을 좀 더 손쉽게 할 수 있는 방법을 제시할 것입니다. 그러기를 희망합니다.

      블로깅과 관련된 좀 어려운 용어들을 살펴볼까요? 트랙백, RSS, Open API ... 본인이 잠깐 자리를 비운 사이에 인터넷은 많은 발전을 해 있더군요. 특히, 트랙백에 대한 개념이 잡히지 않아서 본인을 괴롭게 했었습니다.
      본 문서에서는 이러한 것들에 대해서 약간의 설명을 합니다.
      그리고 원격 블로깅과 관련된 XML-RPC, Open API, Blogger API 에 대해서도 짧게 설명합니다.




      [-] 요점 정리
      본 문서를 통해서 독자들에게 알리고 싶은 주요 내용은 다음과 같습니다.
      - 블로그 Open API 를 통한 편리한 블로깅
      - SOA(Site Open API)라는 막강한 Open API 를 여러분의 개인 홈페이지에 부착시키는 방법




      [-] 블로깅

      블로그란 web+log 가 합해져서 blog 로 표기되며, 네티즌이 자신의 관심사에 따라 자유롭게 칼럼, 일기, 취재 기사 따위를 올리는 웹 사이트를 말합니다. 흔히 말하는 1인 미디어의 대표적인 형태라 하겠습니다.

      사전적 의미로 블로깅이란 다른 사람의 블로그에 방문하여 글을 보거나, 스크랩하여 자료를 모으는 것으로 모든 블로그 활동을 하는 것을 뜻하는 말로 사용됩니다.

      블로그가 어떤 형식을 가져야한다는 규격이 없습니다. 있나요? 본인은 없다고 생각을 합니다. 블로그가 웹 게시판 1개로 구성이 되든, 블로그의 성격에 따라 자료실이나 기타 여러가지 형태의 구조를 가지든, 블로그를 운영하는 사람 마음이라 판단을 합니다. 하지만, 일반적으로 블로그는 자료실이나 게시판이 없이 블로그 운영자만 글을 쓰는 웹 페이지 형태로 간단하게 구성됩니다.


      [-] XML-RPC
      어려운 이야기입니다. 쉽게 한줄로 설명하고 넘어가겠습니다.
      MS-윈도우즈 운영체제에서 유닉스에 존재하는 프로그램을 실행하는 것을 RPC(Remote Procedure Call)라 합니다. 그리고 이것을 인터넷에서 사용되는 XML(eXtended Markup Language)를 바탕으로 데이터를 교환하는 것을 XML-RPC 라고 합니다. XML-RPC 는 이렇게 웹브라우저(또는 웹 클라이언트)가 웹서버와 정보를 교환하는 방식중 하나입니다. 물론 표준이며 자세한 정보는 http://xmlrpc.com 에서 얻을 수 있습니다.
      블로그에서 XML-RPC 는 Open API 서비스하는 바탕이됩니다.


      [-] 웹 2.0
      2006년 말 현재, 많은 이들이 웹 2.0 이라고 목소리를 높입니다. 웹 2.0 대열에 끼지 못하면 괜시리 뒤쳐지는 느낌을 받을 때 입니다. 과거 인터넷 투기 열풍(닷컴 거품 현상)으로 나라가 떠들썩했던 것이 연상됩니다. 뭐 어쨌든 나쁜 현상은 아니라 생각합니다.

      웹 2.0 은 현재 표준이 없습니다. 너무 광범위 해서 표준이 안잡힐 것 같습니다.
      아참, 한줄 정의가 필요하나요?
      웹 2.0은 기존의 웹(WWW)보다 한단계 발전된 모습을 가르키는 것으로서 좀 더 낳은 기능들을 묶어서 서비스하는 것을 말합니다.

      웹 2.0 의 기능으로 Ajax 니 뭐니... 주욱 나열하면서... 꼭 빠뜨리지 않고 포함되는 것 하나가 바로 Open API 입니다.

      참고: http://blog.naver.com/quiz94/30004276107
      참고: http://blog.naver.com/wooseokint1?Redirect=Log&logNo=110011276684

      [-] UCC

      UCC 가 뭐냐고 스스로 질문을 하고 UCC 는 그저 UCC 일 뿐이라고 결론을 낼지 모르겠습니다. 사실 우리나라 사람들이야 UCC 를 확대해서 복잡하게 해석할 뿐이지, UCC 는 그냥 User Crecated Contents 로서 그 이상도 아니고 이하도 아니라고 판다는하는게 100% 맞다고 생각을 합니다. 다만 현재(2006년 말) 흔히 얘기하는 UCC는 그 결과물의 형태가 동영상이라는 것을 중심으로 얘기합니다. UCC 를 통해서 스타가 탄생했다느니 양질의 UCC 제작을 위해서 서포트하는 서비스가 많이 등장했다느니, 기존의 이미지, 유머, 패러디, 이야기 만화, 댓글 등의 컨텐츠를 한단계 업그레이드 시켜 자신을 가장 잘 나타내기 위한 방법으로서의 UCC 니, UCC 의 저작권으로 인해서 수익을 창출한다느니, 차세대 비즈니스 모델이라니... 말이 많습니다.
      UCC 는 UCC 일뿐입니다. 물론 여러가지 활용도가 있겠지만, 현재로서는 특별히 새로운 것 없이 단순히 기존의 사용자 컨텐츠를 통칭하는 용어 정도 입니다.
      UCC 가 기존의 블로그를 대체하는 새로운 미디어로 떠오르며 각광을 받는다는 이야기가 있습니다. 어불성실입니다. UCC 는 UCC 고 블로그는 블로그일 뿐입니다. 둘의 연관 관계가 전혀 없는 것은 아니지만, 이런식의 억지 설정은 참으로 곤란한 일입니다.
      그러나 이렇게 간단히 UCC 에 대해서 결론을 짓고 넘어가기에는 UCC 에 대한 인터넷의 열기가 너무 뜨겁게 달궈져 있습니다. 비록 새로운 것이 없는 UCC 이지만, 새로운 이름 UCC 를 통해서 변화를 시도하는 움직임이 너무 거셉니다.

      http://blog.naver.com/hongjig?Redirect=Log&logNo=150011261731


      [-] Open API
      Open API 란? (한줄정의) 홈페이지 내의 유용한 정보를 홈페이지 외부에서 손쉽게 사용할 수 있게 해주는 기능입니다.
      예를 들어, 자신의 집(또는 회사)를 찾아오게 하기 위해서 지도 서비스 홈페이지로 부터 지도를 제공받아서 자신의 홈페이지에 걸어놓을 수 있습니다.
      다른 예로, ... 검색엔진의 검색어를 입력하고 결과를 보는 페이지를 자신의 홈페이지에 넣을 수 있습니다. 이러한 것이 하나의 Open API 입니다.
      이러한 Open API 는 아주 오래전 부터 존재 해 왔던 웹사이트의 주요 서비스로 조용하면서도 끈질긴 생명력으로 최근까지 애용되고 있습니다. 최근에 웹 2.0의 주요 기능 중 하나로 꼽히면서 Open API 기능에 대한 효과를 인정 받고, 웹 서비스의 전면부로 나왔습니다.
      과거에는 각 사이트에 개별적으로 간단한 인터페이스로 사이트내의 정보를 외부와 연결을 하였습니다. 물론 대형 서비스 업체들은 그에 걸맞은 스펙(규격 문서)을 제공하며 보다 낳은 서비스로 많은 유저를 확보하려고 노력을 해 왔습니다. 1990년 대 웹의 시작 시점부터 Open API 에 대한 표준 제정에 대해서 많은 움직임이 있었습니다만, 1990년 후반부에 들어서 Open API 의 표준이 하나씩 생겨나기 시작했습니다.

      국내의 대형 포털사이트들은 이미 많은 Open API 를 제공하고 있으며 이를 바탕으로 사용자들이 보다 더 쾌적한 환경에서 정보 서비스 이용을 하고 있습니다.
      대한민국의 1,2 위 순위를 다투는 최고의 사이트들은 각 사이트의 Open API 를 경쟁적으로 사용자들에게 제공하기 시작을 했으며 국내 최고라고 꼽는 인터넷(웹사이트) 업체를 예로 들자면, 개별 사이트 이용자들에게 어떻게 자사의 웹사이트에서 제공하는 Open API 를 활용할지에 대한 방법을 상세히, 그것도 CGI를 구성하는 스크립트 언어적인 설명을 포함해서 하는 것을 보니 왠지 사용자를 배려한다는 느낌보다 그렇게까지 해서라도 사용자를 참여시키려는 집착에 놀라울 따름입니다.

      Open API ... 무엇인지 느낌으로 와 닿나요? 그렇지 않다면 한줄 정의를 외우세요.
      더 알고 싶으시면, 검색 엔진에서 "Open API" 라고 쳐보세요. 정보는 널렸습니다. 굳이 몇가지 이곳에 링크를 기록하는 이유는 여러분들의 검색 시간을 덜고 좀 더 정확하고 알찬 정보를 제공하기 위해서입니다. 아래의 링크들을 확인하시면 Open API 의 열기가 얼마나 뜨거운지 아실것입니다.

      http://www.newswire.co.kr/read_sub.php?id=198312&ca1=전자통신-
      http://issue.nida.or.kr/board/007/060928153203001001.pdf
      http://blog.naver.com/dasantea/30722991
      http://www.hometown.co.kr/64
      http://channy.creation.net/blog/?p=299
      http://kr.ks.yahoo.com/service/ques_reply/ques_view.html?dnum=JAK&qnum=4650154&kscookie=1

      [-] 표준 규격
      (IETF(인터넷 엔지니어링 태스크 포스) 는 인터넷 기술 관련 표준을 정의하는 주체입니다. IETF 는 IAB(인터넷 아키텍쳐 위원회) 의 감독하에 표준을 제정합니다.)

      XML-RPC 에 표준이 있듯 Open API 에도 표준이 있습니다. 이미 많은 표준 규격이 정의 되었으며 그 표준 규격을 바탕으로 지금도 많은 사이트에서 Open API 를 작성하고 사용자들에게 제공을 하고 있을것입니다. 그러나 개별 사이트에 꼭 맞는 Open API 규격은 현재로서는 찾을 수 없습니다. 새로운 규격이 필요하며 Site Open API 가 그 한 부분을 담당할 것입니다. 물론 Site Open API 는 표준(국제 표준이나 인터넷 표준)으로 등록되지 않았으며 실무 표준이라고도 얘기하지 않습니다. 하지만 개별 사이트를 위해서 Open API 의 기능을 하기 위해 규격된 Site Open API 는 서버와 클라이언트 구현물이 있으며 서버 개발과 클라이언트 개발에 도움을 제공하고 있는 것이 사실입니다. 만약 자사이트에 Open API 제공이 필요하다면 이미 시행착오를 겪으면서 규격된 Site Open API 를 선택하는 것은 어떨까요?




      [-] SOA ( Site Open API )
      Site Open API 는 정보를 다루는 공간을 블로그나 홈페이지에 국한하지 않고, 보다 넓은 영역에서 사용이 가능하도록 기존 XML-RPC 구현물(API)들의 기능을 보완, 확장하였으며 (혹은 진행중에 있으며) 많은 영역에서 다루어지는 정보를 보다 자유롭게 교환하기 위해서 개발된 XML-RPC 바탕의 새로운 Open API 입니다.
      XML-RPC 에 대한 자세한 내용은 http://www.xmlrpc.com/http://www.xmlrpc.com/spec 를 참고하기 바랍니다. XML-RPC 에 대한 구현물(개발 방법, 개발 라이브러리)에 대해서는 http://www.xmlrpc.com/directory/1568/implementations 를 참고하십시오.
      SOA 에 대한 정보는 http://siteapi.kldp.net 을 참고하십시오.

      SOA 는 여러분의 홈페이지에 강력한 Open API 기능을 제공할 것입니다. Open API 는 더 이상 대형 사이트의 전유물이 아닙니다.

      SOA 로 뭘 할 수 있을까요?
      - SOA 는 Blogger API, Meta Weblog API 를 포함합니다. 이것은 곧 모든 블로깅 관련 툴을 사용할 수 있다는 뜻입니다.
      - 여러분의 홈페이지를 위해서 SOA 만의 특별한 메소드가 존재합니다. 주요 기능은 홈페이지 정보의 검색입니다. 사용자 정보 검색, 글 정보 검색, 쇼핑몰 정보 검색 등 많은 정보를 외부에서 접근하게 할 수 있습니다.



      [-] Blogger API, Meta Weblog API

      Blogger API 는 블로그 사이트를 위해서 제작된 표준 XML-RPC 규칙을 따르는 하나의 완전한 Open API 입니다. Blogger API 는 오래전부터 최근까지 계속해서 발전을 하고 있습니다.
      초기 Blogger API 의 기능을 보강한 것이 Meta Weblog API 입니다. 엮시 표준 XMLRPC 규칙을 준수합니다.
      이러한 Open API 는 웹서버에 설치가 되어 서버의 역활을 합니다. 이를 통해서 블로그의 정보를 데스크톱 응용 프로그램으로 편집할 수 있습니다.
      블로그 사이트의 정보에 접근(기록, 편집)하는 편집기들은 블로깅 클라이언트입니다. '원격 블로깅 툴(편집기)'이라는 표현을 쓰는 것이 올바르겠습니다. 이러한 편집기 프로그램은 무수히 많습니다. 소프트웨어 업체들이 앞다투어서 편집기를 선보이고 있습니다. 왜일까요? 그만큼 가치가 있고 블로거들이 선호를 하고 있기 때문입니다. 원격 블로깅 편집기에 대해서 자세한 것은 본 문서의 다른 항목을 참고하시기 바랍니다.

      국내의 유명 블로그 제공 사이트에서 이 Open API 들을 100% 그대로 제공하면서 자사이트의 이름을 붙여 EGLOOX+ API(가칭) 로 소개한 바 있습니다. 물론 이것 하나만으로 많은 인기 몰이를 했습니다. 그 이유는? 당연히 그만큼 그 활용성이 인정되어서지 않을까 생각을 합니다.

      요점정리를 해볼까요?
      블로그와 관련된 Open API 로서 Blogger API, Meta Weblog API 가 있습니다. 이러한 것들은 XML-RPC 표준을 따릅니다. 이 Open API 를 통해서 원격 블로깅이 가능합니다.

      그 외,
      Blogger API, Meta Weblog API는 Site Open API 속에 모두 포함이됩니다. 따라서 Site Open API 서비스를 하는 홈페이지는 원격 블로깅이 가능하다는 것을 뜻합니다. 뿐만 아니라 SOA 만의 많은 기능을 그대로 이용할 수 있습니다.



      [*] 원격 홈페이지 편집

      "홈페이지를 편집한다." ... ?? 좀 더 명확하게는 "홈페이지의 내용물(정보)을 편집한다." 입니다.

      이 문서에서 원격 블로깅을 하는 방법에 대해서 자세한 설명을 하지 않습니다. 그러나 충분한 개념과 그리고 관련된 유익한 정보를 얻을 수 있는 링크를 제공할 것입니다.

      홈페이지 내용물을 편집하는데에는 여러가지 방법이 존재합니다. 홈페이지의 HTML 파일을 FTP 를 통해서 다운로드 해서 편집을 한 다음 다시 FTP 를 통해서 업로드하면 됩니다. FTP 를 지원하는 편집기에서는 다운로드/업로드 과정이 필요 없을 수 있습니다. 위즈위그 편집기라면 더 바랄것이 없죠. 이러한 사용자의 요구를 통해서 점점 쉽게 변했습니다. 편집기에서 FTP 를 직접 지원하고 위즈위그 기능을 제공합니다.
      홈페이지의 HTML 파일 뿐만 아니라, 게시판의 내용을 변경하고자 한다면 어떻게 하면 좋을까요? 웹브라우저로 편집하면 되겠죠. 웹브라우저로 편집하는게 불편하지만 이미 손에 익어 있습니다.
      그러나 점점 쉽게 변해가고 있습니다. 웹브라우저 내에 위즈위그 편집기가 포함이 됩니다. DHTML, XHTML 등등을 넘어서 ActiveX 컴포넌트, 또는 웹브라우저 자체에 편집기능을 포함하는 것도 있습니다.

      홈페이지의 정보를 편집하는데에 있어서도 많이 편해졌습니다. 최근에는 Open API 를 통해서 훨씬 많이 편해졌습니다. 윈도우즈 응용프로그램을 통해서 직접 게시물을 수정할 수 있습니다.

      본인이 직접 작성한 블로그 편집기가 있습니다. 윈도우즈 XP 에서 실행이되며(기타 운영체제에서 테스트되지 않았습니다.) 위즈위그 HTML 편집 기능을 포함합니다. 명칭은 '장난'입니다. '멀티 블로깅 툴-장난' 이라고 불려지고 싶구요, 한번 글 쓰기로 수십 수백개의 블로그에 글을 기록할 수 있습니다. 자세한 정보은 http://jangnans.com 을 참고하십시오.
      (http://jangnans.com/?cate=bbs&mode=read&idx=289)

      MS 사에서도 여러가지 편집기를 내 놓고 있습니다. MS 워드 프로세스 뿐만 아니라, Windows Live Writer 등 많은 편집기를 출시하고 있습니다. 이런 편집기들은 모두 Open API 를 지원합니다. 따라서 이런 툴을 이용해서 문서를 편집한 뒤 곧바로 게시판이나 블로그에 글을 등록할 수 있습니다.
      MS 사 뿐만 아니라 국내의 많은 기업에서 웹 편집기를 쏟아내고 있습니다. 본인이 개인적으로 멀티 블로깅 툴을 만들 정도인데, 기업들이야 오죽하겠습니까. 많은 편집기가 유료 또는 무료로 사용이 가능합니다.

      [-] 원격 블로깅

      위 항목에서 설명한 '블로깅', '원격 홈페이지 편집'과 별 차이 없는 항목일 수 있습니다.

      그러나 개념적인 방법을 정리해봅시다.

      일반적으로 블로그에 글을 쓰기 위해서는 웹 브라우저로 블로그 사이트에 접속을 해서, 로그인을 하고, 글 쓰기 버튼을 클릭한 다음, 글을 쓰고 출판을 하게됩니다.
      전혀 어려운것 없죠? 너무나 자연스러운 부분입니다. 사실은 아주 불편한 방법이지만, 너무나 익숙해져 버린 나머지 불편한 것인지 조차 판가름을 할 수 없습니다.

      원격 블로깅은 윈도우즈에서 실행되는 응용 프로그램을 실행해서 글을 쓰고 저장을 하는 것입니다. 맨 처음에 블로그 정보를 기록하기 위해서 EndPoint 와 아이디, 비밀번호를 기록해야하며 필요한 경우 그 외에 몇가지 설정을 더 해야합니다.

      너무나 불편한 웹브라우저로 글을 쓰는 것은 너무나 익숙해져 있는데, 아주 편한 원격 블로깅 툴로 글을 쓰는 것은 조금도 익숙하지 않아 불평이 이만 저만이 아닙니다. 원격 블로깅의 길이 너무 어려운 나머지 원격 블로깅을 하는 블로거들에게 욕을 바가지로 퍼붓습니다. 왜 익숙한 웹 브라우저를 놔 두고, 사서 고생을 하느냐구...

      처음 하시는 분들에게는 엮시나 쉽지가 않습니다. 도움이 되기를 바라며 여기서는 개념에 대해서 설명을 하겠습니다.
      우선 자신의 블로그에 글을 쓰기 위해서는 아이디와 비밀번호가 있어야합니다. 이것은 웹 브라우저로 블로그에 글을 쓰나 원격 블로깅 툴을 통해서 글을 쓰나 마찬가지입니다. 꼭 필요한 것입니다. 그리고 블로그 사이트 주소가 있어야합니다. 웹브라우저로 글을 쓰나 원격 블로깅 툴을 통해서 글을 쓰나 마찬가지인 부분입니다.
      이것이 끝인가요?
      네, 그렇습니다. 라고 말씀드리고 싶지만, 남은 것이 있습니다.
      잘 만들어진 블로그 사이트의 Open API 와 잘 만들어진 원격 블로깅 툴의 만남이라면 이것이 끝입니다. 그러나 그렇지 못한 경우에는 다음과 같은 과정이 추가로 필요합니다.

      - EndPoint 의 기록
      - Open API 의 선택

      원격 블로깅을 할 때에는 EndPoint와 OpenAPI의 선택이 필요합니다. 잘 만들어진 경우에는 이러한 것들이 자동으로 설정이 됩니다. 그러나 잘 만들어지지 못한 경우에는 수동으로 설정해야합니다. 그리고 이러한 정보는 사이트 관리자에게 물어서 알아내어야합니다.

      정리해볼까요?
      원격 블로깅을 하기 위해서는 블로그 사이트 주소, 아이디, 비밀번호가 필요합니다.
      특별한 경우에는 EndPoint 와 OpenAPI 의 선택이 필요합니다. 이 정보는 사이트 관리자가 알고 있습니다.
      이러한 정보를 원격 블로깅 툴에 설정을 하고, 글을 쓰면됩니다. 글을 편집하는 부분에 있어서는 웹브라우저보다 훨씬 낳은 느낌을 제공할 것입니다.



      [-] 원격 홈페이지 편집 실제 예
      블로그 Open API 는 블로그의 정보 편집 기능을 제공합니다. Site Open API 에는 블로그 Open API 가 포함이됩니다. Site Open API 는 블로그가 대상이 아니라, 사이트(홈페이지)가 대상입니다. 따라서 Site Open API 를 통해서 블로깅을 하는 것은 블로그의 정보를 편집하는 것이아니라 홈페이지의 게시물 같은 내용을 편집하는 것입니다. 블로그의 글을 편집하는 것이 아닌 자신의 홈페이지(또는 자긴이 가입된 홈페이지), 사이트라고 생각을 하면 됩니다.

      원격 홈페이지 정보의 편집, 또는 원격 블로깅 방법에 대해서 궁금하시죠?
      여기 그 정보가 있는 링크를 제공합니다.

             http://thruthesky.webzero.co.kr/?cate=bbs&mode=read&idx=290

      위 링크된 페이지에는 테스트용 글쓰기를 위한 준비가 되어 있습니다. 위 페이지의 설명에 따라 글을 등록해 보시면 누구나 손쉽게 원격 블로깅에 대해서 알 수 있을 것입니다.




      [-] 추천 원격 블로깅 툴

      다음은 여러분들에게 추천하는 웹 편집기입니다. 블로깅을 하신다면, 꼭 한번 사용해 보십시오. 아마 환장할 것입니다.

      ** MS 사의 윈도우즈 라이브 라이터(Windows Live Writer)
             MS 사의 제품을 소개하고 싶지는 않습니다. 하지만, 수십가지의 원격 사이트 편집기를 사용해 본 결과 가장 잘 만들어졌다고 개인적으로 판단이됩니다.        
             http://windowslivewriter.spaces.live.com/
             http://nosyu.egloos.com/2732428
             http://www.choboweb.com/2006/11/02/%ec%96%b4%eb%96%a4-%eb%b8%94%eb%a1%9c%ea%b7%b8-%ec%97%90%eb%94%94%ed%84%b0%eb%a5%bc-%ec%93%b0%ec%8b%9c%eb%82%98%ec%9a%94-windows-live-wirter/
             http://idealist.egloos.com/2710808

      ** Zoundry 블로그 Writer
             사용하기가 쉬운편은 아니나, 사용해 본 것 중 가장 넓은 API 범위를 지원한다고 생각합니다.
             http://www.zoundry.com/download.html

      ** 퍼포먼스 (Performance) 파폭 에드온(Fire Fox Addon)        http://performancing.com/firefox

      ** 장난 - 멀티블로깅 툴
             http://lopy.egloos.com/498800
             특징: 멀티 블로깅(한번의 글 쓰기로 수십, 수백개의 블로그에 글 등록), 여러개의 글 한번에 삭제.



      [-] 추천 하지 않는 편집기들. 그나마 쓸만 한 것들.
      Site Open API 테스트를 위해서 직접 사용해 본 것들이다. 실제로 사용에 어려움이 있는 것들이 많았으며,
      ** Qumana http://www.qumana.com/download.htm


      [0] 그 외 편집기들 (사용해 보지 않았거나 사용에 불편함이 있는 것들)

      ** MS Word 2007
             http://plaming.egloos.com/2875028
             http://www.zziuni.pe.kr/zziuni/346
      ** ecto http://ecto.kung-foo.tv/
      ** 나모웹에디터
      ** Lycos의 블로깅 툴, Qumana http://lycos.qumana.com/
      ** Zoho Writer http://writer.zoho.com/jsp/home.jsp
      ** BlogJet http://www.blogjet.com/
      ** BlogDesk http://www.blogdesk.org/
      ** w.bloggar http://wbloggar.com/
      ** RocketPost 2 http://www.anconia.com/rocketpost/
      ** Semagic http://semagic.sourceforge.net/
      ** MySpace Blog Editor https://addons.mozilla.org/firefox/3229/
      ** WB Editor http://www.wbeditor.com/
      ** Post2Blog http://www.bytescout.com/post2blog.html
      ** xfy Blog Editor http://www.xfy.com/personal/blog/
      ** Bleezer http://larryborsato.com/bleezer/
      ** Blog Editor http://blog-editor.qarchive.org/downloads.html
      ** Alive Diary http://www.tucows.com/preview/411931
      ** Writely (Google Docs) http://www.writely.com/
      ** http://multiblog.skinmaster-co-uk.qarchive.org/

      [-] 기타 블로그 Open API 관련 소프트웨어들
      ** http://www.newfreedownloads.com/Web-Authoring/Website-Promotion/Blog-Blaster.html
      ** http://www.stardock.com/products/blognavigator/
      ** http://www.coffeecup.com/flash-blogger/


      [*] SOA (Site Open API)

      Open API 는 상당히 매력적인 것입니다. 우리가 현재 사용하고 있는 원격 블로깅 툴만 봐도 그 위력을 쉽게 알 수가 있습니다.
      그동안 Open API 는 대형 인터넷 서비스 업체의 전유물로 인식이 되어왔습니다. 최근에는 국내의 설치형 블로그 소프트웨어 제작 사이트에서 블로그 Open API 의 기능을 기본적으로 제작해서 제공을 하고 있습니다.
      하지만, 개별 사이트에서 Open API 를 제공하기란 만만치가 않습니다.
      그러나 전혀 불가능한것도 아닙니다. 여기 SOA 가 있습니다. SOA 는 현제 http://siteapi.kldp.net 에서 개발이 이루어지고 있으며, 2006년 말 기점으로 제로보드4, 제로보드5, 그누보드4, 장난-홈툴즈, 알지보드 를 통해서 운영되는 홈페이지들은 모두 SOA 를 이용할 수 있습니다. 만약 여러분의 홈페이지(또는 블로그, 쇼핑몰)이 이러한 홈페이지 프로그램을 바탕으로 운영이 되고 있다면 지금 즉시 여러분의 홈페이지에 강력한 Open API 를 제공할 수 있습니다.
      여러분의 홈페이지에 좀 더 낳은 기능을 제공하기 위해서 SOA 는 계속해서 변하고 있습니다. 혹시 여러분의 홈페이지에 맞도록 SOA 가 변경되지는 않았을까요? http://siteapi.kldp.net, http://jangnans.com 을 방문해서 살펴보십시오.

      SOA 의 주요 기능은 아래와 같습니다.
      - 다수의 사이트를 위한 정보의 규격.
      - 사이트 내의 정보 검색.
      - 사이트 내의 정보 편집. (원격 블로깅 툴과 같은 편집기로 홈페이지의 내용을 직접 편집)
      - 사이트간의 정보 교류(연결).


      물론 위에 나열된 대부분의 기능들은 대형 인터넷 서비스 사이트에서는 자체적으로 개발을 해서 제공을 하는 기능들입니다. 그러나 Site Open API 는 한 개인의 사이트가 아닌 많은 사이트들이 손 쉽게 이용할 수 있도록 규격되었습니다.

      Site Open API 를 가장 잘 활용하는 소프트웨어 중 하나는 '사이팅'입니다. 사이팅은 실시간으로 홈페이지의 새로운 정보를 감지 할 수 있습니다. 예를 들어 홈페이지에 새로운 가입자나 새로운 글이 등록되었을 때, 웹브라우저의 도움 없이 실시간으로 그 정보를 확인할 수 있습니다. 실시간 홈페이지 모니터링 툴 '사이팅'은 http://jangnans.com 에서 얻을 수 있습니다. 본인의 경우 홈페이지가 여러개 됩니다. 사이팅 소프트웨어를 이용해서 여러개의 홈페이지들의 새로운 정보를 실시간으로 확인을 합니다. 누가 가입했는지, 어디 홈페이지에서 어떤 글이 올라왔는지, 광고글이 올라오지는 않는지... 홈페이지가 아무리 많아도 실시간으로 확인을 할 수 있습니다.


      SOA 를 이용한 사이트간의 정보 교류는 포괄적인 의미의 기능입니다. 구체적인 내용은 http://jangnans.com 에서 얻을 수 있습니다.

      위에 나열된 SOA 의 기능이 어쩌면 2006 년 말 현재의 주요 기능일지 모르겠습니다. 지속적인 개발이 이루어지고 있으며 영역을 넓혀가고 있습니다. http://jangnans.com 의 '장난 - 홈툴즈' 프로그램을 통해서 SOA 가 처음 제작되며, 차츰 다른 유명한 홈페이지 게시판 프로그램을 바탕으로 포팅을 하고 있습니다. 자신의 홈페이지에 직접 SOA 를 추가하기 위한 프로그래밍을 하거나 다른 플랫폼이나 언어를 통해서 구현을 원하시는 분은 연락을 주십시오. 도움이 될 수 있기를 바랍니다.

      요점 정리 한번 할까요?
      SOA(Site Open API)는 대형 사이트 뿐만 아니라, 중,소형 개인 사이트를 위해서 Open API 서비스를 위한 규격입니다. 국내의 유명 홈페이지 게시판 프로그램들에 기본적으로 제공이됩니다.


      [*] 주의점

      원격 블로깅이나 기타 Open API 와 관련된 작업을 할 때에 아이디와 비밀번호를 기록해야한는 경우가 있습니다., 이때 잘못된 생각을 가지고 아이디와 비밀번호를 다른 용도로 사용하는 툴이 있을 수 있습니다. 특히, 인증되지 않은 사이트에서 원격 블로깅이 가능하게 한다며 아이디와 비밀번호를 입력하라는 경우가 있습니다. 실제로 가능한 경우이며 이런 이유로 국내 대형 블로그 사이트가 Open API 의 서비스를 중지한 일이 발생했습니다.
      어떠한 경우에서든지 타 사이트(잘 모르는 사이트)에 자신의 아이디와 비밀번호를 기록해서는 안됩니다. 물론 데스크톱 응용프로그램이라고 해서 100% 안전한 것은 아니지만, 하지만 그런 위험적인 요소가 훨씬 줄어듭니다.


      [*] 기타

      [-] Open API 관련 개발

      Open API, XML-RPC 작업에 관심이 있다면, 다음의 링크를 참고하십시오.
      xmlrpc & xml :
      http://trio.co.kr/webrefer/xml/xml10.html

      xmlrpc & RSS 2.0 :
      http://kin.naver.com/knowhow/entry.php?d1id=8&dir_id=8&eid=9xPAUaXu6DWZw1UzR30Nu8IdmgsDgGgi
      http://cafe.naver.com/bindung.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=117
      http://blogs.law.harvard.edu/tech/rss

      xmlrpc & Blogger API 프로토콜 :
      http://www.blogger.com/developers/api/1_docs/
      http://xmlrpc.free-conversant.com/docs/bloggerAPI

      xmlrpc & metaWeblog API 프로토콜 :
      http://www.xmlrpc.com/metaWeblogApi
      http://www.xmlrpc.com/spec
      http://blogs.labo-dotnet.com/vlad/services/metablogapi.aspx
      http://www.sixapart.com/developers/xmlrpc/metaweblog_api/metaweblognewpost.html
      http://txp.kusor.com/rpc-api/metaweblog-xml-rpc-api

      기타 참고 :
      http://en.wikipedia.org/wiki/MetaWeblog

      [-] 보안

      Site Open API 는 타 Open API 나 웹 서비스와 마찬가지로 HTTP 프로토콜을 사용합니다.
      따라서 기존의 웹 브라우저를 놓고 보안의 위험성에 대해서 비교를 한다면, 웹브라우저보다 조금도 덜하거나 더하지 않습니다. 왜냐하면 Site Open API 그 자체가 기존의 웹브라우저 환경과 동일하기 때문입니다. 링크를 참조해 보십시오. 도움을 될 것입니다. 를 참고하십시오.

      반응형
      반응형
      반드시 읽어봐야 할 책!!


      반응형

      - written by ETRI 차세대 PC 연구그룹 책임연구원 한동원


      1. 서론

      MIT 미디어랩의 니콜라스 네그로폰데 교수는 “지금까지의 PC는 기술발전으로 보다 빠르고 가볍고 많은 정보를 저장할 수 있게 되었지만, 미래의 PC는 사용자의 문화가 용도와 가치를 결정하는데 큰 영향을 미치게 될 것이므로 속도가 얼마나 빠른가 하는 경쟁보다는 디지털 시대의 문화를 얼마나 잘 담아 낼 수 있느냐가 선택의 기준이 될 것이다”고 공언한 바 있다.

      지금까지 대표적인 정보이용 수단인 PC는 성능이나 처리속도와 같은 기술 중심에서 기능이나 사용자 편리성 등이 강조된 인간 중심의 컴퓨터로 전이되는 현상을 보이고 있으며, 컴퓨터와 패션, 의류 등과의 접목은 웨어러블 컴퓨터와 같은 신 개념의 정보기기 출현을 앞당기고 있다.

      또한 인터넷을 기반으로 하는 정보통신 인프라에서 사용자들은 더 이상 PC에만 의존하지 않으며, 사용자가 언제, 어 디서든지 인터넷에 쉽게 접속할 수 있는 정보통신 이용환경의 변화에 따라 정보단말과 사용자의 제한성이 사라지는 새로운 정보서비스 패러다임의 등장으로 사용자가 원하는 정보를 찾아가는 기존의 정보서비스 개념에서 어디에서나 자신이 원하는 정보가 편재되어 있는 유비쿼터스 정보서비스 시대로 접어들고 있음을 보여준다.

      따라서 기술의 융합화, 서비스의 광역화, 정보기기의 소형, 경량화 추세로 정보기기는 사용하기 편리하고, 착용 가능한 형태로 인간 중심의 컴퓨팅 환경을 제공하게 되어 궁극적으로는 기계화된 인간성을 회복하고 신체적, 정신적 능력을 고양시켜 줄 것이다.

       

      2. 차세대 PC 진화 방향

      . 기술 범위

      차세대 PC의 기술 범위는 인간 친화적인 정보기기를 구성하기 위한 것으로서 휴대성과 편의성을 개선시키기 위하여 언제, 어디서나 컴퓨팅을 실현할 수 있어야 하며, 항시 들고 다닐 수 있을 정도의 소형 컴퓨팅 기기를 통하여 유비쿼터스 컴퓨팅 서비스를 제공할 수 있으며, 컴퓨팅 기능이 주위환경에 내재되어 이로부터 정보를 획득하여 활용하거나 사용자가 인식하지 못하는 상태에서도 컴퓨팅 기능을 수행할 수 있어야 한다.

      따라서 차세대 PC는 착용성, 저전력, 소형화 기술에 의한 스마트 웨어 등과 같은 플랫폼 분야와 재래식 키보드, 마우스, 모니터를 대체할 초소형 키보드 및 디스플레이 등을 포함하여 양손의 사용을 자유롭게 하는 입출력 장치와 음성, 시각, 촉각, 후각, 미각 등 오감 정보처리 기술을 위한 차세대 사용자 인터페이스, 그리고 데이터 송수신을 위한 BAN(Body Area Network), WPAN(Wireless Personal Area Network) 기술 등을 주요 대상으로 본다.

      차세대 PC를 구성하는 기술은 크게 차세대 PC 플랫폼, 초단거리 개인 무선통신 인터페이스, 스마트 I/O, 사용자 친화형 소프트웨어, 오감 정보 UI로 구분된다. 차세대 PC 플랫폼은 휴대형 플랫폼, 착용형 플랫폼, 신체 내장형 플랫폼, 초소형 저전력 소프트웨어 플랫폼 등으로 분류되며, 초단거리 개인 무선통신 인터페이스는 개인통신접속, 신체통신접속, 스마트 I/O는 착용형 I/O Invisible I/O, 사용자 친화형 소프트웨어는 휴먼 에이전트, 감성 에이전트, 시큐리티, 오감 정보 UI는 오감 센서, 오감 인터페이스, BCI(Brain Computer Interface) 등으로 구성된다.

      . 서비스 진화 방향

      기술 융합화 현상의 급진전과 통신, 가전, 컴퓨터간의 상호 영역이 파괴되는 디지털 컨버전스 추세에 따른 PC의 역할 변화 즉, 정보생산자와 소비자에 대한 패러다임 변화가 가속화되며, 정보획득의 제한이 없는 새로운 정보서비스의 제공으로 사용자의 디지털 라이프스타일에 부합하는 정보이용 기기의 변화가 예상된다.

      정보통신 서비스가 새롭게 출현될 때마다 각기 다른 단말기들을 구입해야 하는 현 시점에서볼 때, 단기적으로는 휴대형 정보단말과 휴대폰 기능이 접목되어 팩스, 전자우편, 영상전화 등과 같은 멀티미디어 기능이 융합된 복합 정보단말 형태와 이에 필요한 소형화, 무선화를 위한 플랫폼 기술 발전이 예측된다.

      장기적으로는 음성, , 제스처를 통한 지능형 사용자 인터페이스, 고속 유무선 통합망에 의한 고품질 멀티미디어 처리기능, 휴대화, 저가화를 위한 고성능 저전력 시스템 칩 기술, 네트워크 접속형 시스템 소프트웨어 기술 등의 발전으로 이동통신 단말과 고속 통신망이 결합된 정보기기 형태로 발전될 것으로 전망된다.

      차세대 PC는 기술의 융합화와 정보기기의 소형, 경량화 추세로 차세대 PC의 진화방향과 발전요인에 따라 PDA, 전자지갑 등 지니고 다니는 전자비서 형태에서 손목시계와 같은 액세서리형, 신체 착용형 입는 컴퓨터, 향후 신체 내장형 컴퓨터인 먹는 컴퓨터까지 나아가 차세대 PC는 종래의 컴퓨터에서 보다 진화된 형태의 미래형 컴퓨터의 모습을 가질 것으로 보인다.

      앞 으로 입는 컴퓨터는 의복이나 액세서리 개념의 컴퓨터에서 인간의 오감 메커니즘을 모방하여 자연스럽고 편리하게 컴퓨터와 때와 장소의 제한없이 대화할 수 있도록 기기와 인간사이의 상호작용을 개선시키는 인간 중심의 휴먼 인터페이스 기술로 발전될 것으로 전망된다.

      또한 일상생활에서 매일 사용하는 기기에는 임베디드 프로세서와 무선통신 인터페이스, 소프트웨어 등이 탑재되어 일상생활 물건들이 지능화된 기기로 새롭게 변모되어 정보의 교환 대상이 사람과 사람, 사람과 기기 중심에서 일상생활의 사물과 기기들이 상호 접속되어 사용자가 원하는 것을 사람의 해석이나 간섭없이 처리하고 이를 사용자에게 제공하게 되는 유비쿼터스 컴퓨팅 환경으로 변모될 것으로 보인다.

      이와 같은 개념에서 유비쿼터스 컴퓨팅은 “언제(always), 어디서나(anywhere) 존재한다”는 뜻으로 물이나 공기처럼 우리가 생활하는 세계 도처에 컴퓨팅 환경이 편재되어 있는 상태를 말하며, 유비쿼터스 컴퓨팅 환경에서의 입는 컴퓨터는 메인프레임, PC에 이은 차세대 컴퓨팅 패러다임으로 다가오고 있다.

      차세대 정보이용 단말로서의 입는 컴퓨터는 사람이 옷을 입듯이 몸에 착용할 수 있는 컴퓨터로서 작고, 가벼우며, 벨트나 의복 재킷 등에 넣고 이동하면서 사용할 수 있는 정보기기이며, 포켓 사이즈의 화면이나 헤드마운트 디스플레이를 사용하며 정보 입력방식은 음성명령어나 손목에 부착된 무선 입력기 등을 이용하는 컴퓨터를 지칭한다.

      입는 컴퓨터에서는 사용자의 신체적인 확장성을 제공하기 위하여 센서와 신체에 부착된 기기들간의 네트워크 구성이 가능해야 하고, 인지성 제공을 위해서는 신체와 지속적인 상호작용 및 상황인지 기능을 제공해야 한다.

      그리고 일상생활에서의 편의성과 쾌적성 제공을 위해서는 일상생활을 유지하는데 필요한 기본적인 수단 중의 하나이며, 연령, 성별, 직업, 패션, 라이프스타일, 기후, 문화 등과 같은 개인별 특성과 주변 환경에 따라 인체와 가장 밀접한 생활환경을 가지는 의복, 시계, 안경, 반지, 신발 등과 같은 액세서리 형태를 가지게 될 것이다.

      . 주요 기술 동향

      초소형 플랫폼은 전 세계적으로 다양해지는 정보기기 제품을 위한 초소형 초절전 고성능 SoC 핵심 부품과 표준화된 인터페이스로 동적 재구성 가능한 플랫폼 및 생체신호 센서, 플렉시블 디스플레이, 초소형 대용량 저장장치 및 배터리 기술을 중심으로 발전되고 있다. 미국의 롤트로닉스사와 씬필름테크놀러지사에서는 두루마리 가공기술(Roll to Roll)을 이용한 플렉시블 로직-메모리-스토리지-디스플레이, 필름 배터리 등에 대한 기술개발이 진행되고 있으며, 웨어러블 컴퓨터의 전원 문제 해결을 위한 방안으로 인피니언사에서는 의복 내부와 외부의 온도차이에 의한 전원 발생기술에 대한 연구가 활발히 진행되고 있다.

      사용자 인터페이스 기술은 에이전트 기술과 멀티모달 및 상황 인식을 지원하는 HCI(Human Computer Interaction) 기술로 발전하며, 유비쿼터스 컴퓨팅 환경이 보편화되는 시대에는 정보기술을 이용하는 일반적인 수단이 지금까지의 유니모달(unimodal)에서 벗어난 멀티모달(multimodal) 기반의 인터페이스 기술로 발전되어 시각, 청각 이외에 다양한 휴먼 인터페이스 기술을 실현하기 위하여 햅틱(haptic) 장치 등을 이용한 촉각 인터페이스 기술이 부각되고 있다.

      또한 생체인식 기술의 발달은 사용자의 얼굴, 표정 등으로부터 얻어낸 정보를 바탕으로 사용자의 감성까지 컴퓨터로 전달할 수 있을 것으로 전망되며, 오감 정보처리 기술은 시각, 청각, 촉각 중심에서 후각, 미각 정보처리와 오감을 융합 재현하여 현실감 있는 서비스를 제공하는 기술로 발전하게 되어 궁극적으로 차세대 PC는 플랫폼의 소형화, 에이전트 소프트웨어에 의한 지능화와 아울러 HCI에 의한 실감화 추세로 발전될 것으로 전망된다.

      3. 차세대 PC 산업 특성

      . 차세대 PC 표준화 동향

      차세대 PC 시장은 낮은 진입장벽, 참여기업들의 이질성, 제품의 다양성, 산업간 융합에 따라 언제라도 치열한 경쟁국면에 돌입할 수 있는 특성을 가지고 있으므로, 신제품이 지속적으로 출시되고 라이프사이클이 짧아 제품간, 제품군간, 기업간 복합적인 구도가 형성되어 경쟁이 첨예한 분야이다.

      따라서 차세대 PC 산업은 PC의 윈도(MS), CPU(인텔)와 같은 시장 주도형 독점기술이 부재하며, 시장 특성상 표준이 확립되지 않은 분야이므로 지배적 경쟁구도가 불명확한 가운데 치열한 표준 경쟁이 가속화될 전망이다.

      차세대 PC에서의 표준은 하나의 핵심 표준 주체가 없는 반면, 구성되는 기술별로 추진되고 있으며, 공식 표준화 단계보다는 시장 및 기업 등에서 사실(defacto) 표준화로 진행되고 있다.

      차세대 PC의 대표적인 표준화 활동은 TI ST 공동으로 무선 핸드헬드 기기 인터페이스 표준 규격인 MIPI(Mobile Industry Processor Interface)를 제정하여 모바일 응용 프로세서를 위한 하드웨어 및 소프트웨어 인터페이스를 위한 표준 확립과 촉진을 위하여 단체를 구성하였으며, 핸드셋, 반도체, R&D 컨소시엄, 하드웨어 주변장치, 운영체제, 미들웨어 및 응용 소프트웨어 개발업체들이 참여하고 있다.

      웨어러블 네트워크 분야에 있어서는 필립스, 소니, 노키아 등에서 다양한 응용에 근접장 통신 기술구현 및 표준화 촉진을 위하여 2004 3 NFC(Near Field Communication) 포럼을 구성하였으며, NFC 기술은 터치(touch) 기반의 상호 작용 기술로써, 사용자들은 스마트 기기들을 손가락으로 건드려 서로 다른 기기들을 연결시킬 수 있는 직관적인 방식을 통하여 콘텐츠와 서비스에 접근할 수 있다.

      WWRF(Wireless World Research Forum)에서는 미래 무선통신 시스템 설계에 대한 비전 제시와 아울러 차세대 PC 관련 활동은 근거리 무선통신 시스템 표준그룹인 WG5에서 웨어러블 네트워크 분야의 WBAN(Wireless Body Area Network) WSN(Wireless Sensor Network) 기술과 응용에 대해 다루고는 있으나, 아직 구체화된 표준 모델이 설정되지 않은 단계에 있다.

      사용자 인터페이스 분야는 ECMA(European Computer Manufactures Association, 유럽 컴퓨터 조합연맹) TC32(Communication Network and Systems Interconnection)/TG11 (Computer Supported Telecommunications Applications: CSTA)에서 멀티모달 voice 브라우저에 대한 표준화가 추진되고 있다.

      . 차세대 PC 특허 동향

      차세대 PC의 기술범위와 구성요소 분류에 따른 특허 출원 동향을 살펴보면, 국가별로는 미국 37%(425), 한국 35%(403), 일본 22%(256), 유럽 6%(74) 순이며, 미국과 일본은 1980년 이후 지속적으로 출원되기 시작했으며, 한국은 1990년대부터 시작되어 1998년 이후로 지속적인 증가추세를 보인다.

      차세대 PC의 기술별 특허 출원 동향은 초단거리 개인 무선통신 인터페이스의 비중이 47% (539), 차세대 PC 플랫폼이 27%(307)의 비중을 차지하여 전체 기술의 주류를 이루고 있으며, 스마트 I/O 12%(139), 사용자 친화형 소프트웨어가 8%(98), 오감 정보 UI 6%(75)로 나머지 비중을 차지한다. 이를 통하여 유비쿼터스 컴퓨팅 환경에서의 차세대 PC를 구성하는 초단거리 개인 무선통신 인터페이스 기술이 부각되고 있으며, 국가별 기술분류를 살펴보면 한국, 미국, 일본은 초단거리 개인무선 통신 인터페이스로 각각 218, 163, 137건이 가장 많이 출원되었고, 유럽은 차세대 PC 플랫폼 분야에서 27건으로 다른 국가들과는 다른 경향을 보인다.

      4. 유비쿼터스 디지털라이프스타일

      2004년 2월 프랑스에서 개최된 3GSM 월드 전시회와 미국의 CTIA 와이어리스 2004 등에서 웨어러블 테크놀러지 패션쇼를 통해 차세대 PC에 대한 세계인들의 관심을 고조시키고 있다. 이러한 맥락으로 2004 10월에는 정보통신부에서 주최하고 한국전자통신연구원과 정보통신연구진흥원 등 주관으로 웨어러블 컴퓨터 패션쇼가 서울에서 개최되었다.

      정보통신부에서 추진하는 IT839 전략의 차세대 PC 선도기술개발과제를 중심으로 유비쿼터스 시대에 신 개념의 디지털라이프스타일에 대한 새로운 방향성과 가능성을 제시하는 자리로써 “Everywhere Every wears Technology”라는 주제로 Urban Traveler, Smart Worker, Happy Nomad와 같은 부제로 구성되었다.

      Urban Traveler는 비즈니스 업무와 도시 일상생활 속의 차세대 PC, 유비쿼터스 시대의 모바일 오피스로 구성되며, Smart Worker는 사용자를 찾아오는 U-서비스, 핸즈프리 워커, Happy Nomad는 퍼스널 헬스케어, 웰빙 스포츠, 엔터테인먼트 등으로 구성되어 우리의 일상생활, 근무환경, 여가생활 등 다양한 상황에서 나타나는 패션과 IT기술을 접목시켜 웨어러블 컴퓨터와 같은 차세대 PC에 대한 새로운 방향성과 미래 전략산업으로서의 새로운 발전 가능성을 제시한 것으로 평가된다.

      따라서 차세대 PC는 언제, 어디서나, 누 구나 자신만의 디지털라이프스타일을 즐길 수 있는 보편적인 정보통신 이용환경을 제공함과 아울러 우리가 원하는 장소에서 원하는 시간에 원하는 일들을 함으로써 우리의 일상생활 속에 새로운 변화를 가져다주는 유비쿼터스 시대의 정보생활 필수품 개념으로 자리매김할 것으로 보인다.

      <참 고 문 헌>

      [1]    한동원, “차세대 PC와 유비쿼터스 컴퓨팅 패러다임,” 한국정보기술학회, 2003. 12.

      [2]    박준석, “차세대 PC 발전 전망,” 정보통신연구진흥원, 주간기술동향 1148, 2004. 6. 2.

      [3]    한국정보통신기술협회, “IT839 전략 표준화 로드맵,” 2004. 11.

      [4]    정보통신연구진흥원, “IT839 전략 기획보고서-차세대 PC,” 2004. 6.

      [5]    Venture Development Corporation, “The Global Market for Wearable Computers: The Quest for Killer Applications,” 2002. 8.

      반응형
      네티모 조사…좌석점유율 최대 10%P 차이


      게임 장르에 대한 선호도가 지역별로 다른 것으로 나타났다.

      PC 방용 솔루션 전문 업체 네티모커뮤니케이션즈(www.gamereport.co.kr)가 전국 5000여개 PC방을 대상으로 게임 장르별 좌석 점유율 조사한 결과, 동일 장르 게임이 지역에 따라 최대 10% 포인트까지 점유율 편차를 보이고 있는 것으로 조사됐다.

      전국적으로 점유율 40%를 넘나들며 가장 높은 시장 점유율을 기록하고 있는 MMORPG 장르 만해도 제주도는 44% 점유율을 보였지만 대전에서는 36.9%에 그쳤다. RPG 다음으로 인기 장르인 FPS 게임 또한 대구에서는 29%가 넘는 점유율을 기록했지만 광주에서는 20%에 그쳐 지역별 편차를 드러냈다.

      MMORPG와 FPS 같은 인기 장르가 아닌 경우에도 지역별 선호도가 갈렸다. 최근 1~2년 사이 개발 러시를 이루고 있는 스포츠 게임의 경우 대전과 제주 지역에서 강세를 보이고 있는 것으로 조사됐다. 다른 지역 대부분 6%대 점유율을 보이는 스포츠 장르가 두 지역에서만 8.7%대를 넘어서고 있다.

      또 온라인 아케이드 게임만 놓고 보면 광주가 6.5%가 넘는 점유율로 전국 최고치를 기록했으며, 대구가 2.5%로 최저치를 보였다. FPS게임과는 대조적인 양상이다. 실제 영남 지역에서 부산을 제외한 대구, 울산 등지서는 저연령 층이 즐기는 아케이드 캐주얼 게임이 약세를 보이고 있는 반면, 20대 이상 성인들이 즐기는 FPS 장르가 강세를 보이고 있다.

      인기 장르 가운데 지역별 점유율 차이가 적었던 것은 RTS 게임인 것으로 나타났다. RTS 장르에서는 서울지역이 17%로 가장 높았으나, 나머지 지역들도 대부분 14%대 점유율 분포를 보여 큰 차이가 없는 것으로 조사됐다.

      이 처럼 각 지역별로 인기 장르에 차이를 보이고 있는 것에 대해 네티모 관계자는 "지역별로 발생할 수 있는 정서와 지리적 요인이 복합적으로 게임 선택에 영향을 끼치기 때문"이라며 "그러나 이는 세계 어디에서나 흔히 볼 수 있는 현상"이라고 말했다.

      네 티모커뮤니케이션즈는 약 5000여개 회원 PC방을 확보하고 있는 PC방 솔루션 전문업체이다. 이 회사는 전국 회원 PC방의 PC에서 실행되는 게임에 대한 정보를 집계해 서비스하는 `PC방 전문 리서치 서비스`인 `게임리포트' 사업을 전개하고 있다
      반응형
      IE 설계 변경에 따른 영향
      IE 설계 변경에 따라서 달라지는 것은 무엇일까? 웹 페이지 내에서 'object', 'applet', 'embed' 태그에 의해 로드된 액티브 X, 자바 애플릿, 멀티미디어 파일의 경우, 사용자가 이를 클릭해서 명시적으로 활성화(Activation)시키기 전까지는 임베딩된 개체에 사용자가 직접 상호작용(Interaction)하는 것이 불가능하며, 상호작용과 관련된 DHTML 이벤트도 사용이 불가능하다는 것이다.

      이번 패치의 영향을 받는 대상은 웹 페이지 내에 'object', 'applet', 'embed' 태그를 사용해서 지정되고, 눈에 보이는 UI를 가지며, 사용자가 마우스나 키보드 입력을 통해 이벤트를 처리하는 상호작용 컨트롤에만 해당된다.

      상호작용 컨트롤의 예는 미디어 플레이어, 애플의 퀵타임 플레이어, 매크로미디어의 플래시 등이 있다. UI를 가지지 않는 비상호작용 컨트롤이나 외부 스크립트를 통해 로딩된 상호작용 컨트롤에는 아무런 영향이 없다.

      인터넷 뱅킹 시스템의 경우, UI가 없는 키 로깅 방지 컨트롤은 영향이 없으며, 공인 인증서도 UI가 웹 페이지 내에 임베딩된 것이 아니라 별도의 다이얼로그 창으로 나오기 때문에 영향을 받지 않는다.

      아래 그림은 웹 페이지에 'object' 태그나 'embed' 태그를 사용해서 미디어 플레이어 액티브 X를 구동해 동영상 콘텐츠를 재생하고 있는 모습이다. 활성화되지 않은 상호작용 컨트롤은 마우스나 키보드 이벤트 등의 사용자 입력에 반응하지 않는다. 마우스 커서를 올려놓았을 때 컨트롤 주위에 점선 테두리가 나타나며, 그림과 같은 풍선 도움말이 나타난다.

      컨 트롤을 활성화하려면 마우스로 해당 컨트롤을 클릭하거나 탭 키로 포커스를 이동한 후 스페이스 바나 엔터 키를 누르면 된다. F5 키를 눌러서 페이지를 갱신했을 경우 컨트롤이 다시 비활성화되며, 페이지 내에 컨트롤이 여러 개 있는 경우에는 각각을 활성화해야 한다는 것에 주의해야 한다.

      혼동해서는 안 될 것은 상호작용이 불가능하다는 것이지, 임베딩한 개체가 아예 로드되지도 않고 작동하지도 않는다는 것은 아니다. 즉, 위의 예에서 동영상 콘텐츠 자체가 아예 재생되지 않는 것은 아니다. 다만, 동영상을 멈추기 위해서 정지 버튼을 누르려면(즉 상호작용을 하려면) 컨트롤을 클릭해서 활성화시켜야 한다는 것이다.

      국내 웹사이트의 파급 효과
      위에서 예로 든 멀티미디어 콘텐츠(동영상, 음악) 외에 국내 사이트에서 이 패치에 대해 영향을 받는 것은 어떤 것이 있을지 몇 가지 예를 들어보자.

      요즘 몇몇 사이트들에서는 사진이나 그림을 업로드하기 전에 이미지를 편집할 수 있도록, 이미지 툴 액티브 X를 제공하는 곳이 있다. 이러한 이미지 툴 컨트롤을 사용하려면, 컨트롤을 한 번 클릭해서 활성화시켜야 한다. 또한 업무용 시스템을 보면 차트, 그리드와 같은 요소를 서드파티 액티브 X 컨트롤로 사용하는 경우가 많다. 이 경우 상호작용을 하려면 화면 내의 컨트롤을 각각 활성화시켜야 한다.

      액티브 X 컨트롤도 문제지만, 필자가 생각하기에 국내에서 가장 광범위하게 영향을 받을 것이라고 생각되는 것은 바로 플래시다. 국내 사이트들은 메뉴 등의 네비게이션 UI, 광고, 플래시 게임, 플래시 축하카드 등 플래시에 대한 의존도가 매우 높다. 거의 모든 UI를 플래시로 도배한 모 사이트의 경우, 화면의 대다수가 비활성화되는 현상이 발생했다(하다못해 필자 회사 홈페이지도 메뉴가 플래시로 돼 있다).

      마우스를 올렸을 때 팝업 형태로 메뉴를 보여주는데, 비활성화된 상태에서는 메뉴가 전혀 나타나지 않는다. 사실 활성화를 위해 클릭 한 번 하는 것이 별로 힘든 일은 아니지만, 잘 모르는 사용자의 경우에는 상당히 당황스러울 수 있다는 생각이 든다.

      이러한 사용자들의 혼란을 방지하려면 'object', 'applet', 'embed' 태그를 사용하는 페이지의 경우 수정이 불가피하다. 이를 위해 MS는 상호작용 컨트롤이 이전과 동일하게 즉시 활성화되게 하고 싶으면 외부 스크립트에 의해 상호작용 컨트롤을 로드하라고 권하고 있다.

      예를 들어 다음과 같이 'embed' 태그를 사용하는 페이지가 있다고 가정하자.

      <html>
      <body>
      <embed src="examplecontrol">
      </body>
      </html>

      MyPage.html을 로드하면 해당 컨트롤은 비활성화된 상태가 된다. 이를 방지하려면, 다음과 같이 'embed' 태그를 write 해주는 코드를 외부 스크립트 파일(embed.js)로 작성해서 빼고, MyPage.html에서는 이 스크립트 파일을 지정하면 된다. 이렇게 하면 이전과 동일하게 이 컨트롤은 로드 후 즉시 활성화된다.

      <html>
      <body>
      <script src="Embed.js"></script>
      </body>

      Embed.js
      document.write(‘<embed src=”examplecontrol”>’);

      액티브 X, 플래시의 남발 자제해야

      이러한 준비는 언제까지 마쳐야 할까?
      MS는 1차적으로 3월 1일에 이 IE 패치를 윈도우 업데이트를 통해 선택적으로 배포할 예정이다. 즉 설치를 원하는 사용자만 이 패치를 설치하면 된다. 그러나 4월부터는 보안 업데이트에 일괄 적용되므로, 보안 업데이트를 설치하면 이 패치를 함께 설치하게 된다. 그러므로 사실상 4월 전까지는 위 방법을 통해 패치에 대한 대비책을 세우는 것이 바람직하다고 생각된다.

      이 패치가 궁극적으로 국내 웹사이트에 미치는 영향이 얼마나 될지는 아직 미지수다. 하지만 분명히 외국 사이트에 비해서는 상당히 파급 효과가 클 것으로 예상된다. 그 이유는 국내 사이트들이 액티브 X, 플래시 등에 대한 의존도가 매우 높으며, 많이 사용하고 있기 때문이다. 특히 해외에서 국내 사이트들에 접속해보면 새삼스레 국내 네트워크 인프라의 우수성에 놀라게 된다.

      국내 웹사이트들은 윈도우 XP 서비스팩 2에서 팝업 창 차단 때문에 대대적인 수정을 하는 홍역을 치른 적이 있다. 이제 시도때도 없이 뜨는 팝업 창뿐만 아니라 여기저기에서 남발됐던 액티브 X 및 플래시에도 제재가 들어오게 된 셈이다.

      이러한 소동과 후유증을 겪어야 하는 것은 이올라스나 MS에도 책임이 있겠지만 웹 기획자, 디자이너, 개발자들, 고객이 스스로 이러한 문제를 초래했다는 것을 부인하지 못할 것이다.

      이번 사건 이후에 액티브 X나 플래시 사용을 자제하는 바람직한 모습으로 가는 계기가 될지, 아니면 XP 서비스팩의 팝업 창 차단 이후 레이어를 통해 팝업 창을 흉내내는 기괴망측한 꽁수가 등장했듯이, 이번 사건 역시 개발자에게 스크립트 작업만을 잔뜩 추가해주게 될지는 두고 볼 일이다.
      반응형

      'Information' 카테고리의 다른 글

      온라인게임 지역별 선호도  (0) 2007.02.01
      골치덩어리 IE 보안「액티브 X 컨트롤로 해결」  (0) 2007.01.21
      Websites as Graphs  (0) 2007.01.17
      보안 문제는 수년동안 MS 인터넷 익스플로러를 괴롭혀왔고, 이 웹 브라우저는 치명적인 취약성으로 계속 고통받고 있다. 사실 MS는 2005년 5월경 최근 IE 보안 위협 중 한 가지에 대해 이미 알고 있던 상황이었다. IE 대부분 버전에 영향을 미치는 치명적인 취약성을 고려해볼 때 그간 이 위협으로 IE는 시달려왔고, 크래커들은 웹을 파괴하기 위해 이 취약성을 이용해왔다. 적어도 이번 주까지는 말이다.

      보통 매달 두 번째 주 화요일에 나오는 월간 보안 공지(security bulletins)의 일환으로 MS는 보안 공지 MS05-054, 이른바 '인터넷 익스플로러용 누적 보안 업데이트'를 내놓았다. MS05-054는 인터넷 익스플로러의 4가지 취약성에 초점을 맞추고 있으며, 이 중 두 가지는 대부분의 윈도우에서 심각(critical)한 수준으로 등급이 매겨져 있다. 이 보안 공지는 다음과 같은 결점을 해결한다.

      * 파일 다운로드 대화 상자 조작 취약성
      * HTTPS 프록시 취약성
      * COM 객체 인스턴스화 메모리 오염 취약성
      * 일치하지 않는 문서 객체 모델 객체 메모리 오염 취약성

      인가받지 않은 정보를 노출시키거나, 시스템을 불안정하게 만들거나, 혹은 유해한 웹 애플리케이션을 사용하여 시스템을 가로채거나 할 때 공격자들이 이 취약성을 어떻게 이용할 수 있는지 알아보기 위해 좀더 자세히 보안 공지 내용을 보자.

      문제를 좀더 복잡하게 만드는 건 서드파티에서 만든 수백 개의 COM 객체 애드 인에 있다는 사실 때문이다. 그렇다면 또다른 벤더에서 다운로드한 COM 객체를 마지막으로 업데이트한게 언제였는가?

      서드파티 소프트웨어를 업데이트하지 않는 건 좋은 생각이 아닌데다가 자체적으로 바람직하지 않은 일이 일어날 수 있지만, 가까이에 더 큰 문제가 도사리고 있다. 바로 컴퓨터에 있는 다른 기능과 IE가 통합돼 있다는 점이다. 이런 기능적 통합은 액티브 스크립팅(Active Scripting)과 액티브X 컨트롤(ActiveX controls)를 통해 가능해진다.

      액티브 스크립팅과 액티브X 컨트롤을 컴퓨터에서 꺼버리게 되면 약간은 포기해야 할 기능이 있을 수도 있겠지만, 훨씬 더 많은 보안 이득이 있을 것이다. 어떻게 이 두 기능을 꺼버릴 수 있는지 살펴보자.

      액티브 스크립팅 끄기
      액티브 스크립팅을 동작하기 전에 사용자에게 알려주도록 IE 설정을 해서 일부 취약성으로부터 시스템을 좀더 제대로 보호할 수 있다. 혹은 인터넷 보안 영역에서 완전히 액티브 스크립팅을 꺼버릴 수 있다.

      다음 단계를 따른다

      1. 인터넷 익스플로러가 실행된 상태에서 도구(Tools) -> 인터넷 옵션(Internet Options)로 간다.

      2. 보안(Security) 탭에서 인터넷(Internet) 아이콘을 클릭하고, 사용자 지정 수준(Custom Level) 버튼을 클릭한다.

      3. 설정(Settings) 목록 상자에서 스크롤해 스크립팅(Scripting)을 찾는다.

      4. 'Active 스크립팅'에서 프롬프트(Prompt)나 사용 안함(Disable)을 선택하고 확인(OK)을 클릭한다.

      5. IE가 변경됐다고 확인을 하도록 묻는다면 예(Yes)를 클릭한다.

      6. 설정을 저장하기 위해 확인(OK)을 클릭하고 모든 대화 상자를 닫는다.

      이제 액티브 스크립팅을 처리했으니 이보다 더 위험한 컴포넌트인 액티브X를 끌 시간이다.

      액티브X 컨트롤 끄기
      액티브X 컨트롤이 동작하기 전에 알려주도록 IE를 설정함으로서 일부 취약성으로부터 시스템을 보호할 수도 있다. 이도 역시 인터넷 보안 영역에서 완전히 액티브X 컨트롤을 꺼버릴 수 있다.

      다음 단계를 따른다.

      1. 인터넷 익스플로러가 실행된 상태에서 도구(Tools) -> 인터넷 옵션(Internet Options)로 간다.

      2. 보안(Security) 탭에서 인터넷(Internet) 아이콘을 클릭하고, 사용자 지정 수준(Custom Level) 버튼을 클릭한다.

      3. 설정(Settings) 목록 상자에서 스크롤해 액티브 X 컨트롤 및 플러그 인(ActiveX Controls And Plug-ins)을 찾는다.

      4. 액티브 X 컨트롤 및 플러그 인 실행(Run Active X Controls And Plug-ins)에 대해 확인(Prompt) 혹은 사용 안함(Disable)을 선택하고 확인(OK)을 클릭한다.

      5. IE가 변경됐다고 확인을 하도록 묻는다면 예(Yes)를 클릭한다.

      6. 설정을 저장하기 위해 확인(OK)을 클릭하고 모든 대화 상자를 닫는다.

      신뢰 사이트 목록 관리하기
      IE의 인터넷 보안 영역에서 액티브 스크립팅과 액티브X 컨트롤을 끄면 일부 웹 사이트가 제대로 동작하지 않을 수도 있다는 점을 명심하기 바란다. 필자의 시스템에서는 확인 혹은 프롬프트(Prompt)로 설정했으며, 따라서 액티브 스크립팅이나 액티브X 컨트롤이 포함된 사이트에 새롭게 방문할 때면 사이트를 신뢰할지 여부를 결정해야 한다.

      자주 사용할 사이트라면 신뢰 사이트 목록에 사이트 주소를 넣어두며, 그때그때 팝업창으로 알려준다. 신뢰 사이트 목록에 사이트를 추가하려면 다음 단계를 따른다.

      1. 브라우저 상에서 URL 위에서 오른쪽 버튼을 클릭하고 복사(Copy)를 선택한다.

      2. 도구(Tools) -> 인터넷 옵션(Internet Options)으로 간다.

      3. 보안(Security) 탭에서 신뢰할 수 있는 사이트(Trusted Sites) 아이콘을 클릭하고 나서 사이트(Sites) 버튼을 클릭한다.

      4. 영역에 웹 사이트 추가(Add This Web Site To The Zone) 텍스트 상자에서 마우스 오른쪽 버튼을 클릭하고 붙여넣기(Paste)를 선택한다.

      5. 이 영역에 있는 모든 사이트에 대해 서버 확인(https:) 필요(Require Server Verification (HTTPS:) For All Sites In This Zone) 체크 박스를 해제한다.

      6. 추가(Add)를 클릭해 닫기(OK)을 클릭한다.

      7. 설정을 저장하기 위해 확인(OK)을 클릭하고 모든 대화 상자를 닫는다.

      액티브 스크립팅과 액티브X 컨트롤을 꺼버리면 웹 브라우징을 할 때 IE가 더 안전해진다. 인터넷 익스플로러가 정도를 넘어서는 보안 문제를 갖고 있긴 하지만 오늘날 사용되고 있는 가장 대중적인 웹 브라우저인 건 사실이다. 파이어폭스(Firefox)나 오페라(Opera)같은 다른 브라우저로 바꾸고 싶지 않다면 인터넷을 안전하게 브라우징하기 위해 보안 설정을 높여줄 필요가 있다.
      반응형

      'Information' 카테고리의 다른 글

      온라인게임 지역별 선호도  (0) 2007.02.01
      IE 액티브 X 컨트롤 실행 문제「이렇게 대처하라!」  (0) 2007.01.21
      Websites as Graphs  (0) 2007.01.17

      JayG.org as Graph

      위 그림은 웹 페이지를 파싱해서 그래프를 만들어주는 자바 애플릿을 이용하여 이 블로그를 표현한 그래프이다. 이 자바 애플릿은 Sala라는 사람이 개발했고 소스 또한 공개되어 있다. 자신의 웹 페이지를 그래프로 표현하기 위해서는 이곳에 접속하여 주소를 입력하고 그래프가 다 그려질 때까지 인내하면 된다. 그래프가 다 그려지는데 꽤 오래 걸리기 때문에 켜두고 다른일을 하는게 좋을 거다. 다른 사람들의 그래프를 보기 위해서는 Flickr’websitesasgraphs’를 찾아보면 되고 자신의 그래프에 ’websitesasgraphs’ 태그를 붙여 저장하면 동참할 수 있다.

      그래프의 각 색상이 의미하는 바는 다음과 같다.

      • 파랑: 링크 (<a> 태그)
      • 빨강: 표 (<table>, <tr>, 그리고 <td> 태그)
      • 초록: <div> 태그
      • 보라: 그림 (<image> 태그)
      • 노랑: 폼 (<form>, <input>, <textarea>, <select>, 그리고 <option> 태그)
      • 주황: 개행과 인용문 (<br>, <p>, 그리고 <blockquote> 태그)
      • 검정: 뿌리 (<html> 태그)
      • 회색: 그 외

      출처 : http://jayg.org/professional/web/websites-as-graphs/332/

      반응형

      + Recent posts