이글루스에 개설했습니다.

네. 이사간다는 이야기는 아닙니다. 정리하면서 사라졌던 분류의 글들을 쓰기 위해 공간을 하나 더 만들었습니다. 사실, 이 블로그에 쓰는 글들이 지적 허영이가득 찬 글들이기도 하거니와, 그냥 무거워진 이 공간말고, 가벼운 공간이 하나 더 필요하다는 요구와 즉흥적인 지름에 하나 더 만든겁니다. 인생 뭐 있나요.

어쩌면, 포스트의 절대적인 수로는 역전현상이 나타날지도 모르겠습니다만. 과거 블로그의 제목이 ‘Crow’s Maniacal World’이던 시절에서 Devspace@Crow로 넘어오면서 사라져버린 다른 제 자신을 적어내는 공간이니 당연한 것일지도 모릅니다.

여전히, 이 곳은 쓰던 글들과 써야할 글들이 올라옵니다. 지금 쓰고 있는 글만 3개정도 되는군요. (개요잡고 고민하는 글을 이야기하는 겁니다. 제목과 주제만으로 치면 더 많… orz) 하지만, 이 곳과 텀블러에 쓰지 않던 글들이 올라오겠지요. 워낙에 관심분야도 넓고 하는 짓도 많아서 어쩔 수 없나봅니다.

그럼. 돌아온 Crow’s Maniacal World를 소개합니다. 씨익-

웹이 아닌 앱의 시대가 오고있다.

이 글은 링크없는 블로그: 반쪽짜리 블로그에서 출발하여, @minoci님, @pariscom님과의 대화를 통해 발전해서 쓰여졌습니다. 두 분께 감사드립니다. 🙂

웹은 HTTP프로토콜을 기반으로 HTML을 통한 유연한 링크를 이용해 정보사이의 소통이 가능한 길을 열었고, 이는 블로그와 위키를 만나면서 새로운 소통의 시대를 열었다고 해도 과언이 아니다. 하지만, 이 소통의 시대는 현대사회가 아직도 풀지 못하고 있는 장벽에 가로막혔다. 지정학적 혹은 정치학적 요인에 의해 갈라진 국가라는 개념이 인간사이를 막고 있는 것처럼, 이 소통의 시대는 호스트(서비스업체)라는 장벽에 가로막혀 버렸다. 무서울 정도로 국가의 개념과 호스트의 현실은 연계되는데, 현실세계에서 국가의 힘이 결국 국민의 수에 의존하는 것과 마찬가지로 호스트의 가치는 사용자의 수에 의존한다. 또한, 이민을 막는 최종적 발목이 인간관계라는 점을 비추어보아도, 웹에서 유사하게 작동한다. 호스트를 이동하는 것은 존재하던 관계를 버리고 새로운 관계를 생성해야 함을 의미한다. 게다가, 각 호스트에 모인 사람들의 특성은 국가가 제시하는 민족주의와 유사하게 사람들 사이의 집단의식을 이끌어낸다. 인간이 국가라는 틀에 갖혀있는 것처럼, 호스트 속에 갖혀버린다.

올블로그나 블로그코리아 같은 메타업체들이 힘을 쓰지 못하는 것도 마찬가지의 이유다. 대다수의 사람들은 외국과 교류하지 않는다. 지정학적으로 가까운 사람들과 소통하기 마련이며, 다른 문화의 사람들에게 배타적인 심리를 갖기도 한다. 호스트도 마찬가지다. 대다수의 웹이용자들은 자신이 사용하는 호스트내에서 제공하는 아쉬울 것 없는 기능들을 이용하여, 자신의 주변을 만들어간다. 저 멀리에 있는 다른 호스트로 찾아가서 애써 관계를 만들 이유는 없는 것이다.

초창기의 블로고스피어를 생각해보면, 이는 더욱 자명하다. 초창기의 호스트들은 사람들이 원하는 소통량을 달성할 만큼 이용자수를 갖고 있지 못했다. 따라서, 다른 호스트에 있는 사용자들과 소통할 필요를 느꼈고, 메타사이트의 출범과 함께 블로고스피어는 빅뱅을 맞이하는 듯 했다. 하지만, 이용자수가 증가하고 각각의 호스트들 내에서 원하는 소통량을 달성하게 된 사용자들은 점점 메타사이트에 가야할 이유를 잃었다. 이것이 이 블로그의 트래픽유입이 대부분 검색엔진과 RSS리더가 된 이유일 것이다.

