Back to the Future 대한극장 이야기

난 서울에서 10대를 보냈다. 그리고 그 10대는 1980년대를 관통했다. 이 조건과 함께 하는 영화팬 중에서 충무로 대한극장에 아무런 감흥이 없는 사람이 과연 있을까? 방학이 시작하면 가장 화제가 되는 영화들이 개봉 됐던 그 곳은, 지금 생각해보면 일종의 성지였다. 인터넷 예매가 없던 그 시절은 극장 매표소에 서서 표를 사는 것이 영화를 보기 위한 유일한 방법이었고, 대한극장에서 개봉하는 영화라면 닥치고 조조영화를 보기 위해 대한극장 앞에서부터 줄이 이어져 상당히 길게 명동 쪽까지 뻗어가곤 했다. 길 가던 사람들이나 버스를 타고 가던 사람들 모두에게 그건 장관이었다. 그들은 저게 뭐지? 라는 눈빛으로 줄 선 사람들을 바라봤다. 난 그 시선을 즐겼던 것 같다. 그들은 아니지만, 난 이제 곧! 이 영화를 볼 사람이니까.
대한극장 인파의 역사에 획을 그은 사건이 있었다. 1987년 7월 17일. <빽 투 더 퓨쳐>가 개봉하는 날이었다. 아침 일찍 서두른다고 충무로역에 도착했지만 이미 전철에는 나와 함께 충무로역에 내리는 사람이 많았고, 대한극장 쪽으로 달리는 사람도 많았으며 도착한 그곳은 이미 줄이 길고 또 길었다. 도대체 이 사람들은… 하면서 줄의 끝으로 걸어갈 수밖에 없었다. 끝은 없는 것 같았고 함께 갔던 아버지는 나를 줄 끝으로 보내곤 상황을 보려는지 매표소 쪽으로 가셨던 것 같다. 그 후에 일어났던, 내 생애 가장 치열했던 영화 관람을 위한 고군분투는 굳이 이곳에 적지 않겠다. 아직까지도 친구들을 앞에 두고 지껄이는, 내 십대를 장식하는 대표적 에피소드가 되었다는 정도만 알린다. 어쨌든 표는 구할 수 있었다. 1회는 아니었지만. (당시 1회를 관람한 사람들의 증언도 듣고 싶다. 도대체 어떻게 해야 그게 가능했던 거지?)

째깍째깍 하는 소리와 함께 영화가 시작 됐다. 거대했던 대한극장 스크린에 대형 스피커가 가득 차더니 마티 맥플라이가 기타 줄을 튕김과 동시에 웽~! 하고 뒤로 날아간다. 그 장면부터 난 이 영화에 빠져들었던 것 같다. 휴이 루이스 앤 더 뉴스의 ‘Power of Love’가 들리는 가운데 마티가 스케이드 보드로 등교하는 장면부터는 정신을 거의 잃었던 것 같다. 드로리안을 타고 과거로 날아간 다음부터의 코미디와, 미래를 바꾸는 일격의 통쾌함이나, 사라지기 시작하는 마티(안돼!!!!!! 라고 소리지를 뻔 했다), 미래로 가기 위한 서스펜스까지 영화는 계속 나를 망치로 내리쳤다. 그리고 1편의 마지막 장면. 박사가 마티를 태우고 미래로 가는 장면에서 갑자기 드로리안이 공중으로 붕 떠오르더니 스크린을 들이박고 굉음과 함께 끝나는데 그 흥분을 도저히 주체할 수 없었다. 결국 연달아 두 번 영화를 봤다. 당시 대한극장 2층 가장 뒤에는 표 없이 앉아서 볼 수 있는 의자가 마련되어 있었다. 나처럼 연달아 두 번 영화를 보는 애들을 위한 자리였을 것이다. 그 의자를 잡기 위해서는 역시 달려야 했다.

그 다음 주 월요일, 학교에서는 난리가 났었다. 너 그 영화 봤니? 아직 안 봤니? 미친놈. 그걸 안 보고 뭐했냐! 넌 봤니! 그 장면 끝내주지!!! 내 말이!

난 극장에서 사온 팜플렛(당시에는 영화에도 책 같은 팜플렛을 제작했었다)을 걸레가 되도록 보고 또 봤고, 마티처럼 손목시계를 찬 채 괴자세로 잠을 자보기도 했고, 그런 오리털 조끼는 어디서 구하나 궁금했으며, 스케이브 보드를 타고 언덕길을 내려오다 넘어지기도 했고, 우리 동네에는 미친 과학자 하나 안사나 푸념하곤 했다. 그러던 어느 날 <백 투 더 퓨쳐>가 속편을 만들고 있다는 소문이 들렸다. 그것도 2편과 3편을 동시에 제작하고 있다는 것이었다. 당시에는 파일 공유 같은 것이 없던 시절이라 어디서든 구해왔던 복사에 복사가 거듭된 불법 VHS들이 동네 비디오 가게의 핫 아이템이었고, 할리우드에서 개봉한지 얼마 후, 우리 동네에도 <백 투 더 퓨쳐 2>의 비디오가 풀리기 시작했다. 그건 미국 극장 캠 버전이었다. 그걸 본 반 친구에 의하면 영화가 끝나면 일어서는 관객 머리가 보인다고 했다. 난 곧 극장에서 개봉한다는 소식에 허벅지를 꼬집어 가며 참았고, 비짜 비디오로 먼저 봤다는 친구들에게 그 화질로 봐서 뭐하냐는 공허한 비웃음을 날렸다. 그러나 부러웠다. 기다림 끝에 드디어 영화가 개봉했다. 친구들과 가서 봤고, 몇 개월 후 3편까지 모두 마스터 했다. 그렇게 <백 투 더 퓨쳐> 트릴로지의 여정을 완료했다.
2편은 1편의 흥분까지는 아니었지만 복잡하게 얽히는 재미가 아주 쏠쏠했고, 사실 3편은 조금 실망하긴 했지만 대망의 마무리로서는 손색이 없는 완결편이었다.
그 이후로 <백 투 더 퓨쳐>는 하나의 아이콘이 되었고 전설이 되었다. 마치 내 10대를 책임진 영화처럼 변화하기 시작했다. 그게 변화인지 증폭인지 아니면 원래 그랬던 건지는 기억할 수 없다. 지금 와서 굳이 진실이 무엇인지 따질 필요는 없다. 아무튼 그렇게 되었으니까. 대학교 때의 에피소드가 하나 있다. 내가 소속되어있던 영화 동아리에서는 학우들을 대상으로 하는 정기상영회를 열곤 했는데, 본 영화를 틀기 전에 기다리는 사람들을 위해 후배가 가져온 <백 투 더 퓨쳐> VHS를 튼 적이 있었다. 공교롭게도 1편의 마지막 하이라이트 부분이었는데, 영화를 보러 온 사람들이 너무 집중하고 만거다. 그러는데 영화가 끝난 다음 바로 이어서 2편이 시작 되고 말았다. 후배가 그렇게 녹화했다고 하더라. 1편의 마지막에서 하늘을 나는 드로리안이 스크린에 부딪힌 다음, To Be Continued 글자가 나오고 바로 2편이 시작된 시점. 1편 끝과 동일한 장면들이 보여지고는 구름과 함께 뜨는 오프닝 크레딧들. 본 영화를 상영해야 할 시간이라 <백 투 더 퓨쳐>를 끌 수밖에 없었는데, 그러자마자 객석에서는 아쉬움의 한숨이, 그것도 너무나 큰 소리로 들려왔다. 그 때 이 영화는 나에게만 아이콘이 된 영화는 아닐 거라는 생각을 하게 됐다. 그 동아리에서 1편을 200번 봤다는 후배도 만나게 되었고, 초면이라 어색했던 후배와 말을 튼 것도 바로 이 영화였으니 말이다.
<백 투 더 퓨쳐>가 나온 지 25주년이다. 영국에서는 디지털 버전으로 변환해 재개봉을 하는 모양이다. 한국에서는? 과천 국제SF영화제에서 10월 말, 이 3편을 모두 상영한다. 비록 상영포맷이 디지베타라고는 하지만 이번 상영을 위해 원본에서 바로 뜬 본이기 때문에 화질과 음향이 매우 우수하다는 관계자의 정보가 있다. 화면비도 유지된다고 한다. 중학교 때, 대한극장에 뛰어갔던 그 후, 난 이 영화를 극장에서 본 적이 없다. 물론 DVD 세트를 집에 고스란히 모셔놨지만, 그렇다고 많이 보게 되지는 않았다. 그저 한 번 더 봤던 것 같다. 하지만 그 영화가 스크린에 다시 투영된다니 움직이지 않을 수 없다. 나 뿐 아니라 나와 비슷한 추억을 가지고 있던 비슷한 나이 대 사람들이 우글우글 나란히 앉아 그 영화를 볼 예정이다. 밤을 세워가며. 다들은 조금 두근두근 하고 있을지도 모른다. 언젠가, 아주 옛날 옛적에는 영화를 보기 위해 줄을 서있을 때, 이 영화를 내가 보게 되다니, 라며 두근두근했던 적이 있었다. 그 두근거림은 크리스마스를 기다리는 마음보다 조금 늦은 시간에 사라지긴 했지만 어쩌면 이번 상영으로 그 느낌을 다시 받을 수 있을지 모르겠다.
다시 1987년 7월 17일. 대한극장은 그 날의 아수라장을 사진으로 남겼다. 그리고 그 사진을 확대해 판넬로 제작하더니 홍보 및 과시용으로 극장 안에 오랜 시간 걸어두었다. 멀티플렉스로 바뀐 후 사진은 슬그머니 사라지고 말았지만 아마 지금도 대한극장 창고 어딘가에는 여전히 그 사진이 먼지를 뒤집어쓴 채로 있을 것 같다. 사진 속 어딘가의 내 머리 위에도 먼지가 쌓이고 있을 것이다.

[원본: 어느 네이버 블로그 : 현재 못찾음 => 사진은 창고에 없다고 함. 버렸다고 함]

계릉의 전투

다리 잘리고 발분(發奮)한 손빈(孫臏) 2007.03.04 16:30:13
생몰년 모두 불확실하다. 다만 활동 연대가 맹자(孟子) 장자(莊子)와 비슷하며 변법가이자 냉혹한 법가 사상가로 유명한 상앙(商鞅)과도 비슷하거나 10~20살 정도 어릴 가능성이 있다.