하지만, 웹은 RSS/ATOM의 등장과 웹서비스의 발명을 통해 기능을 외부로 노출하는 가능성을 맞이한다. 일종의 국제협약이 생긴 것이다. 페이지를 표현presentation중심이 아닌 의미content중심으로 바라볼 수 있다는 가능성은, 웹을 기반으로 컨텐츠간의 융합을 가능케 했다. 하지만, 여전히 대다수의 사람들은 이 협약을 사용할 필요성을 느끼지 못한다. 여전히 그들은 만족하고 있으므로.

하지만, 쓰기 힘든 글을 기반으로 하는 블로그를 위시한 출판개념의 기존의 웹은 SNS를 맞이하며 변화를 시작한다. 고정된 의미가 아닌 흐르는 소통을 기반으로 하는 SNS들은 웹에서 발명된 것들을 차용하며, 서비스간의 교차점을 만들어냈다. 대표적인 사례가 Twitter인데, Twitter는 이미 플랫폼이란 이야기가 나올 정도로 수많은 파생물을 만들며 지금 이 시간에도 변화하고 있다. 정치적 위치와 물리적 한계가 소통을 제약하는 현실세계와는 달리 SNS는 기민함과 익명성을 무기로 소통의 흐름을 가속화하고 있다. SNS는 기존의 웹을 백엔드화 하고 있으며, 이러한 경향은 지속될 것으로 생각된다.

이런 긍정적인 변화에도 불구하고, SNS역시 국가란 개념에서 벗어나기는 힘들다. Twitter, 페이스북, 미투데이, 싸이월드 등의 SNS서비스들은 이전의 웹보다는 나아졌지만, 여전히 호스트라는 장벽에서 벗어나고 있지 못하다. 여기에서 가능성을 하나 찾을 수 있다면, 이전의 웹이 브라우져에 기반하여 제약되고 있었다면, 현대의 웹은 RSS와 웹서비스를 이용한 기능의 노출을 이용해 브라우져가 아닌 앱으로 이용이 가능해지고 있다는 사실이다. 모바일 정보처리장치들의 발전과 궤를 같이하는 것이지만, 단지 그것만은 아니다. 웹에서는 구현하기 어려운 것들이 앱에서는 손쉽게 구현이 가능하다. 실제로 웹이란 인터페이스상에서는 단순한 동기화만 가능하지만, 앱을 이용하게 되면 여러 호스트 사이의 유기적인 통합이 가능하다. FacebookTwitter를 통합한 TweetDeck이 좋은 사례가 될 것이다. (비록 현 시점에서는 좀 단순한 형태이긴 하지만)

블로그의 출현이 만들어내고 SNS가 가속화하고 있는 RSS/ATOM와 웹서비스, 그리고 이를 잘 활용하여 유기적인 형태로 만들어지고 있는 앱. SNS가 더 널리 사용되고 지속적인 발전을 하게 된다면, 이에 따라 앱 역시 발전하게 될 것이다. 그리고, SNS사이의 표준적인 -dejure이든 defacto이든- 프로토콜이 성립한다면, 웹브라우져는 의미의 지반을 보는 뷰어의 역할을 하게 되고 앱은 그 지반들을 이어주는 소통의 혈관이 될 것이다. 그리고, 모바일의 발전은 소통의 순간을 키보드에서 독립시킬 것이다. 아니, 이미 독립 시키고 있다. 이러한 것들이 서로 만나면서, 결국 국가란 개념이 웹에 뿌리내린 호스트라는 현상은 소통을 제약하지 못하게 될 것이다.

물론, 이 글이 옛날에 쓰여진 허무맹랑한 소설이 될 가능성이 없는 것은 아니다. 하지만, 빅브라더가 이미 현실로 다가온 이 시점에서 정보기술이 사람들의 소통을 억압하는 것이 아니라 이를 가속화했으면 좋겠다는 작은 희망에서 출발한 생각이므로 이대로 되었으면 좋겠다. 물론, 소통이 발전하는 만큼 감시도 발전하겠지만.

ps1. 확정형의 표현을 피하는 편이지만, 왠지 오늘은 피할 길이 없다.
ps2. 여러분은 지금 마이크로네이션에서 글을 읽고 계시고, 저는 텀블러에 대사관을 건설한 게 되는군요. 으응?!
ps3. 이 참에 다른데도 대사관을 세워볼까.. (참앗!)