그의 본명은 알 수 없으니 孫은 말할 것도 없이 그의 姓이지만, 빈(臏)은 이름이 아니라, 그가 得罪를 하여 무릎 이하가 잘리는 형벌을 받은 절름발이라는 뜻이다. 따라서 손빈이란 손씨라는 성을 지닌 다리 잘린 형벌을 받은 사람이라는 뜻이 된다.
중국 전국시대를 대표하는 저명한 군사전략가로써 전하기를 공자(孔子)와 활동연대를 같이 하며 오자서와 함께 오국(吳國)을 패자로 만드는 데 결정적인 공을 세운 춘추말기 때의 저명한 군사전략가 손무(孫武)의 후손이라 한다. 태생지는 전국시대에는 제국(齊國)에 속한 阿와 鄄 사이 지방이라 하니, 이곳은 지금의 산동성(山東省) 양곡현(陽穀縣) 아성진(阿城鎭)과 견성현(鄄城縣 북쪽 일대에 해당한다. 일찍이 제 위왕(齊威王)에게 등용되어 군사(軍師)가 되어 고국인 齊나라가 계릉지전(桂陵之戰)과 마릉지전(馬陵之戰)에서 위국(魏國)을 격파하는 데 결정적인 공을 세웠다고 사마천은 사기(史記)에서 기록한다. 하지만 이런 기록은 최근에 山東省 임기현(臨沂縣) 은작산(銀雀山)에서 발견되고 발굴된 서한묘(西漢墓) 출토 손빈병법(손빈병법) 죽간(竹簡)과는 상당한 차이를 보인다. 이런 괴리에 대해 지금은 많은 이가 죽간 손빈병법(孫臏兵法)이 저록(著錄)된 연대가 사마천의 사기보다 반세기 이상을 앞선다는 점을 주목해 이에 더 많은 신뢰를 주는 실정이다.

그렇다면 손빈(孫臏)은 누구인가?

우선 史記 중의 손자오기열전(孫子吳起列傳)에 첨부된 그의 행적은 대강 이렇다.

손빈(孫臏)은 어릴 때 귀곡자(鬼谷子)에게 방연(龐涓)과 함께 병법을 배웠다. 방연은 재빨리 위국(魏國)으로 가서 벼슬을 해서 그 혜왕(惠王)에게 등용되어 장군이 되었다. (필자 註 : 이 惠王이란 인물은 맹자 첫 대목에서 不遠而千里하고 달려온 맹자에게 “하필 이익만 말씀하십니까”라고 개쪽을 당한 그 인물이다. 魏國은 이 당시에 대량<大梁>이란 곳에 도읍한 까닭에 梁이라는 국호로도 불렸다) 하지만 손빈이 자기보다 재능이 뛰어나다고 시기한 방연은 齊國에 있던 손빈을 魏國으로 끌어들여 혜왕에게 발탁케 하고는 그를 모함하기를 “齊國과 몰래 통한다”고 했다. 이에 得罪한 손빈은 두 다리를 잘리는 형벌을 받은 것은 물론 면상(面上)에는 죄인임을 표시하는 묵글씨를 지져 새기는 묵형(黥形)도 아울러 받았다.

이런 암울한 나날을 보내다가 손빈은 고국 제나라에서 大梁으로 사절로 온 사신을 몰래 찾아가 구제를 요청하니, 이에 사신이 그와 대화를 나누가가 그가 인재임을 알고는 몰래 그를 빼돌려 제국으로 데리고 갔다. 그를 주목한 이는 제나라 장군 전기(田忌)였다. 이 당시 제국(齊國)은 이미 강태공(姜太公)에게서 시작하는 강씨(姜氏)시대가 전씨(田氏) 왕조로 교체된 지 오래라, 전기(田忌)는 그 성으로 보아 왕족에 속할 것임은 분명하다.

역시 그의 재능을 알아차린 전기는 손빈을 賓客의 신분으로 추숭하니 손빈 또한 主君을 위해 충성하게 된다.

그렇다면 그의 주군 전기는 어떤 인물인가? 사기에 이르기를 그는 도박광인 ‘타짜’라, 어느날 제국의 公子들과 돈을 걸어 수레 경주 놀이판을 벌였다. 손빈은 쌍방 수레 세 대씩을 관찰하건데 그것을 끄는 말은 상 중 하 세 등급으로 나눌 수 있거니와 각각의 등급끼리 경주를 맞붙을 경우 승부를 예측하기 힘들 정도로 비슷했다. 이에 손빈은 전기에게 이런 내기 방식을 제안한다.

“장군이 가진 가장 뒤처지는 수레는 상대방의 가장 빠른 수레와 맞장을 뜨게 하시고, 장군의 가장 좋은 수레는 상대방의 중등 수레, 그리고 장군의 중간 수레는 상대방의 하등 수레와 붙이십시오.”

이리하여 3 대 3으로 붙은 경기 결과는 2 : 1로 전기(田忌)가 승리했다.

이에 감복한 전기는 손빈을 제 위왕에게 천거했다. 이 면접시험에서 발탁되어 손빈은 일약 군작전 최고 참모인 군사(軍師)가 되어 이후 평생과 같이 주군인 전기(田忌)를 보좌하게 된다. 그를 발탁하고 천거한 전기에 대해서는 모든 기록이 마치 손빈 없으면 아무 것도 하지 못했을 바보처럼 그리지만, 내 보기엔 진정 위대한 인물은 손빈보다는 이 전기라는 사람이다.

애니웨이, 장군 전기-군사 손빈이라는 투 톱 체제가 가동되고 난 지 얼마 지나지 않아, 제국이 군대를 출동해야 할 일이 생겼다. 위국(魏國)이 조국(趙國)을 대대적으로 침범한 것인데, 백척간두에 밀려 수도 한단(邯鄲)까지 함락 일보 직전에 몰린 조국이 제국에 도움을 요청한 것이다. 이리하여 제국은 구원군을 파견하게 된다. 애초에 위왕은 손빈을 장군에 임명하려 했으나 한사코 거절하는 바람에 전기를 장군, 손빈은 군사로 삼되 손빈의 모습은 눈에 띄지 않도록 수레에 숨겼다. 이는 조국(趙國) 정벌에 나선 위국(魏國) 장수가 방연이며, 나아가 그가 孫臏을 누구보다 잘 알 터이므로, 허를 찌르기 위해 손빈 스스로가 은닉을 자청했을 수도 있으며, 그것이 아니라면 병신이 된 자기 모습을 드러내기가 쪽팔려서 그러했을 가능성도 내칠 수는 없다. 다만, 후자보단 전자에 혐의가 가는 것만은 부인할 수 없다.

바보 같은 전기, 한단으로 곧바로 돌진해 조국을 구원하려 하나, 손빈이 막아선다.

“상대방의 허점을 쳐야 싸움은 이기는 법. 지금 위국 대량에는 전쟁 통에 노약자만 남아있을 뿐. 한단보단 대량을 치면 본국을 지키고자 방연은 군사를 몰아 돌아올 것입니다.”

이 전략은 멋지게 성공해 위군은 함락 일보 직전의 수중에 두었던 한단을 포기하고 귀환한다. 이를 계릉(桂陵)에서 기다린 제군(齊軍)은 위군을 대파하니 이를 계릉지역이라 부른다. 이 전술은 나중에 모택동(요즘은 마오쩌뚱이라 한다. 뚱뚱!!)

13년 뒤, 이번에 위국이 원수로 지내던 조국과 합세해 한국(韓國)을 공격했다.(韓-魏-趙 3국은 춘추시대 중원을 차지한 최강국 진<晉>을 3氏가 나눠먹기 해서 생긴 것이라 해서 흔히 삼진<三晉>이라 통칭하기도 한다.) 이 때도 제국은 전기를 대장, 손빈을 군사로 삼아 위국 수도인 대량을 친다. 이에 한국 정벌에 나선 방연은 포위를 풀고 귀국길에 오른다. 손빈은 이때야말로 방연을 잡을 때라고 생각하고는 계책을 꺼낸다.

“숙영지를 옮길 때마다 부뚜막 숫자를 절반씨 줄이소서.”

기대한 대로 방연은 제군을 추격하다가 거기에 도망병이 많이 생겼다고 생각하고는 이동속도가 현격히 떨어지는 보병을 뒤로 제쳐두고 기병과 정예부대만을 이끌고 마릉(馬陵)이란 곳까지 제군을 추격하게 된다. 이곳은 길은 좁고 양쪽은 험안 산이 들어선 이른바 死地. 손빈은 마릉 계곡 옆 큰 나무를 골라 껍지를 벗겨낸 다음 그 하얀 속껍질에 이렇게 썼다.

“방연은 이 나무 밑에서 죽으리라”

제군은 방연이 들이닥치기를 기다려 양쪽 협곡에 활과 노수들을 집중배치해 결국은 위군을 몰살케 하는 대 전과를 올렸다. 이에 방연은 스스로 목을 찔러 죽었다.

이것이 사기에 기록된 대강이다. 한데 이런 기록에서 석연치 않은 대목이 발견된다. 계릉 전투와 마릉 전투에서 방연이 똑같이 당했다는 점이 그것이다. 계릉 전투에서는 그랬을지 몰라도, 13년 뒤에 벌어진 마릉 전투에서도 똑같이 당했다고 보면 말이 되지 않는다. 13년 전 교훈을 살린다면 대량에다가 적어도 최소 군대를 주둔시켜 두고 방연은 한국 정벌에 나섰을 것이기 때문이다.

하지만 손빈병법 죽간에는 마릉전투가 없고 저런 사기에 기록된 일들은 모두 계릉전투에서 있었던 것으로 되어 있다. 나아가 방연은 자살한 것이 아니라 포로가 되었다고 했다. 암튼 손빈병법 죽간 쪽이 여러 모로 보아 더 합리적이라는 점은 부인하기 힘들다.

그렇다면 계릉전투 이후 손빈은 어떻게 되었는가?

戰國策 중 제나라와 관련한 유세객들의 이야기를 다룬 제책(齊策)에는 그 일단이 엿보인다. 이에 의하면, 손빈의 주군인 전기는 제국 재상 추기(鄒忌)와 권력 투쟁을 벌인다. 둘 중 하나는 죽어야 한다. 쿠데타 전운이 감도는 가운데 손빈은 전기를 향해 쿠데타를 먼저 일으켜야 한다고 주장한다. 하지만 전기는 이를 거부한다. 그러다가 추기가 선수를 치자 전기는 겨우 목숨만을 건진 채 초국(楚國)으로 망명한다. 손빈은 이 때 죽었거나, 아니면 전기와 함께 초국 망명길에 올랐을 것이다.

史記 전제세가(田齊世家)에 의하면 이렇게 도망친 전기는 제에서 위왕이 죽고 선왕(宣王)이 즉위하자 고국으로 돌아온다. 하지만 손빈이 어떠했는지는 행적이 보이지 않는다. 아마도 전기의 쿠데타를 계기로 손빈은 전기와는 갈 길을 달리한 듯하다.

漢書 藝文志에는 “齊孫子 89篇 ”을 거론했다. 제국의 손자라는 뜻이니 이는 손무가 아니라 손빈병법을 지칭한다. 이것이 은작한 한묘에서 출현한 셈이다. 하지만 한서 예문지 이후 손빈병법은 어찌된 셈인지 모습을 보이지 않는다. 완전히 사라지는 바람에 손빈은 실은 孫武와 같은 사람이며, 그의 저서란 것도 실은 손무의 저서인 손자병법과 다름 아니라는 주장이 횡행하게 된다. 이런 막가파식 주장은 실증사학이 판을 친 일본 학계에서 주도적으로 제기되곤 했는데, 이런 사정은 한국고대사라고 진배가 없었다.

1부 직전신장 (오다 노부나가)

일본의 전국시대 힘있는 영주들이 영토를 늘리려 전쟁이 끊이지 않았다.

1534년 오다 노부나가(직전신장織田信長)는 오와리에서 노부히데의 둘째 아들로 태어났다.

나고야의 성주로 살았는데 어릴적 기발한 생각이 많아 엉뚱하게 행동 하였다.

사람들은 [오와리의 멍청이]라 불렀다.

1551년 노부히데가 사망하자 아버지의 지위를 동생 노부카쓰가 이어받았다.

1553년 미노의 사이토 도산(제등도삼斎藤道三)은 노부나가가 보통이 아님을 알고 사위로 맞아들여 노부나가는 노와 결혼 하였다.

노부나가는 동생과 전쟁을 벌여 동생을 죽이고 아버지의 지위를 이어받았다.

계략으로 병이난척 하며 노부카쓰가 병문안을 오자 죽인 것이다.

시바타 가쓰이에(시전승가柴田勝家)는 노부나가를 반대했던 인물이지만 뛰어난 무장이기에 거두어 들였다.

노부나가가 무력으로 쓸어 오와리를 통일 하였다.

 

 

 

 

 

 

1560년 이마가와 요시모토(금천의원今川義元)가 오와리에 쳐들어 왔다.

요시모토는 스루가, 도토미, 미카와를 영지로 갖고 있는 영주로 군사 3만을 몰아왔다.

노부나가의 군세는 겨우 5천 밖에 되지 않았다.

노부나가는 적의 대장만 죽이면 된다고 생각하고 기습을 하여 요시모토를 죽였다.

요시모토군은 패하여 달아나고 말았다.

이 전투를 오케하자마 전투라 한다.

이마가와 가문이 패배후 쇠락 하였는데 1561년 마쓰다이라 모토야스(송평원강松平元康 : 훗날의 도쿠가와 이에야스德川家康)는 미카와에서 독립 하였다.

미카와 태생인 그는 1543년 생이고 인질 생활을 하다가 어릴적 노부나가와 친하게 지냈었다.

모토노부에서 요시모토의 이름을 따 모토야스로 바꿨었는데 이마가와가와의 관계를 끊기위해 이에야스로 개명 하였다.

1566년에는 성도 도쿠가와로 바꾼다.

 

 

 

 

 

 

1556년 사이토 도산은 아들인 요시타쓰와 전쟁을 벌이다 전사 하였다.

1561년 요시타쓰가 죽고 사이토 다쓰오키(斎藤龍興)가 영주가 되었는데 무능한 인물 이었다.

노부나가는 미노를 점령하기 위해 미노 북부의 아자이 나가마사(천정장정浅井長政)와 손을 잡았다.

노부나가는 여동생 이치를 아자이가에 시집보내 유대를 강화 하였다.

나가마사의 아버지 히사마사는 롯카쿠에서 벗어나지 못해 그의 가신들은 반란을 일으켜 재능이 뛰어난 나가마사에게 영주의 자리를 주었다.

노부나가는 전략적으로 주요한 지점에 기노시타 도키치로(목하등길랑木下藤吉郞)에게 진채를 짓게 하였다.

도키치로(훗날 도요토미 히데요시豊臣秀吉)는 1537년 오와리국 농민의 아들로 태어났다.

전투에는 뛰어나지 않지만 노부나가가 시키는대로 뭐든지 해내어 신임을 얻었다.

노부나가의 짚신을 따듯하게 품거나 전쟁을 나갈때 노부나가의 말고삐를 잡고 달렸다.

머리는 비상하게 잘 돌아갔고 사람을 끌어들이는 재주가 있었다.

생김새는 원숭이 같이 생겼고 경박하게 행동했다.

사이토군을 잘 막고 전략적 거점에 진채를 완성하자 노부나가는 도키치로를 칭찬 하였다.

“이봐 원숭이! 고생했다. 너의 이름이 가벼우니 내가 새로운 이름을 지어주마. 너의 어릴적 이름이 히요시마루 였으니 내 아버지의 노부히데에서 한글자를 따 히데요시라 하겠다.”

“감사합니다. 주군!”

 

 

 

 

 

 

 

 

 

1561년 미노에 쳐들어온 오다군을 탁월한 전략으로 막아낸 젊은 장수가 있었는데 그의 이름은 다케나카 시게하루(죽중중치竹中重治)이다.

다케나카 한베(죽중반병위竹中半兵衛)라는 이름으로 잘 알려져 있다.

시게하루와 히데요시가 여러번 싸웠으나 번번히 기노시타가 패하였다.

영주 다쓰오키는 주색에 빠져 정무를 돌보지 않아 시게하루가 몇번 건의 하였는데 무시 당하였다.

1564년 시게하루는 동생 시게노리를 문병 한다는 핑계로 수하 16명을 의료진으로 꾸며 이나바 산성에 들어가 다쓰오키를 사로잡고 성을 탈취 하였다.

노부나가는 이소식을 듣고 자신에게 달라고 하였으나 시게하루는 거절하고 다시 다쓰오키에게 돌려 주었다.

“주군, 이성을 다시 돌려 드리겠사옵니다. 그대신 술과 여자를 멀리 하시고 간신을 가까이 하지말것이며 백성을 사랑 하소서.”

다쓰오키는 당장 알겠다고 하며 성을 돌려 받고는 시게하루와의 약속을 지키지 않았다. 

 

1565년 교토에서 미요시가는 제13대장군(쇼군)아시카가 요시테루(족리의휘足利義輝)와 반목하다 요시테루를 죽이고 말았다.

이를 에이로쿠의 변이라 한다.

미요시가는 요시테루의 사촌동생  아시카가 요시히데(足利義栄)를 쇼군으로 추대 하였다.

 

1567년 노부나가는 멍청한 다쓰오키를 물리치고 미노를 차지 하였다.

노부나가는 이나바 산성을 기후로 바꾸었다.

“중국 문왕의 기운이 있다는 기산(岐山)과 공자가 태어난 곡부(曲阜)에서 한자씩 따서 오늘부터 이성을 기후성(岐阜城)이라 하겠다. 또한 나는 [천하포무]란 인장을 사용 하겠다.”

천하포무는 무력으로 천하를 취한다는 뜻으로 천하통일의 야망을 드러낸 대목이다.

그는 천하통일로 전쟁이 없는 세상을 만들겠다고 결심했다.

노부나가는 낭인이 되어 떠돌던 시게하루를 맞아 들였다.

그러나 남의 말을 듣는것을 싫어하는 노부나가는 도키치로의 부대에 편입 시켰다.

 

요시테루의 동생 아시카가 요시아키(족리의소足利義昭)는  에치젠 아사쿠라 요시카게(조창의경朝倉義景)의 영지로 들어갔다.

요시아키는 요시카게가 원수인 미요시가문을 치는데에 관심이 없어 노부나가에게 도움을 청한다.

요시아키는 아케치 미쓰히데(명지광수明智光秀)를 사자로 보냈다.

“요시아키님은 노부나가님께 쇼군(將軍)의 자리에 앉도록 도움을 달라고 하셨습니다.”

미쓰히데는 사이토 도산의 가신 이었는데 그의 사후 낭인이 되어 떠돌아 다녔다.

미쓰히데는 조정과 인맥이 깊고 문화에 관심이 많으며 노부나가의 부인 노와 사촌관계라 자신의 수하로 삼았다.

 

교토로 진출하기 위해 오다군은 미노의 롯카쿠 요시카타(六角義賢)를 공격했다.

오다군은 미요시가의 가신들이 배반 하도록 하여 공략해 교토로 진출 하였다.

미요시 나가야스(삼호장일三好長逸), 미요시 마사야스(삼호정강三好政康), 이와나리 토모미치(암성우통岩成友通)는 패하여 달아났다.

1568년 아시카가 요시아키(족리의소)가 제15대쇼군에 앉았다.

요시아키는 노부나가에게 감사해했다.

“모든것이 다 그대의 덕분이다. 바라는 벼슬이 있는가? 원하는대로 해주겠노라.”

“벼슬은 필요 없습니다. 무역로를 장악하게 해주십시요.”

노부나가는 서양과 교역을 통해서 경제력을 일으켰다.

 

노부나가는 아사쿠라 요시카게를 공격하기 위하여 교토로 불렀다.

끝내 요시카게가 오지않자 1570년 노부나가는 에치젠으로 원정을 갔다.

어릴적부터 친분이 있었던 미카와의 성주 도쿠가와 이에야스(덕천가강)와 연합 하였다.

이에야스군의 규모는 크지 않았지만 병사들이 목숨을 바쳐 주인에게 충성을 하는 강군 이었다.

연전연승을 하던 오다와 도쿠가와 연합군은 가네가사키에서 각자의 영지로 돌려야 했다.

아자이 나가마사가 배반을 했기 때문이다.

아자이 가문과 아사쿠라 가문은 전통적으로 동맹 관계였다.

나가마사가 오다가와의 혼인 관계로 아사쿠라가를 도와주지않자 가신들이 나가마사의 아버지 히사마사를 이용해 나가마사를 움직이게 한것이다.

아케치 미쓰히데와 기노시타 히데요시(목하수길木下秀吉), 도쿠가와 이에야스가 후군을 맡아 간신히 막았다.

노부나가는 몇명 되지않는 수하들과 교토로 달아났다.

노부나가와 사이가 틀어진 쇼군은 노부나가 포위망을 형성하게 하였다.

반노부나가 세력은 아사쿠라 요시카게, 아자이 나가마사, 다케다 하루노부(무전청신武田晴信), 모리 데루모토(모리희원毛利輝元 ), 미요시가였다.

반노부나가 세력은 노부나가 포위망을 형성 하였다.

 

다케다 하루노부는 너무나 유명한 장수이므로 잠깐 알아보면 출가후 법명인 다케다 신겐(무전신현武田信玄)으로 잘 알려져 있다.

1521년 생으로 [가이의 호랑이]란 별명이 붙어 있다.

풍림화산 기마대로 유명하다.

우에스기 겐신(상삼겸신上杉謙信)과의 5차례에 걸친 가와나카지마 전투를 벌인다.

 

우에스기 겐신도 이시기에 유명한 무장이므로 잠시 알아보겠다.

1530년 생으로 [에치고의 용]이란 별명이 있다.

우에스기 겐신은 출가후 이름이고 그전엔  나가오 가게토라(장미경호長尾景虎()), 우에스기 마사토라()上杉政虎), 우에스기 데루토라(上杉輝虎)였다. 