애플의 폐쇄구조

컴퓨터 하드웨어와 OS를 동시에 만드는 회사는 그리 흔하지 않다. 기억하기로는 애플, Sun, HP, SGI, IBM 정도 일텐데, 각자 특징을 가지고 있다. 이 와중에서, 폐쇄적인 설계구조로 욕먹는 회사는 아마 애플뿐이리라 생각된다. Sun의 Solaris는 x86계열의 CPU(특히, 옵테론)을 적용하기 위해 x86으로 포팅된게 아닌가 싶을 정도로 자사 플랫폼에서만 사용되던 OS였고, HP의 HP-UX나 IBM의 AIX등은 아예 자사 하드웨어 플랫폼에서만 돌아간다. (고 알고있다.)

애플의 폐쇄구조를 가지고 수많은 이야기들이 오고가지만, Mac OS의 핵심부분인 Kernel이 공개되어있다는 사실은 아는지 모르겠다. 2000년경 Darwin이란 이름으로 공개가 되었으며, 해킨토시(Mac OS X을 일반 PC에서 돌리기 위한 일련의 작업들)에서 많이 사용되는 부두커널같은 녀석도 결국은 Darwin의 소스코드를 이용하여 특정 플랫폼에 맞게 작업하는 것으로 알고 있다. 물론, Quartz나 Cocoa같은 커널 위에 올라가는 다른 부분들은 공개되지 않지만, 의외로 애플에서 공개적으로 개발하는 것은 많다.

현대 컴퓨팅 환경에서 가장 중요한 컴포넌트라면 웹브라우저의 렌더링엔진을 꼽을 수 있다. 애플의 Safari에서 사용하는 엔진은 WebKit인데, KDE 프로젝트에서 진행하던 KHTML+KJS 프로젝트의 분기branch로 시작한 공개 프로젝트다. WebKit Team에 가보면, 애플과 구글의 개발자들이 참가하고 있는 것을 알 수 있다. 반면, 전통적으로 소프트웨어 개발에서 가장 중요한 컴포넌트라면 소스코드를 번역하여 기계어 코드를 생산하는 컴파일러를 꼽을 수 있다. 애플은 주목받고 있는 오픈소스인 LLVM 프로젝트에 투자하고 있다. 역시, LLVM Developers를 살펴보면, (WebKit처럼 잘 나와있지는 않지만) 애플의 개발자가 있음을 알 수 있다.

물론, 이러한 사항들이 애플이 갖고 있는 폐쇄적인 구조에 대한 변명거리가 될 수는 없다. 하지만, 애플을 컴퓨터 제조업체가 아닌 가전제품 업체로 놓고 생각한다면, 이야기는 좀 달라진다. 삼성이나 LG가 자신들의 제품에 대해서 공개하는 범위와 애플이 자신들의 제품에 대해 공개하는 범위를 놓고 보면 답이 나온다. 휴대폰만 봐도 그렇다. 애플의 휴대폰에서 작동하는 소프트웨어를 만드는 것과 삼성이나 LG의 휴대폰에서 작동하는 소프트웨어를 만드는 것을 비교해보면 자명하다. 삼성이나 LG에는 공개된 SDK가 없다. 게다가, 이들이 공개적으로 개발하는 것도 없다. 그 내부에서 무엇이 일어나고 있는지는 아무도 모른다.

애플의 폐쇄적인 구조에 대한 비판은 Mac의 경우, 보통 성능에 비해 비싼 가격에서 출발하는데, 조립컴퓨터를 사용하던 사람들의 이야기가 아닐까 생각된다. 잘 구성된 하드웨어 위에 그 하드웨어의 성능을 잘 뽑아내는 OS를 얹고, 더불어 그 둘 사이가 잘 연계되어 별 문제없이 (즉, 하드웨어와 OS의 연계에 뇌를 낭비하지 않고) 쓸 수 있는 컴퓨터가 있다면, 성능은 기본만 해주면 크게 문제될 영역은 아니다. 남은 영역은 가격인데, 가격면에서 본다 하더라도 그렇게 많이 비싼편은 아니다. 안정적인 하드웨어 구성과 OS와의 연계에서 오는 장점을 생각해본다면, 사실 이득을 본다고 할 수 있다. 물론, 일반적으로 Windows를 사용하는 PC들에게서 얻은 복잡한 세팅문제에서 출발하는 이야기일 것이다. 하지만, 생각해보자. TV나 DVD 플레이어를 구입하고 세팅에 신경쓰는 사람은 없다. 컴퓨터도 매한가지 아닐까? Let me free. 그냥 컴퓨터로 할 일을 하게 해달라.

연장선상에서 컴퓨터를 별세계의 이야기로 두지 않고, 그냥 가전제품이란 관점에서 보면, 삼성이나 LG가 불법복제 생산품들을 막으려고 애쓰는거나 별반 다를게 없다. 삼성이나 LG가 휴대폰이나 TV같은 제품들의 내부구조나 소프트웨어를 공개하지 않듯이, 애플도 마찬가지다. 그리고, Mac OS X은 애플입장에서는 자사의 제품들에서 작동시키기 위한 OS이지 소프트웨어로 판매하기 위한 OS는 아니다. 게다가, Mac OS X을 공개하거나 다른 플랫폼에 설치할 수 있도록 개방하게 된다면, 애플입장에서는 거기서 발생하는 수익보다 그걸 유지하기 위해서 들어가야하는 비용이 훨씬 커지기 마련이다. MS의 Hardware Compatibility Lab을 생각해보라. 생각만해도 머리아프다.

그리고, 최근에 애플의 폐쇄구조에 대한 이야기가 나오면, iTunes App Store에 대한 이야기가 따라나오기 마련이다. 허나, App Store가 폐쇄적이라는 이야기에 대해서는 동감하지 못하겠다. 애시당초 전혀 다른 Platform이다. 그러니까, 천문학적으로 말하자면 전혀 다른 행성이고, 생물학적으로 말하자면 전혀 다른 생태계다. 애시당초, 스마트폰이 무엇인지도 애매하다. 그리고, 클릭 몇번으로 소프트웨어를 찾아서 다운로드 받는 건, 기존의 휴대폰에도 있던 기능이다. 그 제어 권한이 통신사에서 애플로 넘어갔다는게 첫번째 차이이고, 개발자-컨텐츠 제공자-의 범위가 일반 개발자에게까지 확대 되었다는 점이 두번째 차이이다. 애플의 관리하에 있다는 것이 폐쇄적이란 이야기로 이어지는 것은 어불성설이다. 권한이 바뀌고, 영역이 넓어졌을 뿐이다. Auction이나 G마켓도 폐쇄적이란 말인가?

결론적으로 보자면, 가전업체로서의 애플은 생각보다 그리 폐쇄적이지 않고, 생각보다 많이 공개되어 있고, 개방되어 있다. 그렇다고 애플의 단점이 없는 것은 아니다. 하드웨어와 소프트웨어의 통합이라는 강점을 이용해 소비가전시장에서 돌풍을 일으켜 온 애플이지만, 하드웨어와 소프트웨어를 둘 다 한다는 것은 결국 양쪽에서 모두 경쟁해야 한다는 점이다. 현재는 연합전선의 형태로 단일전선을 유지하지만, 하드웨어 전선과 소프트웨어 전선이 분리되는 순간 애플의 위기는 다가오지 않을까 생각한다. 물론, 애플의 가장 큰 위기는 잡스의 건강이겠지만.

Let me free: 생각대로 하면 되고.

애플에서 만든 iMac. 즉, Mac OS X을 처음 써보고 꽤 큰 쇼크를 먹었다. 그냥, 컴퓨터로 하고 싶은걸 하면 되었다. 하드웨어나 드라이버 같은건 신경쓰지 않아도 되었다. 그냥 하고 싶은걸 하면 된다. 컴퓨터 가격이 아깝지 않은 최초의 순간이었다. (물론 쓰다 불편한 건 이것 저것 깔아서 바꾸긴 하지만.. 지금 내 맥에는 그런 류의 유틸리티는 없다고 봐도 된다. 그냥 필요한 것만 깔려있다.) PC를 쓸때 했던, 각종 OS관련 설정이나 삽질은 없었다.