체격이 크지않았음에도 스스로 전장에 뛰어들어 전투를 할만큼 무력이 높았고 지휘력도 좋았다.

전략이 뛰어난 반면 그대신 두통에 시달렸다.

 

아네가와강 전투에서 노부나가는 아사쿠라, 아자이 연합군에게 고전 하지만 용맹한 도쿠가와군의 활약으로 전세를 역전 시켰다.

노부나가가 셋쓰의 미요시가를 공격하는 사이 아사쿠라, 아자이, 엔랴쿠지 연합군이 오미에 쳐들어와 모리 요시나리(삼가성森可成), 노부나가 동생 오다 노부하루(직전신치織田信治)가 전사 하였다.

노부나가가 연합군과 대치하고 있을때 혼간지의 명을 받은 나가시마 잇키가 오와리, 이세를 공격하여 노부나가의 동생 오다 노부오키(직전신흥織田信興)와 사카이 마사히사가 전사했다.

잇키란 저항세력이다.

전황이 불리하게 돌아가자 노부나가는 조정에 압력을 넣어 쇼군의 명으로 연합군이 뒤로 물리게 하였다.

 

1571년 노부나가는 엔랴쿠지에 보복하려 했다.

“주군, 사찰을 불태우면 민심이 떠나버리고 맙니다.”

아케치 미쓰히데가 말렸다.

“재수없는 대머리야! 나는 그들에게 몇번이나 기회를 줬지만 듣지 않았단 말이다!”

노부나가는 그를 말리는 미쓰히데를 여러 무장들 앞에서 발로 차 버렸다.

결국 사찰을 불태우는 것을 실행에 옮겼다.

1572년 미쓰히데는 오미국 내에 영지를 받아 사카모토 성을 세웠다.

 

다케다 신겐이 미노로 내려왔다.

도쿠가와 이에야스는 전력의 차이로 패하여 간신히 달아났는데 다케다 신겐의 무서움을 뼈저리게 느꼈다.

1573년 신겐이 병사하여 다케다군은 물러났다.