내가 위키를 쓰지 않는 이유 역시 CN의 그것과 동일하다. personal wiki가 유용해지는 시점은 강의노트를 정리할때 뿐이다. 강의노트는 특성상 링크가 유용할 때가 많은데다가, 책의 내용을 요약하는 경우가 많으므로 대다수의 위키에서 제공하는 Table of Contents 기능이 “매우” 유리하다. 또한, 강의노트는 작성 시간에 크게 상관없다. 생각나는 것들을 정리하는 블로그. 블로그의 어원이 Web Log라는 점을 돌이켜보자. 블로그는 어떤 사람의 생각 혹은 행동의 로그다. 일기를 백과사전처럼 쓰는 사람이 없듯이, 몇몇 아티클을 쓰기위해 위키를 쓸 필요는 없는거다.

그냥, 원하는 것을 찾아서 있으면 쓰고, 없으면 만들면 된다. 자연스럽게 쓰면 된다. 시스템에 의해 불필요한 행동이 늘어나는 것 만큼 짜증나는 일이 또 있으랴. Mac과 PC의 차이는 “생각대로 하면 되고”에 존재한다. “아는대로 하면 되고”가 아니다.

이럴땐 이걸 쓰고 저럴땐 저걸 쓰면 된다. 구글Docs도 혁명적으로 생각하는 사람들이 있는데, 마찬가지다. 그냥 구글Docs가 필요할때 쓰고, MS Office가 필요할때 쓰고, Open Office가 필요할때 쓰면 된다. 그 필요의 정당성에 대해서는 당연히 고민해보아야 하겠지만.

지난번의 투정을 버리고, 아이폰을 구매한 이유도 마찬가지다. 결국은 귀찮았다. WM기반의 핸드폰을 구매할 경우의 삽질, 아이팟터치를 샀을 때의 삽질을 생각해보니, 막막했다. -_-;

어떤 시스템을 사용하기 위해 필요한 Learning Curve와 사용자가 유지해야 하는 Brain Clock수가 문제인거다. 그냥, 최대한 간단하게 원하는 기능을 쓸 수 있게 해달라. 인간의 뇌는 해야할 일이 굉장히 많으므로. 🙂

네. 그래서 아이폰 샀다구요. (아니잖아 이건!!)

MSVC 2008 STL vector

사건의 발단은 VC9으로 테스팅하던 코드를 VC7.1로 포팅하면서 발생했습니다. 이상한 점은 VC7.1이 더 빠른겁니다. ?! 그것도 무려 60%정도였습니다. VC7.1은 STLPort를 사용하고 있었고, VC9은 MS에서 제공하는 녀석을 쓰고 있었지요.

일단, 코드부터 봅시다.

// STLPort 5.2.1 _vector.h:121
typedef _Tp value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef value_type* iterator;
typedef const value_type* const_iterator;
// MSVC 2008 vector:1886
// 줄바꿈은 제가 한겁니다. @_@
typedef _Vb_const_iterator<size_type, difference_type, _Myt>
    const_iterator;
typedef _Vb_iterator<size_type, difference_type, _Myt>
    iterator;

..(생략)..

typedef iterator pointer;
typedef const_iterator const_pointer;
typedef std::reverse_iterator<iterator>
    reverse_iterator;
typedef std::reverse_iterator<const_iterator>
    const_reverse_iterator;

두둥. iterator의 타입이 포인터가 아니라.. iterator라는 클래스로 되어 있습니다. 뿐만 아니라, pointer도 iterator클래스로 되어있습니다. 내부를 파고 들어가보니 이렇습니다.


// MSVC 2008: vector:114
// 역시 줄바꿈은 제가..
_Myt& operator++()
{ // preincrement
_SCL_SECURE_VALIDATE(this->_Has_container());
_SCL_SECURE_VALIDATE_RANGE(
_Myptr < ((_Myvec *)(this->_Getmycont()))->_Mylast
);

#if _HAS_ITERATOR_DEBUGGING
if (
this->_Mycont == 0 ||
((_Myvec *)this->_Mycont)->_Mylast <= _Myptr ) _DEBUG_ERROR("vector iterator not incrementable"); #endif /* _HAS_ITERATOR_DEBUGGING */ ++_Myptr; return (*this); } [/cpp] _SCL_SECURE_VALIDATE라는 Macro를 장렬하게 호출합니다. (.. ) 이 매크로는 _SECURE_SCL 매크로에 의해 제어가 가능한데, 현재 상태가 제대로 된 상태인지 검사해주는 역할을 합니다. 잘못되면 예외를 발생시킵니다. ;; 일반적으로 vector는 T*를 반복자로 사용해도 문제가 없는 스펙을 갖고 있습니다. STLPort에서 T*를 반복자로 사용하는 이유도 그렇게 써도 되기 때문이지요. (표준안이 바뀌었을지는 모르겠습니다만..) 포인터를 반복자로 사용할 수 있다는 점은 시사하는바가 큽니다. 바로, 성능문제이지요. native타입인 T*는 컴파일러가 최적화 할 수 있는 소지도 많을 뿐더러, 인라인처리가 될까 말까 고민할 필요도 없으니까요. 대신, T*를 사용하게 되면, 이를 악용하는 프로그래머의 실수와 함께, range check와 같은 디버깅 관련 기능을 추가할 수 없다는 단점이 존재합니다.

MSVC 9.0은 단점을 위해 장점을 버린 케이스라고 할 수 있겠습니다. 뭐 성능문제는 _SECURE_SCL매크로를 끄니 5%내외로 낮아지긴 했습니다만.. 왠지 찜찜하군요. 결국 STLPort를 VC9용으로 빌드해버렸습니다. STLPort도 STLP_DEBUG모드로 사용하면, 저런 range check를 해주거든요. 🙂

사실 놀랐습니다. 저런 assertion관련 기능은 Release모드에서 별도로 켜주어야 작동하는게 맞는거 같은데 말이죠. 참고로 _SECURE_SCL을 켜두면 set에서 나는 차이는 더더욱 커집니다. 아무리 CPU가 발달해서 넘쳐나는 세상이라지만, 이건 좀 심하네요. -_-

물론, 개발툴입장에서 개발자의 편의를 추구하는 것은 당연하지만, 이런류의 편의성을 채택할거면 C#이나 Java를 쓰지 누가 C++을 쓰겠습니까. -_-; 디버깅할때나 필요할 법한 기능을 Release모드에 때려박다니.. 무슨 숨은 뜻이라도 있는걸까요. 🙁 뭐 저는 STLPort를 쓰기때문에 딱히 상관은 없습니다만. 🙂

ps1. 표준 관련 호환성은 많이 좋아지긴 한듯 합니다.
ps2. 그냥 STLPort에 투자하면 안되겠니 MS… -_-
ps3. 사고싶어요 징징.

TortoiseGIT와 Subversion. Local Commit의 사용!

TortoiseSVN을 이용한 Subversion의 사용은 매우 쾌적합니다. 멋진 UI가 가져다 주는 쾌적함과 Windows Explorer의 Context Menu확장을 통한 통합된 이용은 아주 매력적이죠.

하지만!!!!!!!!

도저히 참을 수 없는 단점이 있습니다. 바로 “Local Commit”의 부재입니다.

Local Commit은 중앙의 저장소에 Commit하는게 아니라, 프로그래머의 개인 저장소에 Commit하는 개인적인 Commit의 개념입니다. 작업량이 많을 경우에는 중간 중간 Commit하는게 필요한데 중앙의 저장소에 Commit했다간 동료들의 불평불만을 한꺼번에 받을 가능성이 있지요. 이런 이유로 Local Commit은 상당히 편리한 기능입니다.

하지만, Subversion에는 Local Commit이 없습니다. OTL. 이를 위해 Mercurial을 사용하기도 해보았지만, TortoiseMercurial의 (TortoiseSVN에 비해) 떨어지는 UI는 사용할 맛이 안날 뿐더러, Subversion과의 연동에도 문제가 많았습니다.

이리저리 찾아본 결과 GIT이라는 훌륭한 시스템이 있었습니다. GIT은 리눅스 커널등의 개발에 사용되는 소스형상관리 시스템인데, 분산된 소스형상관리 시스템의 개념을 사용하고 있으므로, Local Commit이 매우 자연스럽게 적용됩니다. Subversion과의 연동도 훌륭한 편이여서 내심 노리고 있었습니다. 하지만, 사용이 불편하다는 단점이 있었지요. 이런 와중에.. TortiseGIT이 발표되었습니다. 그렇습니다. CVS, SVN에 이어 GIT도 거북이를 등에 업은겁니다!

제가 사용한 방법은 매우 간단합니다. GIT를 일종의 SVN클라이언트로 사용하는거죠. 🙂

  1. git svn clone 명령을 이용해서 작업할 영역을 GIT repository로 복사해옵니다.
  2. 생성된 GIT내에서 작업을 합니다. blah blah TortoiseGIT가 있으니 세상이 아름답습니다.
  3. TortoiseGIT의 SVN rebase명령을 이용해 Subversion측의 변경내역을 가져옵니다.
  4. TortoiseGIT의 SVN dcommit명령을 이용해 GIT측의 변경내역을 Subversion으로 밀어 넣습니다.

스크린샷을 찍어가면서 열심히 쓰고 싶지만, 그건 나중에… git svn clone을 TortoiseGIT에서 하지 않은 이유는 TortoiseGIT이 svn clone을 수행할때 인증절차를 제대로 처리하지 못하는 문제가 있었기때문입니다. 🙁 clone할때 한번 인증 시키면 그 뒤에는 잘 되더군요.

이렇게 하니, 부담없이 작업기록을 로컬의 GIT에 남겨두고 완성한 뒤에 중앙의 SVN에 커밋하는 일이 가능해졌습니다. 🙂

하지만.. 로컬의 GIT에 담겨있던 코드들이 SVN에 넘어갈때 자잘한 커밋로그까지 다 넘어가는 문제가 있더군요. 🙁 GIT에서 branch하고 dcommit하는 부분을 따로 관리하면 이것도 정리해서 가능하지만, 커밋로그라는게 작업했던 당시의 상황을 담는 용도도 있는지라 무시하기로 했습니다. 🙂 Blame을 써보면, 자잘하게 적은 로그이지만, 나중에 유용할때가 있거든요.

나중에 필요하거나 시간이 되면 좀 더 자세히 정리해보도록 하겠습니다. 🙂

boost::array를 배워봅시다.

1. Old. Old. Old style

char buffer[1024];
...(기타 여러 코드들)...
sock.recv(buffer, 1024);

혹시 위와 같은 스타일의 코드를 작성하고 있지는 않으신가요? 물론, 잘 작동하고 문제가 없는 코드일겁니다. 하지만, 여기엔 문제가 하나 있습니다. buffer는 배열이지 객체가 아닙니다. iterator도 없으며, 멤버함수도 없습니다. 불편할 뿐더러 위험합니다. 한번 볼까요?

char buffer[1024];
...(기타 여러 코드들. 복잡해서 눈에 잘 안들어옴)...
sock.recv(buffer, 4096); // 뭔가의 필요에 의해 고쳐졌군요.

와우. 망했습니다. 스택이 깨지면서 어떤 문제가 발생할지 감도 잡기 힘듭니다. 주로 보안사고가 이런 코드에서 많이 발생합니다. buffer overflow죠. 이런 류의 “실수”를 하지 않는다고 보장할 수 있을까요? 네. 이런걸 막기 위해 사람들은 이렇게 작업하기도 합니다.

#define BUFFER_SIZE 1024
char buffer[BUFFER_SIZE];
...(기타 여러 코드들. 복잡해서 진짜 눈에 잘 안들어옴)...
sock.recv(buffer, BUFFER_SIZE);

별 문제 없어보입니다. 하지만, 버퍼의 크기가 각 위치마다 달라져야 한다면.. 그 수만큼 #define도 늘어날겁니다. enum을 쓰더라도 이건 매한가지죠.

그렇다면, 이런건 어떨까요.

std::vector<char> buffer;
buffer.resize(1024);
sock.recv(&buffer[0], buffer.size());

훌륭하죠. 이제 C++답습니다. 하지만, buffer는 여전히 stack변수이며 이 부분이 실행될때마다 매번 새로 만들어질겁니다. 그리고, 매번 새로 만들어진다는건… 매번 할당자를 호출해야한다는 겁니다. (쉽게말해 new/malloc이 매번 호출됩니다. 재앙이죠.)

이걸 막기 위해선, 그렇죠. buffer를 재사용하면 됩니다. 하지만, 재사용시에는 언제나 멀티쓰레드 환경을 고민해야하는 상황이 다가옵니다. 후.

좀 더 C++다우면서, 배열과 같은 효과를 내는건 불가능할까요?


2. olleh! array!

boost::array<char, 1024> buffer;
sock.recv(&buffer[0], buffer.size());

네. 완벽하게 C++ container스러우면서, 배열의 역할을 수행하는 자료구조입니다. boost::array이죠! 이녀석의 내부구조는 다음과 같습니다.

template<class T, int N>
class array
{
    ...(생략)...
    T elems[N];
};

유일하게 갖고 있는 멤버변수는 elems. 배열입니다! 결국 배열을 선언한 것과 동일한 효과를 갖습니다. 여기까지 왔으면, 파직 하고 뭔가 옵니다.

array는 iterator, const_iterator, size(), begin(), end(), front(), back(), empty()등의 STL컨테이너라면, 다들 갖고 있는 형식과 함수들을 갖추고 있습니다. 그러면서도 []연산자를 지원하여 기존의 배열과 흡사하게 사용할 수 있지요. 이것이 시사하는 바는 생각보다 큽니다.

기존의 배열에 알고리즘을 적용해봅시다.

char buffer[1024];
...(생략)...
char* found = std::find(buffer, buffer+1024, 'c');

위와 같은 알고리즘을 적용할 경우, 1024라는 크기상수가 지속적으로 따라다닙니다. 또한, buffer를 vector나 다른 자료구조로 바꾸기라도 하면, 꽤 많은 수정을 가해야하지요. 하지만, boost::array를 사용한다면 다음과 같이 바뀝니다.

// 편의를 위한 typedef. C++ 프로그래머의 친구죠. :)
typedef boost::array<char, 1024> buffer_type;
buffer_type buffer;
buffer_type::iterator found =
    std::find(buffer.begin(), buffer.end(), 'c');

3. 정리

사실, boost::array(TR1에 들어갔으니 이젠 tr1::array려나요.)는 굉장히 간단하고, 의미없게 느껴질 수 도 있습니다. 하지만, 과거의 배열은 원소들을 담는 컨테이너의 역할을 함에도 불구하고 STL스럽지 않다는 단점이 있었습니다. 자료구조를 다루는데 있어서, STL 컨테이너들과 굉장히 동떨어진 사용법은 코드의 일관성을 해치게 됩니다.

이런 면에서 볼 때, 배열과 동일한 구조/성능을 가지고 있으면서 STL 컨테이너와 유사한 인터페이스를 갖춘 array는 C++내에서 C의 유산에 의해 코드가 망가지는 것을 피할 수 있도록 해주는 상당히 중요한 도구입니다. 🙂 그리고, 200줄이 안되는 이 코드는 좋은 참고자료이기도 합니다. 시간 나시면 꼭 한번 읽어보시길. 🙂


A. References
boost::array의 문서

WordPress+Open ID

myid.net 서비스를 사용하고 있었다. 하지만, 오픈아이디 주소를 myid.net측 주소를 사용하는 건 아니기 때문에 위임(delegate)형태로 활용하고 있었는데, 문제는 블로그 스킨을 바꾸면 설정해놓은 delegate가 날아가버린 다는 점… 난감하지 아니할수가 없다. 간만에 스프링노트를 들어가려 했더니.. 헉;

스킨을 고칠까하다가 플러그인을 검색해보니 OpenID라는 멋진 녀석이 있어서 슥슥 깔았다. 하지만, libcurl이 설치되지 않은 관계로 작동불능. -_-; 이걸 쓰면 myid.net을 거치지 않고도 직접 Open ID를 제공할 수 있으니 여러모로 좋긴 한데… 안되는 걸 어찌하리오. (서버 관리자님께 무려 트윗으로 부탁해놨다 -ㅅ-)

좀 더 찾아보니, Extended Option이란 플러그인을 통해서 각종 메타정보를 집어넣을 수 있고, 이 메타정보에 Open ID도 있다! 만세!

혹시라도, 워드프레스 + 오픈아이디를 쓰고 싶으신 분은 OpenID를 깔거나, 저처럼 Extended Option을 써서 위임방식으로 써보셔요. =3==3

워드프레스 삽질 + 퍼엉-

사용중인 모 서버가 모 사이트에 의해 펑하고 뚫려서.. 블로그가 맛이 갔었더랩니다. -_-b
테마가 날아가서 고생이었는데, 이건 성공적으로 복구를 했고.. 관리페이지로 로그인이 안됩니다. 헉.

..

워드프레스 권한관리체계를 이리저리 따라가면서 디버깅을 하던 와중에..
관리자인 모님이 mysql인코딩을 바꿔주니 되는군요. -_-;;

확인해본결과 role이 capabilities라는 옵션으로 들어가는데 이게 DB에 저장되는데다가, 무려 string으로 저장이 되어있었드랩니다. 결국, 인코딩 문제로 권한 스트링을 분석 못한게 죄… -_-;

결국. 복구는 성공했습니다. 하악.

(주기적인 백업은 필수인듯.. T_T)