다케다군이 물러나자 노부나가는 아시카가 요시아키(족리의소)를 기습하여 그를 몰아냈다.

아시카가 요시아키는 마지막 쇼군이 되었다.

얼마후 아케치 미쓰히데는 아시카가 요시아키를 방문 하였다.

“주베에, 노부나가는 언젠가 천황도 몰아낼 위험한 놈이다.”

“그렇게까지 하겠습니까?”

요시아키는 미쓰히데에게 노부나가를 감시 하도록 했다.

“주베에, 놈이 검은 속내를 들어내면 그대가 처리해야 한다. 그것만이 천하를 안정 시키는 일이다.”

 

1573년 오다군은 아사쿠라 요시카게(조창의경)를 공격 하였다.

오다군은 아사쿠라가의 신하들을 배반시켜 공략했다.

몰리게 되자 요시카게는 자살을 했다.

오다군은 아자이 나가마사(천정장정)도 공격했다.

아자이가에 시집을 간 노부나가의 여동생 이치는 구출 되었다.

나가마사도 대세가 기울자 자살을 하였다.

나가마사와 정실부인과의 어린 아들 만보쿠마루(萬福丸)는 전쟁중에 죽었다.

노부나가가 이치를 보기위해 나가마사의 영지에 방문 했을때 가신들이 암살을 계획 했어도 나가마사는 노부나가를 보호 했었다.

아사쿠라 가문과의 동맹 때문에 노부나가를 배신한 대가로 나가마사는 비참한 최후를 맞이한 것이다.

 

“원숭이, 이치를 구해내느라 고생 많았다. 너에게 오다니성을 주겠다.”

“대단히 감사합니다. 주군!”

노부나가는 히데요시를 영주로 만들어 주고 새로운 성(姓)을 내렸다.

니와 나가히데(단우장수丹羽長秀)와 시바타 가쓰이에(시전승가柴田勝家)의 이름에서 한자씩 따서 기노시타를 하시바(우시羽柴)란 성으로 바꿨다.

이치는 나가마사와의 사이에서 차차(요도)란 딸을 낳았다.

 

1574년 다케다 가문을 물려받은 다케다 가쓰요리가 쳐들어 오자 노부나가는 충돌을 피하여 기후로 군대를 돌렸다.

나가시마 문도를 공격하다 노부나가의 형인 오다 노부히로(織田信広), 노부나가의 동생 오다 히데나리(織田秀成)를 잃었다.

그대신 반란군을 싹쓸어 잠재워 버렸다.

 

1575년 다케다 가쓰요리는 다케다가를 배신한 오쿠다이라 사다마사(奥平貞昌)를 공격하려다 노부나가의 군대와 마찰이 일어났다.

노부나가와 이에야스 연합군은 가쓰요리의 기마대가 내려오는 좁은 길목에 목책을 쌓고 조총으로 공격 하였다.

일본의 기마대는 유목민족과 중국의 기마대와 달리 말을 타고 싸우지 않고 말을 타고 전장으로 간후 말에서 내린뒤 전투를 벌였다. 

기동성이 뛰어난 보병대라고 보면 된다.

일본은 산간지형이라 그런 특성이 생긴것으로 보아진다.

이전투에서 가쓰요리는 패하였고 풍림화산 기마대란 이름으로 전국에 공포의 대상이었던 군대를 물리친 노부나가에게 자신감만 불어넣어 주었다.

노부나가는 에치젠을 정벌하여 시바타 가쓰이에 북국 군단을 편성 하였다.

 

노부나가는 장자인 오다 노부타다(직전신충織田信忠)에게 지위를 물려주고 일선에서 물러났다.

1576년 아즈치성을 짓기 시작하여 1579년 웅장한 규모의 성을 완성했다.

천황이 되기위한 야심을 드러낸 대목 이었다.

 

당시 일본의 군대에 여자가 있으면 사기가 떨어진다는 이유로 남색이 유행 하였다.

노부나가는 그의 비서인 호리 히데마사(굴수정堀秀政), 모리 란마루(삼란환森蘭丸)를 이용해 욕구를 해결했다.

 

1576년 우에스기 겐신을 맹주로 하여 노부나가 포위망이 다시 형성 되었다.

1577년 시바타 가쓰이에는 에치고의 우에스기 겐신(상삼겸신)에게 공격을 받아 노부나가에게 원군을 요청 하였다.

노부나가는 하시바 히데요시(우시수길)에게 지원을 명했다.

가쓰이에는 타고난 무장이고 히데요시는 주로 전략을 쓰는 장수라 가쓰이에는 히데요시를 무시 하였다.

히데요시는 사이가 좋지않은 가쓰이에를 구원하고 싶지 않아 노부나가의 명을 어겼다.

노부나가는 자신의 명은 잘못된 것이라도 부하들이 따라야 하는데 그렇지 않으면 누구라도 처단하려 했다.

“원숭이, 네 마음대로 가쓰이에를 지원하지 않다니! 내 명을 어기겠다는 것이냐?”

“아닙니다. 주군! 후방에도 위험이 있기에 자리를 지키고 있었을 뿐입니다. 용서하여 주십시요.”

히데요시는 노부나가에게 반란의 뜻이 없음을 해명하였다.

결국 시바타 가쓰이에가 겐신에게 패하자 노부나가는 지원군을 다시 돌렸다.

상황이 이렇게 돌아가자 마쓰나가 히사히데(송영구수松永久秀)는 노부나가를 배신 하였다.

노부나가는 배신자 히사히데를 공격하여 히사히데는 죽고 말았다.

 

1578년 노부나가에게 운이 좋게 우에스기 겐신도 갑작스럽게 죽었다.

겐신은 진지내 변소에서 쓰러져 죽었다.

겐신이 결혼을 하지않아 자식이 없고 양자만 있었는데 후계자를 정하지 못했기 때문에 우에스기가에는 혼란이 일어났다.

자연스레 노부나가 포위망도 사라지게 되었다.

 

노부나가의 영지가 넓어지자 여러방면에 군단을 형성 하였다.

우에스기 가게카쓰(상삼경승上杉景勝)은 시바타 가쓰이에가 견제하고 주코쿠(중국) 방면은 하시바 히데요시, 시코쿠(서국)은 니와 나가히데가 맡았다.

노부나가의 군단은 사방으로 뻗어나가 영지를 계속 넓혀 천하통일의 기반을 다졌다.

노부나가를 유일하게 막을수 있던 다케다 신겐과 우에스기 겐신이 사라지자 이제 남은 위협은 모리군과 호조군 정도였다.

오다군이 이렇게 성공한 이유는 직업군인제도를 들수 있다.

당시 일본은 반농무사로 평상시에는 농사를 짓다가 농번기를 피해 전쟁을 벌여 농민이 군대에 소속되었는데 노부나가는 전쟁의 경험이 많은 병사를 정예군으로 데리고 있었다.

 

아라키 무라시게(황목촌중荒木村重)가 배반하자 히데요시는 그의 부하 구로다 요시타카(흑전효고黑田孝高 = 구로다 간베에 : 흑전관병위黑田官兵衛)를 보내 항복 하도록 만들었다.

오히려 요시타가는 사로잡혀 감옥에서 생활하게 된다.

노부나가는 요시타카가 돌아오지 않자 배신을 한줄알고 그의 어린아들 구로다 나가마사(흑전장정黑田長政)를 죽이라고 히데요시에게 명했다.

다케나카 시게하루가 히데요시를 말렸다.

“히데요시님, 간베에님에게 무슨일이 생긴것이 틀림없습니다.”

“나도 간베에가 배반했다고 생각하지 않네. 그러나 주군의 명이 떨어진 이상 듣지 않으면 내목숨도 위험해!”

시게하루는 가짜목을 보내게하고 어린아이를 살려 두었다.

1년후에 오다군은 무라시게를 무찌르고 요시타카를 구출한다.

요시타카는 자신의 아들을 살려준 시게하루에게 고마워 했다.

요시타카는 오랜 감옥생활로 다리가 불편하게 되었다.

 

시게하루는 몸이 약하고 병을 앓고 있어서 히데요시가 쉬게 하였지만 전장에서 죽기를 원했다.

시게하루는 죽어가면서 히데요시에게 요시타카를 중용하라 권했다.

“히데요시님, 저는 먼저 가시만 간베에님은 생각이 깊어 히데요시님의 앞길에 도움이 될 것입니다. 앞으로 모든일을 그와 상의 하십시요.” 

 

1579년 노부나가는 자신의 사위이자 이에야스의 장남인 마쓰다이라 노부야스(송평신강松平 信康 )와 이에야스의 처인 쓰기야마에게 처형을 명했다.

적과의 내통 혐의가 그이유이다.

이에야스의 가신들은 당연히 반대 하였지만 노부나가와의 충돌을 피하고 싶은 이에야스는 명을 따랐다.

 

1580년 오랫동안 오다가문에서 일한 중신 사쿠마 노부모리(좌구간신성佐久間信盛)를 무능력하다는 이유로 추방했다.

하야시 히데사다(林秀貞), 안도 모리나리(안등수취安藤守就)는 과거에 배반 했다는 이유로 추방시켰다.

그러나 가쓰이에는 능력이 뛰어나 추방시키지 않았다.

노부나가는 무능력하고 권리만 누리려는 가신들을 정리하여 공을 세우고 능력이 있는 자에게 영지를 나눠주려 한 것이다.

옆에있던 가신들은 불안할 수 밖에 없었다.

능력이 없으면 자신들도 언젠간 쫓겨날 수 있기 때문이다.

 

1582년 노부나가는 연합군을 형성해 다케다 가쓰요리를 공격했다.

전황이 불리하자 다케다가의 무장들은 앞을 다투어 항복을 하였다.

노부나가는 손쉽게 다케다령을 점령했다.

JavaScript 의 과거, 현재, 미래

이 글은 2013년 05월에 월간 Microsoftware  제 이름으로 기고한 글을 바탕으로 작성된 글입니다.

ECMAScript와 JavaScript

JavaScript 만큼 세상에서 오해받고, 천대받았던 언어가 갑자기 트렌드의 주류로 떠오른 (번역), 대박 인생역전 언어가 또 있을까?

이번 포스트에서는 일단 JavaScript의 표준안인 ECMAScript 에 대해 알아보고, 그 태생이 어떻게 진행되어 갔는지를 한번 써 보려고 한다.

ECMASCRIPT Cloud - by John Resig
ECMASCRIPT Cloud – by John Resig ## Released under the GPL v2

ECMAScript???

이쪽 분야에 큰 관심이 없는 사람은 ECMAScript 라는 생소한 단어를 보고 어리둥절할지 모르겠다.

ECMAScript는 JavaScript의 기초를 이루는 스크립트 언어로서, Ecma International 기구에 의하여 ECMA-262 specification 에 정의한 규격을 따른다. JavaScript는 ECMAScript를 포함하는 관계이며 ECMAScript에 여러 부가적인 요소를 덧붙인 것이 JavaScript 이다.

ECMAScript 를 기반으로 하는 언어는 JavaScript 만 있는 것은 아니고, 예전 MicroSoft 사의 JScript 나 Adobe의 Action Script 등이 있다.

역사

JavaScript는 넷스케이프에 탑재하기 위해 개발된 언어였다.

사실 시작은 엉뚱한 면이 있다. 그 당시 브랜든 아이크(BrendanEich) 는 넷스케이프에게

“10일 안에 브라우저에서 스킴(함수형 프로그래밍 언어의 일종) 이 동작하게 하겠다”

라는 조건으로 입사한뒤 언어 개발에 착수했다.

하지만 그 당시 인기 언어였던 Java 에 편승하고자 스킴 언어를 사용하려는 계획은 버리고 개발을 시작하게 되었고, 1995년 9월 역사적인 날에 넷스케이프 네비게이터 2.0에 라이브스크립트(Live Script) 라는 이름으로 탑재되어 세상에 모습을 드러내었다.

그 뒤 버전인 2.0B3에서 Sun Microsystems(현 오라클에 인수)의 동의를 얻어 이름을 JavaScript 로 변경하였다.

마이크로소프트도 이런 시류에 편승하여 Internet Explorer 3.0에 JScript가 개발되어 탑재되었는데, 이는 넷스케이프의 JavaScript의 복사본이라 할만큼 동일하였고, 상표 문제를 회피하기 위한 이름만 다른 언어였다.

이에 자극받았는지는  잘 모르겠지만, 브랜든 아이크와 넷스케이프는 JavaScript를 산업 표준화를 위해 Ecma International 에 받아들여져 ECMAScrpt 표준이 만들어졌다.

JavaScript에게는  역사적인 순간이다.
그 이후 ECMAScript 표준을 따르는 JavaScript 표준이 제안되기 시작했고 1999년 12월에 이르러서는 현재의 JavaScript의 모습을 갖춘 ECMA-262 3판의 규격을 따르는 버전이 제안되었으며 현재 이 구현(JavaScript 1.5)이 제일 널리 쓰이고 있다.

ECMA International 에서는 지속적으로 언어 규격을 변화시키고 발전시키려 노력했고 그 결과로 4번째 판을 제안하게 되었지만 많은 반대에 부딪혀 흐지부지되고 만다.

4판의 규격에는 JavaScript의 본질인 프로토타입의 특성, 간결한 표현식과는 많이 다른 이질적인 느낌의 클래스 타입 프로그래밍의 특성을 다수 도입하는 내용이었다. (클래스 객체지향, 다중 메서드 지원, 연산자 오버로딩, 타입 애노테이션, Strict Mode 등등. 이중 일부는 EcmaScript 5판에 채택되어 있다.)

이 큰 변화에 대한 반발은 거셌다.

이 변화 내용에 대해서 더글라스 크락포드 등의 유명한 JavaScript 관련 프로그래머들은 강하게 반발했으며 ECMAScript 4에 제동을 걸기 시작했다.

Douglas_Crockford
더글라스 크락포드

초보자, 웹개발자, 언어과학자가 아닌 언어 비평가들은 언어를 바꾸는 시도를 하지 말아달라
https://mail.mozilla.org/pipermail/es-discuss/2011-May/014061.html

특히 더글라스는 위와 같은 돌직구 발언을 날리기도 하는 등, 분위기는 뜨거워졌고, 거의 성명전(Outsider님 블로그 참고) 수준의 논쟁(Channy 님 블로그 참고), 이 지나간뒤 협회에서는 둘의 주장을 전부 받아들여 발전해나가기로 결정하였다.

2011년 6월, ECMAScript 5판이 발표되어 있으며, EcmaScript Harmony 라는 이름으로 현재 6판이 작업중이다.

발전

CommonJS, AMD 등의 모듈화

JavaScript는 모듈화를 언어 자체에서 지원하지 않는다. 모듈화란 쉽게 말해 기능별로 프로그램을 나누어 기능별로 개발하고 조립해가는 방식인데, Java 같은 경우 클래스와 패키지로 지원하고 있다.

JavaScript는 모듈화에 필요한 여러 요소들이 존재하지 않기에 별도의 표준이 필요했고 그 결과 탄생된 표준 이 CommonJS,AMD이다. 이들의 목표는 JavaScript의 표준 라이브러리를 만드는 것이 목표이다.

Node.JS, Rhino

JavaScript가 자주 사용되는 곳이 클라이언트 사이드이지만 본래 JavaScript는 클라이언트에 국한된 언어가 아니다.

Node.JS 는 크롬 브라우저에서 쓰이는 V8 엔진 을 사용한 서버사이드 JavaScript 런타임으로, JavaScript를 말그대로 서버환경에서 동작시키며 프로그래밍 할 수 있다. V8 엔진의 고성능답게 현재 주목을 받고 있는 기술이다.

Rhino 는 JavaScript 인터프리터를 자바로 구현한 것으로 Java 6.0에 기본 스크립팅 엔진으로 탑재되어 있다. 이를 사용하여 자바가 돌아가는 환경이라면 어디서든 JavaScript를 조작하고 실행시켜 볼 수 있다.

CoffeeScript, TypeScript, Dart

JavaScript는 분명 언어상의 한계가 극명하다. 때로는 잘못된 설계도 보이며 그 중에는 아주 치명적인 것도 존재한다. 대표적으로 보면 전역 변수의 접근이 쉬우며 모호한 타입 비교 연산, 객체지향의 구현이 까다로운 점, 모듈화를 고려하지 않은 언어 설계 등 이다.

그러한 상황을 아예 언어적으로 벗어나고자 하는 움직임도 있는데 CoffeeScript TypeScript는 그 예들중 하나이다.

CoffeeScript는 JavaScript의 언어적인 불편함과 표현력을 루비와 파이선의 친근한 문법으로 소스코드를 작성하고 별도의 컴파일 과정을 거쳐 안정된 JavaScript를 만들어 낸다.

TypeScript는 MS에서 내놓은 JavaScript 컴파일러로서 CoffeeScript가 파이썬과 흡사한 문법이라면 이쪽은 Java와 거의 흡사한 문법이다.

위 둘과는 전혀 다른 방법으로 접근한 방식도 있는데 구글에서 발표한 Dart 이다. Dart는 언어를 컴파일하여 결과물을 JavaScript로 얻는 방식이 아니며, 별도의 VM으로 구동된다.

VM의 지원만 된다면 굉장한 속도로 사용할 수 있지만 VM의 지원이 현재는 크로미움 계열의 브라우저에서만 VM이 구동되므로 사용이 어렵다는게 아쉽다. VM을 지원하지 않는 플랫폼에도 대응하기 위하여 별도의 JavaScript 컴파일러를 제공하여 Dart 코드를 변환시킬 수 있지만 결과 코드의 효율은 그리 좋지 않은 편이다.

문법 자체는 위 TypeScript와 흡사하며 Node.JS 처럼 서버사이드 환경에서도 구동할 수 있는 것은 위 두개의 언어 컴파일러에 대비되는 확실한 장점이다

관련 트윗 중에 이 셋을 비교하면서 남긴 코멘트가 인상깊다

“자바스크립트를 C라고 하면 CoffeeScript는 파이선, TypeScript 는 C++, Dart는 자바…인가요?”

결론

JavaScript는 현재 많은 변화와 주목을 받고 있다. github (Git을 사용하는 프로젝트 호스팅 서비스. 루비 온 레일스로 작성되어 있다. 현재 거의 모든 오픈소스를 여기에서 검색할 수 있으며 전세계적으로 제일 인기있는 Git 기반 서비스이다.) 의 오픈소스의 대부분을 JavaScript 가 점령하고 있으며, 인터넷에서는 많은 스터디 그룹이 생기고 그곳에서는 시간이 다르게 다양한 의견이 오가고 있다.

관련 프로젝트나 프레임워크, 라이브러리 개발도 오픈소스 개발자 뿐 아니라 MS, Google, Adobe 등의 대기업에서도 앞다투어 참여하고 있으며 서로 자신들이 제안한 표준이 W3C에 채택되기에 노력을 아끼지 않고 있다. 스크립트는 더이상 브라우저 안에서만 동작하는 개구리가 아닌, 서버사이드 뿐 아니라 다양한 플랫폼에서 활용되고 인정받고 있다.

이는 다른 관점에서 생각해보면 JavaScript를 잘 다룬다는 것은 키워드를 서치엔진에 검색한 뒤 Copy & Paste를 잘하는 것이 아닌 보다 전문적인 지식이 필요해졌다는 것을 의미하며 언어적인 면에서 많은 부분을 공부해야 할 필요성이 있다는 것을 말해주고 있다.

역사에 대해 흥미가 생기신 분은 이 포스팅도 한번 참고해 보길 바란다.

JavaScript.next에 대해서

Bon 15″ jib monitor

The BON BSM-153H is a 15″ monitor I purchased in Dec. of 2013. I love the size, just right for my Jib and its Super bright when I need it to be. It’s jam packed with features I may never use and discovered some that are now VERY useful.

 

I purchased mine through Nebtek out of Salt Lake City Utah (Talk to Trish) they were right on it and have offered great post sales support. I also talked with the LA rep. Shane Harness, both gave me identical quotes, but went with Trish primarily because I live in CA I could save the CA sales tax, sorry Shane …and CA.

 

I love that this monitor has just about every input I need. SDI for multiple video feeds, Component(for my old HVX), HDMI (for my 5D), DVI (for my computer) and composite (for old time sake).

 

BON claims that the screen is 1500cd/m², I don’t know what that means, but all I know is that I can see my picture perfectly, even with the sun shining directly on it. It has two other brightness presets, one for indoor and two others for High Bright outdoors.

 

A caution for using the monitor in the High Bright (Outdoor) mode: When you are using the monitor for the DP to look at exposure etc., be sure you’re in the indoor mode. In outdoor mode, you’ll think you’re overexposed. We made this mistake right off the bat when setting the exposure from this monitor (too our eye) then looking at the waveform to discover we were indeed under exposed. We only use the daylight mode when used for framing and not picture.

 

Though some DP’s may feel that other monitors are better suited for “Video Village” picture accuracy, I find my monitor to be pretty good. I use mine as the second “program” monitor with my Mac Pro (FCP 7) and feel my results are real world.

 

All in all, this monitor met all my expectations and then some. One of the bonus features is it has is GPI (General Purpose Interface) trigger control menus. What this means is I can set monitor functions (i.e. Tally, Input, Focus Assist, Under/Over scan, Markers Etc.) to be changed by a remote trigger or button. There are Five GPI controls in the menu you can assign to just about any monitor function.

 

So, I built a box that Velcro’s to my jib, using a short Cat 5 cable, it is connected to my Monitor. I found a Photoelectric Switch Sensor Relay Module on amazon for $7 (Seven Dollars) and I can tape the Photo Cell to the camera’s tally light, assigned one of the GPI menus to trigger tally and bingo my tally indicator shows on the screen.

 

Then I wired four momentary buttons into my Jib’s Zoom controller and assigned each button a GPI function. I now can toggle on & off the Focus assist when I need it (it can be really distracting always on), I can switch from one SDI input to another (for checking the “Program” feed from the truck), or whatever I may need without having to reach up to the monitor, it’s right there with my zoom functions. And, the whole remote box only cost me about  $150 and about three days of soldering.


This monitor, for me, is what I’ve always needed. The price is right, inputs everything I need, has functions that are useful and can be controlled remotely; I recommend this monitor.

BTW: The remote/tally project was not rocket science and I will share my hand drawn schematic/notes on request. I am not interested in building another, as the time involved would make for an expensive little box; that said I can be bought. 

Bret Allen s.o.c.

파이썬으로 CGI 프로그램 작성하기

파이썬(Python)으로 CGI 프로그램 작성하기

이강성

2000.1.26

차례

여기 사용된 소스를 다운 받으려면 여기(WinZip 파일) 또는 여기(tar.gz 파일)를 클릭하세요!!!

 

왜 파이썬으로 CGI프로그램을 작성해야 하는가?

먼저, 파이썬(Python)은 범용 언어라는 것을 말해야겠다. 파이썬은 대부분의 웹 프로그래밍에 적당하지만, 단지 몇 개의 SSI(Server Side Include) 페이지가 필요하다면 PHP와 같은 언어가 더 적당할 것이다.

Perl은 CGI의 ‘왕’으로 알려져있다. Perl은 텍스트 스캐닝과 프로세싱에 잘 맞는 언어이고, 확장된 CGI 모듈은 잘 설계되었다. 하지만, 전문적인 Perl 프로그래머를 제외하고는 Perl을 이용하여 빠른 어플리케이션을 작성하기란 보통의 프로그래머로는 생각하기 어렵다. 펄의 잡음 같은 문법과 ‘어떤 일을 수행하는데는 한가지 이상의 방법이 존재한다’라는 철학은 관리하기 어려운 복잡한 코드를 만들어 낸다.

괜찮고 강력한 프로그램이 펄로 쓰여질 수 없다고 이야기하는 것은 아니다. 때때로 다른 사람의 복잡한 코드를 이해하기 위해서 언어 자체에 관한 지식이 필요하다. 만일 여러분이 처음부터 웹 프로그래밍을 시작하려 한다면 파이썬을 진지하게 고려해봐아야 할 것이다. ‘그 일을 하기에는 바로 이런 방법이 존재해!’ 와 같이 명백한 방법론을 제공하는 파이썬을 말이다.

파이썬은 다른 어떤 언어보다도 더 깔끔한 문법을 갖는다. 또한, 파이썬 자체가 객체지향을 위해서 만들어 졌다. 하지만 클래스를 사용하건 말건 그것은 사용자에 달렸다. 클래스를 사용하지 않더라도 모듈단위의 객체 개념을 사용할 수 있다. 파이썬은 깔끔하고, 읽기 좋은 구문 구조는 이 언어를 배우는 사람들에게 ‘축복’이라고까지 할 수 있다.

아파치 서버에서 프로그램을 개발하는 사람들은 mod_python 이나 pyApache 모듈이 아파치 안에 숨겨져서 펄 프로그램의 수행속도와 견줄 정도가 되는 것에 놀랄 것이다.

최근에 파이썬은 매우 확장적이고, 잘 정리된 다양한 유용한 포터블 라이브러리를 갖는 모듈이 개발되어왔다. 인터넷 관련 모듈은 상당히 흥미있어서, 파싱, URL검색부터 POP서버로부터 메일을 가져 오는 것까지, 그리고 그 사이의 모든 기능이 있다. GUI부터 데이터베이스까지 다루는 또 다른 모듈들도 존재한다.

 

첫 번째 CGI 프로그램

여기서 우선, 여러분이 파이썬 실행 환경을 갖추고 있고 웹서버가 준비되어있다고 가정하겠다. (그렇지 않으면 더 진행할 수 없다.)  먼저 설명해야 할 것은 여러분이 아파치 서버를 사용하고 있다면 mod_python 혹은 pyApache를 사용하기 바란다( http://www.modpython.org/,http://www.bel-epa.com/pyapache/ ) 그 모듈은 인터프리터를 시작하고, 연결을 설정하는 시간을 절약해 줄 것이다.

여러분이 유닉스에서 아파치 서버를 사용하고 있다면, CGI가 기본적으로 위치해야 할 디렉토리는

      user_home/public_html/cgi-bin  (예: /home/gslee/public_html/cgi-bin)

이거나 그 서브디렉토리일 것이다. user_home은 여러분의 홈 디렉토리이다. (시스템 설정에 따라 달라지니 확인해 보아야 한다.) 다음에 여러분이 작성할 첫 번째 CGI 프로그램을 보인다. 파일명은 hello.py라 하자. 아무 텍스트 편집기를 사용하여 다음 파일을 만든다.


#!/usr/bin/python

# Tell the browser how to render the text
print "Content-Type: text/plain\n\n"

print "Hello, Python!"  # print a test string

Linux/Unix를 쓰고 있다면 파일을 만들고 난 후 반드시 chmod +x hello.py를 하여 실행모드를 주는 것을 잊지 말자!!! 첫 번째 라인

#!/usr/bin/python

은 Linux/Unix 시스템에만 필요하지만, 다른 운영체제에서는 문제를 일으키지 않는다. 파이썬 인터프리터를 자동적으로 호출하기 위한 경로명이다. 따라서 이 경로명은 정확해야 한다. /usr/local/bin/python 인 겅우도 있다. 윈도우즈나 매킨토시에서는 파이썬 파일을 실행하도록 다른 절차를 거쳐야 한다. 첫 번째 문자가 #이라면 주석(comment)문이다.

# Tell the browser how to render the text

이것 역시 주석(comment)문이다.

print "Content-Type: text/plain\n\n"

표준 출력으로 Content-Type: text/plain 와 두 개의 new-line코드를 출력한다. 표준 출력은 서버를 통해서 클라이언트(웹브라우저)로 전달된다. 이 첫 번째 출력 내용은 어떤 형식으로 문서가 구성되어 있다는 것을 나타낸다. text/plain은 일반 텍스트 문서임을 나타낸다. 나중에 text/html 문서를 보내는 방법을 배울 것이다. \n은 줄 바꾸기 키인 Enter키 코드에 해당한다. 이것은 CGI 문서 교환에 있어서 표준이다. 두 개의 new line이 필요하다.

print "Hello, Python!"  # print a test string

이 문은 단순히 Hello, Python!을 출력한다. 이 출력은 화면이 아닌 웹 브라우저로 전달된다.

자, 이제 웹 브라우저에서 이 CGI 모듈을 호출해 보자. hello.py가 gslee/public_html/cgi-bin 에 저장되어 있고, 아파치 서버가 cgiwrap을 이용하여 개인 사용자(gslee)에게 cgi 쓰기를 허용한다면,

http://sr.kwangwoon.ac.kr/cgi-bin/cgiwrap/~gslee/hello.py

와 같이 호출할 수 있다. 만일 루트의 권한이 있어서 /home/httpd/cgi-bin에 hello.py를 저장한다면, 다음과 같이 호출한다.

http://sr.kwangwoon.ac.kr/cgi-bin/cgiwrap/~gslee/hello.py

화면에 “Hello Python!”이 나온다면 성공!!!!

 

폼 태그와 연결하기

앞 예는 CGI의 동작을 보여주는 실용적인 예로서는 충분하지 않다. 여기서는 간단한 실제의 CGI 프로그램 예를 보여준다. 파이썬에 대해서 잘 모르면 설명서 윈도우를 올려놓고 함께 참고하는 것도 좋은 방법일 것이다.

먼저 알아야 할 것은, 어떻게 HTML 문서의 폼 태그로부터 정보를 얻어 오는 가이다. 파이썬은 이를 위한 훌령한 모듈을 제공한다. 그 모듈이름은 우연하게도 cgi이다(^^).  예를 보자.

HTML 폼에 있는 데이터는 input 요소의 이름으로 참조된다. 예를 들어 <INPUT TYPE=TEXT NAME=email SIZE=40> 는 email이란 이름의 40자 폭의 텍스트 박스를 만들어낸다.

이 정보는 CGI로 GET이나 POST 방법으로 전달된다. 하지만 신경쓸 것 없다. cgi 모듈은 이 방법의 차이를 여러분으로부터 숨기며, 파이썬의 기본 데이터형-사전-으로 값을 전달한다. 사전은 숫자가 아닌 내용으로 참조되는 배열과 유사하다. 파이썬 cgi모듈은 FieldStorage라 불리는 메써드를 제공한다. 이 메써드는 모든 폼 <INPUT>과 그에 대응하는 값을 저장한 사전을 리턴한다. 원하는 INPUT 요소의 이름을 알면 다음과 같이 쉽게 값을 얻을 수 있다.


import cgi
The_Form = cgi.FieldStorage()
print The_Form["email"].value

 
The_Form = cgi.FieldStorage()

는 폼의 input 이름과 값을 저장한 사전을 돌려주고,

print The_Form["email"].value

는 ’email’ 태그의 값을 출력한다. 물론

email = The_Form['email'].value

와 같이 값을 변수에 저장할 수도 있다. 만일 폼 태그로 넘어오는 전체 변수이름들을 알고 싶으면

print The_Form.keys()

값들 목록을 보고 싶으면

print The_Form.values()

한다. 단지 위의 순서는 보장이 안된다는 것을 명심하자. 만일 정의되지 않은 혹은 값이 없는 필드를 얻고자 하면 예외가 발생한다. 만일 이것을 여러분이 처리하지 않으면 스크립트는 중단된다. 그래서 “Internal Server Error”를 보게 될 것이다. 예외처리의 자세한 내용은 파이썬 매뉴얼을 참조하기 바란다. 간단히 처리하는 예를 여기서 보이면 다음과 같다.


import cgi
The_Form = cgi.FieldStorage()
try:
email = The_Form["email"].value
except (KeyError, TypeError):
email = ''
print email

종합해서 간단한 프로그램을 작성해 보자. HTML 폼이 제공하는 모든 변수를 출력하는 예를 작성해 보자. (prfield.py)


#!/usr/bin/python

import cgi   

print "Content-Type: text/plain\n\n"

The_Form = cgi.FieldStorage()

for name in The_Form.keys():
    print "Input: " + name + " value: " + The_Form[name].value + "
"

print "Finished!"

보는 바와 같이, 이 프로그램은 HTML 폼에서 제공하는 모든 변수의 값을 출력한다.

for name in The_Form.keys():

는 모든 변수의 이름에 대해서 반복하는 제어문이고, 각 변수이름에 대하여 다음 문을 수행한다.

    print "Input: " + name + " value: " + The_Form[name].value + "

여기서 name은 변수명이 되고, The_Form[name].value는 그에 해당하는 값이다. 문자열에 있어서 ‘+’ 연산은 두 개의 문자열을 붙인다.

HTML 문서에는 다음과 같은 폼을 만들 수 있다. (http://sr.kwangwoon.ac.kr/~gslee/prfield.html)

<form name=”form” method=”get” action=”http://sr.kwangwoon.ac.kr/cgi-bin/cgiwrap/~gslee/prfield.py”&gt;
<p>
email:<input type=”text” name=”email”>
name:<input type=”text” name=”name”>
<input type=”submit” value=”실행”>
</p>
</form>

폼 태그에서 action=”http://sr.kwangwoon.ac.kr/cgi-bin/cgiwrap/~gslee/prfield.py 는 호출할 cgi 프로그램의 URL을 기술한다.

 

Display 함수를 정의하자

앞의 예를 봐서 알겠지만, CGI란 생성된 정보를 갖는 새로운 문서를 만들어 주는 프로그램이다. 정보를 생성하는 것은 응용에 따라서 쉬울 수도 있고 어려울 수도 있다. 그 것은 일반 프로그래밍과 다르지 않다. 그러나 어떠한 경우에나 문서를 좀 더 멋지게 보이기 위해서는 HTML 문서 형식으로 출력해야 하는데, 이 것을 CGI프로그램상에서 하기에는 좀 번거롭다. 물론 많은 경우 그렇게 하기도 하지만, 프로그램이 커질수록 관리하기가 점점 더 어려워진다. 가장 좋은 해결 방법은 HTML문서의 틀은 HTML 문서 편집기로 편집한다(디자인). 그리고 그 틀 안의 원하는 위치에 CGI에서 생산된 정보를 배치시키면 디자인과 프로그램 작업을 분리할 수 있다.

다음의 예를 보자. 실제적인 HTML문서는 이것 보다는 훨씬 더 복잡하겠지만 기본적인 아이디어를 설명하기 위하여 가장 간단한 문서를 만들었다.

template.html

<html>
  <head>
    <META NAME="keywords" CONTENT="blah blah -- your ad here">
    <title>Python is Fun!</title>
  </head>
  <body>
                <!-- *** INSERT CONTENT HERE *** -->
  </body>
</html>

문서중에 <!– *** INSERT CONTENT HERE *** –> 부분은 CGI에서 생성된 정보로 대치될 부분이다. 파이썬 프로그램은 이 부분을 찾아서 다른 문자열로 대치한다. 이것을 수행하기 위해서 한 문자열을 다른 문자열로 대치하는 방법이 필요하다. 정규식(Regular Expression:RE)으로 이것이 가능하다. 파이썬의 PE는 펄의 것과 거의 동일하다. 하지만 이것이 언어의 일부로 설계된 것은 아니고 모듈(re)로서 제공된다. 정규식에 대해서 더 알고 싶으면  the Regular Expression HOWTO를 참고하기 바란다.

모듈 re는 subn 함수를 제공하는데 형식은 다음과 같다.

subn (pattern, repl, string)

string에서 pattern을 찾아서 repl로 바꾼다. 예를 들면 다음의 예는

res = re.subn('abcd', 'xyz', 'abcdefghi')
print res
('xyzefghi', 1)

의 출력을 낸다. ‘abcd’를 찾아서 ‘xyz’로 바꾼다. 출력은 터플인데 첫 번째 값은 치환된 스트링, 두 번째는 성공했으면 1, 실패했으면 0이다. 따라서 res[0] 은 ‘xyzefghi’이고 res[1]은 1이다.

Display() 함수는 하나의 인수(Content)를 받는데 이 것은 <!– *** INSERT CONTENT HERE *** –> 위치에 들어갈 문자열이다.

자 이제 함수 Display를 만들 모든 준비는 됐다.


import re  # 정규식 모듈 사용할 수 있게 import 한다

# 틀 파일을 지정한다
TemplateFile = "template.html"

# Display 함수 정의
# 하나의 인수를 받음 - 표시할 문자열임
def Display(Content):
    fp = open(TemplateFile, "r")  # 파일을 읽기모드로 연다
    # 전체 파일을 읽어 들인다
    TemplateInput = fp.read()     
    fp.close()                    # 파일을 닫는다

    # 틀 파일이 망가져서 예외가 발생했을 때 출력할 예외 문자열을 정의
    BadTemplateException = "틀 파일에 문제가 생겼어요!"

    SubResult = re.subn("<!-- *** INSERT CONTENT HERE *** -->",  
        Content,TemplateInput)
    if SubResult[1] == 0:
        raise BadTemplateException  # 예외를 발생시킨다

    print "Content-Type: text/html\n\n"
    print SubResult[0]

BadTemplateException은 틀 파일이 망가졌을 때 예외를 발생시키기 위해서 정의되었다. 만일 틀 파일에서 주석을 발견할 수 없을 때는 치명적인 에러를 발생시키고 프로그램을 중단한다. 또한 프로그램이 단순히 틀 파일을 open 할 수 없을 때에도 (unhandled, fatal) 예외를 발생시킨다.

앞서 설명했듯이 다음 문은 틀 파일 텍스트(TemplateInput) 의 <!– *** INSERT CONTENT HERE *** –>를 Content 변수에 저장된 문자열로 바꾼다.

    SubResult = re.subn("<!-- *** INSERT CONTENT HERE *** -->",  
        Content,TemplateInput)

subn 함수는 터플을 돌려주는데 첫 번째 값은 치환된 문자열이고 두 번째는 정수값으로 성공했으면 1, 실패했으면 0의 값을 갖는다.

여러분은 이제 자신의 CGI 프로그램에서 이 함수를 사용할 수 있다. 출력할 완전한 문자열이 준비되면 Display함수를 불러라.

 

폼을 생성하고 폼을 처리하는 하나의 CGI를 만들자

앞서의 예에서는 폼을 생성하는 HTML문서와 폼을 처리하는 CGI 프로그램이 별도로 작성되었다. 여기에서는 하나의 CGI 프로그램이 폼을 생성하고, 생성된 폼에서 요구하는 내용을 처리하는 프로그램을 작성하자. 먼저, 사용될 폼을 다음에 보인다.

form.html

    
<form method="post" action="sample1.py">       
      <INPUT TYPE=HIDDEN NAME="key" VALUE="process">
      Your name:<br>
      <input type="text" name="name" size="60">
      <br>
      Email: (optional)<br>
      <input type="text" name="email" size="60">
      <br>
      Favorite Color:<br>
      <input type="radio" name="color" value="blue" checked>Blue
      <input type="radio" name="color" value="yellow">No, Yellow...
      <input type="radio" name="color" value="swallow">What do you 
               mean, an African or European swallow?
      <p>
      Comments:<br>
      <textarea name="comment" rows="8" cols="60">      
      </textarea>
      <p>
      <input type="submit" value="Okay">
</form>

전체 프로그램은 다음에 보인다.

sample1.py:

#!/usr/bin/python 

import re
import cgi 

# 틀 파일 이름
TemplateFile = "template.html" 

# 사용자에게 보여줄 폼 파일 이름
FormFile = "form.html" 

# Display 함수.  출력할 문자열인 하나의 인수를 받는다.
def Display(Content):
    TemplateHandle = open(TemplateFile, "r")  # 파일 읽기모드로 오픈
    # 전체 파일을 읽는다
    TemplateInput = TemplateHandle.read()
    TemplateHandle.close()                    # 파일 클로우즈
    # 틀 파일이 잘못 되었을 때의 예외 정의
    BadTemplateException = "HTML 틀 파일에 문제가 생겼어요~" 

    SubResult = re.subn("<!-- *** INSERT CONTENT HERE *** -->", 
                Content,TemplateInput)
    if SubResult[1] == 0:
        raise BadTemplateException 
    print "Content-Type: text/html\n\n"
    print SubResult[0] 

### 틀을 보여주고, 그 것을 처리하는 두 개의 매인 행동 함수 정의

# 간단한 함수임.
def DisplayForm():
    FormHandle = open(FormFile, "r")
    FormInput = FormHandle.read()
    FormHandle.close()     
    Display(FormInput) 

def ProcessForm(form):    
    # 폼에서 정보를 쉽게 추출..
    try:
        name = form["name"].value
    except:
        # name 이 정의안되었으면 메시지 출력하고 종료
        Display("이름은 입력하셔야 합니다. 되돌아가 주세요")
        raise SystemExit
    try:
        email = form["email"].value
    except:
        email = None
    try:
        color = form["color"].value
    except:
        color = None
    try:
        comment = form["comment"].value
    except:
        comment = None 

    Output = ""  # 출력 버퍼 초기화
    Output = Output + "Hello, "     

    if email != None:
        Output = Output + "<A HREF="mailto:" + email + "">" +  name + "</A>.<P>"
    else:
        Output = Output + name + ".<P>"     

    if color == "swallow":
        Output = Output + "You must be a Monty Python fan.<P>"
    elif color != None:
        Output = Output + "Your favorite color was " + color + "<P>"
    else:
        Output = Output + "You cheated!  You didn't specify a color!<P>"     
    if comment != None:
        Output = Output + "In addition, you said:<BR>" + comment + "<P>"     

    Display(Output) 

###
### 실제 스크립트 여기서 시작
### 

### CGI 요구 평가
form = cgi.FieldStorage() 

### "key" 는 폼에서 숨겨진 요소임.
try:
    key = form["key"].value
except:
    key = None 
if key == "process":
    ProcessForm(form)
else:
    DisplayForm()

Display 함수는 앞서 설명했으므로 넘어가기로 하자.  파이썬은 동적 해석 언어이므로 함수는 사용되기 전에 먼저 정의되어야 한다.

DisplayForm() 함수는 form.html을 출력하는 함수이다. 즉, 사용자에게 입력을 요구하는 문서를 제공한다.

ProcessForm() 함수는 DisplayForm()함수에 의해서 출력된 폼으로 사용자가 요구를 제출(submit)했을 때 처리하는 함수이다. 처리는 두부분으로 구분해 볼 수 있다. 변수 값을 꺼내는 부분과, 꺼내진 값을 조합하여 출력할 내용을 만드는 부분이다. email과 color값을 기반으로 출력할 내용을 변수 Output에 저장한다.  그리고 최후에 만들어진 결과를 표시하기 위해 Display()함수를 호출한다.

ProcessForm() 이후의 마지막 부분이 실제 코드의 실행이 시작되는 부분이다. 폼의 key값이 process이면 ProcessForm()을 호출하고, 처음 호출할 때와 같이 값이 설정되어 있지 않으면 DisplayForm()을 호출한다.

 

 

파이썬에서 데이터베이스 사용하기

CGI 프로그래밍에서 마지막으로 배워야 할 부분이 어떻게 하면 데이터베이스 질의언어 (SQL)를 파이썬에서 사용할 수 있을까 하는 것이다. 파이썬은 데이테베이스와 작업을 하기위하여 표준 API(Application Programming Interface)를 제공한다. 이 인터페이스는 제공되는 모든 데이터베이스에서 동일하게 사용할 수 있다. 따라서 여러분은 프로그램을 수정하지 않고도 어떠한 데이터베이스를 사용할 수 있다(이론적으로는).

현재 Python DBI (Database Interface) 대부분의 일반적인 데이터베이스를 지원한다 – Gadfly, mSQL, MySQL, Oracle, PostgreSQL, Informix, Interbase, Sybase, Solid

표준적인 인터페이스를 지원하지만 다른 데이터베이스를 사용하기 위해서는 각 DB에 맞는 모듈이 있어야 하는 것을 잊지는 말아라(노파심에서 한마디).

더욱 자세한 정보를 원한다면 the Database SIG (Special Interest Group)에 가보라.

여기서는 MySQL을 이용한 아주 단순한 읽기 질의를 다룬다. 처음에 해야 할 일은 모듈을 import하는 것이다.

import MySQLdb

MySQL DBI 모듈을 불렀으면, 데이터베이스를 연결함으로 초기화한다. 이 연결을 위해서 클래스 인스턴스를 생성해야 하는데 형식은 다음과 같다.

MySQLdb.connect(host, user, passwd, db, port, unix_socket, client_flag)

이 인터페이스는 키워드 인수를 통해서 필요한 값만 전달한다.

host - hostname (NULL : default)
user - username (NULL)
passwd - password (no password)
db - database name (NULL)
port - integer, TCP/IP port
unix_socket - TCP를 사용할 unix소켓의 위치
client_flag - integer, 필요할 경우 사용하기 위한 flag (0)

사용자를 gslee 암호를 secretpassword라 할 때 localhost에서 guestbook이라는 데이터베이스를 사용하기 위한 초기화 예는 다음과 같다.


import MySQLdb
connection = MySQLdb.connect(user='gslee', passwd='secretpassword', db='guestbook')
cursor = connection.cursor()  # 커서 객체를 얻어온다.
.....
cursor.close()  #사용이 종료되면 닫아준다. (직접 안하면 자동으로 닫아진다)

마지막 문장은 커서(cursor)라고 불리는 것을 리턴했다. 이 객체의 이름을 ‘커서’라고 하는데, 모든 데이터베이스의 액션은 커서를 통해서 이루어진다. 프로그램과 데이터베이스를 연결 해 주는 것이 커서의 역할이라 할 수 있다. 커서 객체는 execute()와 fetchall()과 같은 몇 개의 메써드를 가지고 있다.  execute()는 실제적으로 SQL 문을 수행하기 위해 사용되며 fetchall()은 execute()의 결과를 터플 형식으로 얻기 위해서 사용된다. 각 터플은 데이터베이스의 행(레코드)에 대응된다.

커서가 있다면, cursor.execute(statement)와 같은 형식으로 데이터베이스가 지원하는 어떠한 SQL 문도 수행할 수 있다. 전체 레코드를 얻는 간단한 예를 아래에 보인다.



#모든 엔트리를 얻는다.
myquery = "SELECT * FROM gbook ORDER BY stamp"
cursor.execute(myquery) #질의 수행
Result = cursor.fetchall() # 결과 가져오기
total = len(Result) # 결과 레코드 수 얻기

entries = []

if total < 1:
    print 'No guest book entries!'
else:
    for record in range(total):
        entry = {} # 공 사전
        entry['gid'] = Result[record][0] # guestbook ID
        entry['stamp'] = Result[record][1] # time stamp
        entry['name'] = Result[record][2] # ...
        entry['email'] = Result[record][3]
        entries.append(entry) # 리스트에 정보 추가

for entry in entries:
    print entry['name'] + '  email:' + entry['email'] + '...'

결과가 Result에 저장되며, 질의 결과로 넘어온 전체 레코드 수는 total에 저장된다. Result에 저장된 결과는 터플의 리스트 형식이므로 각 필드에 맞추어서 정보를 얻기 위해서는 필드 이름과 위치 정보를 미리 알고 있어야 한다. 0번째 필드는 guestbook ID로 사용되고 있는 것을 아는 상태에서 위와 같이 정보를 추출 할 수 있다. 이와 같은 사전 정보 없이 각 필드의 이름과 데이터 형, 크기등을 알고 싶다면 execute를 수행한 후, description 특성을 이용하면 정보를 얻을 수 있다. 이에 관한 자세한 사항은 Python Database API 2.0 문서를 참고하기 바란다.

for문에서 각 레코드 단위로 정보가 사전 형식으로 entry에 저장되고, 그 사전은 다시 entries 리스트에 추가된다.

마지막 for문은 저장된 정보를 출력한다.

데이터베이스를 다루는 것에 대해서 충분하게 다루지는 못했지만 CGI와 연결해서 다룰 만큼의 기초는 충분하다고 생각된다. 앞으로 문서가 갱신된다면 좀더 자세하게 데이터베이스를 다루는 루틴을 소개하겠다.

 

Python Database API 2.0 커서 객체에 대해서 좀 더 자세히

이 API는 데이터베이스를 사용하는 유사한 파이썬 모듈간의 호환성을 유지하기 위해서 정의되었다. 이것을 만들고 사용함으로 다른 데이터베이스에 변경없이 쉽게 적용 가능한 이해하기 쉬운 코드를 생성할 수 있다. (이것은 커다란 장점이다!!)

커서 객체

커서 객체는 질의를 수행하고 실행된 결과를 가져오기 위해서 사용된다. 커서 객체를 만드는 방법은 앞절에서 기술하였지만 다음과 같이 connection 객체로부터 얻어올 수 있다.

import MySQLdb
connection = MySQLdb.connect(user='guest', db='test')
cursor = connection.cursor()  # 커서 객체를 얻어온다.

일단 커서 객체를 받았으면 execute 메써드를 이용하여 질의를 수행할 수 있다.

cursor.execute('select * from pet')

아무 메시지 없이 다름 프롬프트가 나오면 성공한 것이다. 질의 결과로 얻어진 각 필드의 특성을 알고 싶으면 description 특성(attribute)을 이용하라.

print cursor.description

(('name', 253, 8, 20, 20, 0, 1), ('owner', 253, 6, 20, 20, 0, 1), 
  ('species', 253, 7, 20, 20, 0, 1), ('sex', 254, 1, 1, 1, 0, 1), 
  ('birth', 10, 10, 10, 10, 0, 1), ('death', 10, 10, 10, 10, 0, 1))

결과는 7개 시퀀스의 시퀀스(터플)인데, 7개 값의 의미는 다음과 같다.

(name, type_code, display_size, internal_size, precision, scale, null_ok)

(필드명, 데이터형_코드, 표시크기, 내부크기, 정확도, 비율, null가능여부)

(‘name’, 253, 8, 20, 20, 0, 1)을 예를 들어 설명하면 다음과 같다.

필드이름('name')-name, 데이터형(253)-VARCHAR, 표시크기(8)-8, 
내부크기(20)-20 (VARCHAR(20)으로 선언되었다.), 
정확도-20, 비율-0(스트링에서 별 의미 없음), null가능(1)-Yes

description은 만일 execute()를 호출한 적이 없거나 검색 결과 행을 가지고 있지 않다면 None값을 갖는다.

rowcount는 검색(select) 결과 레코드의 수 혹은 (update, insert등으로) 변경된 레코드의 수를 알려준다.

print cursor.rowcount

11L

질의 결과를 가져오기 위해서는 fetchone(), fetchmany(), 혹은 fetchall() 메써드를 사용할 수 있다.

res = cursor.fetchone()  # 결과 한 개 가져오기
res = cursor.fetchall()  # 결과 모두 가져오기
res = cursor.fetchmany(10) # 결과 10개 가져오기

이름에서 알 수 있듯이 fetchone()은 하나의 레코드를 터플로 리턴하며, fetchall()은 모든 레코드를 터플의 리스트로 리턴한다.

fetchmany(n)은 n개 만큼의 레코드를 가져온다. 만일 숫자가 지정되지 않으면 (기본값을 사용하면) cursor.arraysize 만큼의 레코드를 가져온다. 만일 충분하지 않은 레코드가 남아있다면 그 남아있는 레코드가 넘어온다. 가능한 한 일정한 수의 레코드를 요구하는 것이 시스템 성능에 도움을 준다.

만일 execute()에서 아무 결과가 없었다면 예외가 발생한다.

res = cursor.fetchall()의 질의 결과는 터플의 리스트 형태로 저장된다. 하나의 터플은 하나의 행(레코드)를 나타낸다.

res = cursor.fetchall()  # 결과 모두 가져오기
print res

[('Puffball', 'Diane', 'hamster', 'f', '1999-03-30', None), ('buffy', 'harold',
'dog', 'f', '1990-05-13', '0000-00-00'), ('Claws', 'Gwen', 'cat', 'm', '1994-03-
17', '0000-00-00'), ('whistler', 'gwen', 'bird', 'n', '1997-12-09', '0000-00-00'
), ('Fluffy', 'Harold', 'cat', 'f', '1993-02-04', None), ('Chirpy', 'Gwen', 'bir
d', 'f', '1998-09-11', None), ('Bowser', 'Diane', 'dog', 'm', '1989-08-31', '199
5-07-29'), ('fang', 'benny', 'dog', 'm', '1998-08-27', '0000-00-00'), ('slim', '
benny', 'snake', 'm', '1996-04-29', '0000-00-00'), ('fang', 'benny', 'dog', 'f',
 '1998-09-22', '0000-00-00'), ('slim', 'benny', 'snak', 'm', '1996-04-29', '0000
-00-00')]

좀더 품위 있게 정보를 출력하려면 다음과 같은 코드를 이용할 수 있다.

res = cursor.fetchall()  # 결과 모두 가져오기
print "%-10s %-8s %-8s %1s %11s %11s" % ('name', 'owner', 'species', 's', 'birth', 'death')
print
for record in res:
    print "%-10s %-8s %-8s %1s %11s %11s" % record

name       owner    species  s       birth       death 

Puffball   Diane    hamster  f  1999-03-30        None
buffy      harold   dog      f  1990-05-13  0000-00-00
Claws      Gwen     cat      m  1994-03-17  0000-00-00
whistler   gwen     bird     n  1997-12-09  0000-00-00
Fluffy     Harold   cat      f  1993-02-04        None
Chirpy     Gwen     bird     f  1998-09-11        None
Bowser     Diane    dog      m  1989-08-31  1995-07-29
fang       benny    dog      m  1998-08-27  0000-00-00
slim       benny    snake    m  1996-04-29  0000-00-00
fang       benny    dog      f  1998-09-22  0000-00-00
slim       benny    snak     m  1996-04-29  0000-00-00

또는 다음과 같이 하나씩 출력할 수도 있다. 위와 같은 출력을 얻을 것이다.

print "%-10s %-8s %-8s %1s %11s %11s" % ('name', 'owner', 'species', 's', 'birth', 'death')
print
while 1:
    record = cursor.fetchone() # 결과 하나 가져오기
    if record == None: break   # 없으면 빠져나감
    print "%-10s %-8s %-8s %1s %11s %11s" % record

“동부·두산·한진그룹도 재무부담 가중…유동성 위험 현실화될수도”

“동부·두산·한진그룹도 재무부담 가중…유동성 위험 현실화될수도”

  • 입력:2013.10.01 07:24
[쿠키 경제] 동부그룹과 두산그룹, 한진그룹의 재무 부담이 커지고 있다는 분석이 나왔다.

1일 한국기업평가의 그룹 분석보고서에 따르면 동부그룹은 비금융부문 주력 계열사들의 지속적인 투자에도 눈에 띄는 실적 개선이 이뤄지지 않아 재무 부담이 커진 것으로 평가됐다. 한기평은 그룹 전반에 걸쳐 신용도가 떨어지는 가운데 장기 차입금의 원천인 회사채가 대부분 1∼2년물에 집중돼 차입구조 개선에도 별로 도움이 안 되는 상황이라고 지적했다. 동부제철과 동부건설, 동부팜한농, 동부메탈, 동부하이텍, 동부씨엔아이 등 주력 6개사의 지난 6월 말 기준 합산 차입금 규모는 5조5000억원이며 이중 1년 이내 만기가 도래하는 차입금의 비중은 56.1%에 달한다.

한기평의 이지웅 책임연구원은 “계열사 간 지원 여력이 제한적인 수준이어서 재무 부담이 가중됐을 때 그룹 전반적인 유동성 위험이 현실화될 가능성이 있다”고 말했다.

두산그룹은 주력 계열사의 인수합병(M&A) 등에 따른 투자가 재무 부담을 키운 요인으로 지적됐다. 두산그룹은 최근 10여년 동안 12건의 M&A를 진행해 계열사 수를 25개(지난해 말 기준)로 늘렸다. 한기평은 “그룹의 외형 성장을 가져다준 M&A 전략은 사업 환경이 우호적일 때는 긍정적인 역할을 했지만, 수요시장 위축 등 업황이 부진한 최근에는 차입금·이자비용 증가와 영업외 자금소요 등의 부담으로 작용하고 있다”고 지적했다.

한진그룹은 항공·해운 업황 침체로 영업실적이 떨어지는 가운데 항공기와 선박 투자 규모가 늘어나면서 재무 부담이 커진 상태로 지적됐다. 김봉균 수석연구원은 “국내외 항공·해운 시황이 침체되면서 그룹의 두 주력사인 대한항공과 한진해운의 실적이 나빠졌다”며 “두 회사의 최근 영업실적과 투자계획을 감안하면 그룹 전반의 차입금 확대 추세는 당분간 이어질 전망”이라고 말했다. 김 연구원은 “최근 한진그룹은 지주사 체제 전환을 도모하고 있는데 순환출자 해소 등 그룹 지배구조 개선 과정에서 일부 주력 계열사의 재무 부담이 커질 가능성도 있다”고 덧붙였다.

국민일보 쿠키뉴스 천지우 기자 mogul@kmib.co.kr