집에 애기가 있는지라 소음이 심한 PC 대신에 소음이 거의 없는 맥미니를 주로 사용하고 있습니다. 사실 아주 옛날에 중고로 산 모델이라 성능이 엄청 떨어져서 하드(?!)한 작업은 좀 힘든데요, 그래도 꾸역꾸역 쓰고 있는 중입니다. ㅠㅠ

제가 vi를 좀 좋아하는지라(^^;;;) Sublime Text2를 vi 모드로 설정해서 쓰고 있는데요, 커서 이동을 위해 J나 K 같은 문자를 길게 누르면 키가 반복 입력되서 이동하는 게 아니라 특수 문자를 입력할 수 있는 메뉴가 뜨더라구요. ㅠㅠ

얼마 간은 참고 썼는데 오늘 드디어 인내심이 폭발해서 이게 뭔가 찾아봤더니만... 액센트가 있는 문자를 쉽게 입력하기 위해 맥에서 지원하는 기능이더군요. @0@ 아니, 이렇게까지 신경써주지 않아도 되는데... 쿨럭..;;; 이걸 키 반복으로 바꾸려면 다음과 같이 입력하면 됩니다.

# 키 반복으로 설정하는 경우
defaults write -g ApplePressAndHoldEnabled -bool false

# 특수 문자 입력으로 설정하는 경우
defaults delete -g ApplePressAndHoldEnabled

이제야 잘 되는군요. ^^;;; 맥의 액센트가 있는 문자 입력 기능에 대한 내용은 Back to the MAC님의 블로그를 참조하세요.

아두이노
아두이노 인벤터 킷 - 출처 sparkfun

아두이노(Arduino)의 경우 맥(Mac)에서도 개발을 할 수 있도록 스케치(Sketch) 프로그램을 제공하고 있습니다. 마침 아두이노 보드가 생긴지라 테스트를 해보려고 맥에 연결한 뒤 간단한 LED Blink 예제를 실행해봤는데요, 아래와 같은 오류가 발생하더라구요. ㅠㅠ

avrdude: stk500_recv(): Programmer is not responding

맥(Mac)에서는 어지간하면 다 드라이버를 설치해주기 때문에 아무 생각없이 아두이노를 꽂았는데, 에러 메시지를 봤을 때는 약간 당황스러웠습니다. 그래서 구글 검색을 해봤더니 저와 같은 문제를 겪은 사람이 한두 명이 아니더라구요. 아두이노 보드는 우노 보드를 사용하고 있는데, 요즘 나오는 atmega8U 칩 버전이 아닌 FTDI 칩을 사용하는 버전에서 그런 문제가 많이 보였습니다.

한참을 검색하다가 혹시 드라이버에 무슨 문제가 있는 건가해서 드라이버쪽으로 검색을 해봤는데요, 아니나 다를까!! 역시 드라이버가 문제였습니다. ㅠㅠ FTDI 사의 사이트에서 드라이버를 업데이트하니 정상적으로 업로드가 되었습니다. 다운로드 받으려면 여기로 이동하시면 됩니다. ^^

아... 보드 설치한지 거의 1시간 만에 기본 예제를 실행했네요. ^^;;; 갑자기 피곤이 밀려와서 쉬어야겠습니다. ㅎㅎ

그럼 즐거운 주말 되세요 ^^

요즘 개인적인 이유로 우분투 계열의 리눅스를 의도적으로 쓰려고 하고 있습니다. 예전에도 쓰긴 했지만 빌드 머신으로만 활용한지라... ㅠㅠ 사실 쓴다고 이야기하기도 부끄러울 정도였거든요. 그래서 열심히 써보려고 하긴 하는데, 역시나... 맨날 쓰는 것만 쓰니 마찬가지네요. ^^;;;

쓰다가보니 부팅 때마다 매번 실행하고 싶은 프로그램이 생겼는데요, 매번 실행하려니 이것도 일이더라구요. 그래서 찾아봤더니 /etc/rc.local에 실행하고 싶은 프로그램을 지정해두면 자동으로 실행할 수 있더군요. ^^ 아래처럼 말이죠.

# 매 부팅 시 /usr/test 프로그램을 자동 실행하 싶다면 /etc/rc.local에 다음과 같이 입력

/usr/test &

그럼 좋은 하루 되세요 ^^

ps) /etc/inittab에 추가하는 방법도 있습니다. respawn 옵션은 프로그램이 죽었을 때 자동으로 재실행해주는 옵션이에요 ^^)/~

MyProgram::respawn:프로그램 경로

요즘 나오는 리눅스들은 기본적으로 ASLR(Address Space Randomization) 옵션이 켜져있는데요, 이 옵션이 켜지면 프로세스가 실행될 때마다 로딩되는 주소가 바뀌게 됩니다. 크래커들의 공격을 막기위해 들어간 기능인데요, 만든 프로그램을 디버깅할 때는 오히려 불편하더라구요. 그래서 ASLR을 끄는 방법을 찾아봤더니 의외로 간단했습니다.

echo 0 > /proc/sys/kernel/randomize_va_space

콘솔에서 위의 명령을 입력하면 즉시 ASLR 옵션이 비활성화됩니다. 활성화하려면 0을 1로 바꿔주면 되겠지요. ^^)/~

그럼 좋은 하루 되세요 ^^

펌웨어 관련 리버스 엔지니어링 자료를 찾다보니 이 바닥에서 아주 유명한 도구가 있더군요. Firmware Mod Kit(FMK)이 바로 그건데요, 펌웨어 정보를 파악해서 추출(Extract)과 재조립(Repackaging)을 편리하게 해주는 도구입니다. binwalk와 squash 파일 시스템 관련 각종 도구 및 스크립트로 구성되어 있는데, 각각 설치할 필요 없이 한 곳에 모아뒀다는 것이 장점인데, 직접 써보니 만능(?!)은 아니네요. ^^;;;

FMK를 백트랙(Backtrack) 5에 설치하고 분석하다보면 lzma 관련 라이브러리가 없다는 오류가 발생하는데요, 아래처럼 liblzma-dev 라이브러리를 설치해주면 됩니다. 간단한 내용이지만 잊어먹을까봐 남겨봅니다(요즘 들어 깜빡깜빡하는 일이 많아지고 있어요 ㅠㅠ).

sudo apt-get install liblzma-dev

그럼 좋은 하루 되세요 ^^

마크다운(Markdown)으로 플리커 사이트(flickr.com)의 이미지 삽입하기

마크다운(Markdown)은 텍스트만 이용해서 구조적인 글을 쓰도록 도와주는 일종의 문법인데요, 저는 주로 개발 로그를 정리하거나 틈틈이 메모를 할 때 사용하고 있습니다. 물론 요즘은 블로그(kkamagui.tistory.com)에 글을 남길 때도 마크다운을 사용하고 있습니다. ^^;;;

마크다운을 처음 접하게 된 건 위키(Wiki) 때문이었는데요, 위키가 글을 엮기 편하고 문법 자체가 아주 간단해서 개발 로그를 남기는 데 그만이더라구요. 그래서 처음에는 설치형 위키인 도쿠 위키(Doku Wiki)를 썼는데요, 혼자 돌리기에는 왠지 무거운 느낌도 있고해서 위키패드로 갈아탔습니다. 위키패드를 써보니 기능도 만족스럽고 마음에 쏙 들더라구요. 그래서 위키패드로 글을 쓰기 시작하다가 위키 문법에 집착하게 되고, 이게 블로깅까지 이어지면서 결국 텍스트로 글쓰는 행위 자체에 집착하게 됐습니다. ㅠㅠ

마크다운을 즐겨 쓰시는 분들 중에는 저처럼 웹에 있는 위지윅(WYSWYG) 에디터가 불편한 분도 있으실 겁니다. 위지윅 에디터의 오류로 쓴 글이 날라가거나 굵게 한 글씨가 제대로 해제가 안되고 계속 굵게 나온다거나 하는 문제를 몇 번 겪고나니 의욕이 사그라들더라구요. ㅠㅠ 뭐, 마크다운으로 갈아탄 뒤에는 그런 일이 없어졌지만요. ^^)/~ 그래서 직접 글 쓰기 사이트(Writer's Note)도 만들어 쓰고 있습니다(개 밥 먹는 중이에요 ㅎㅎ).

제가 사실 이미지는 왠만하면 잘 안넣는데요, 그래도 가끔 필요한 경우가 있어서 제 티스토리 블로그(kkamagui.tistory.com)에 이미지를 올리고 그 링크를 가져와서 넣고 있습니다. 이미지를 많이 안 쓰다보니 별로 불편한 점을 모르고 있다가 오늘 문득 불편하다는 생각이 들더라구요. 그래서 어떻게 하면 좋을까 생각을 해봤는데, 플리커 같은 사이트에 블로깅용 이미지를 모아두고 링크를 거는 방법이 좋을 것 같더군요.

그런데 왠 걸~!! @0@)/~ 실제로 이미지를 올린 뒤에 링크를 아래처럼 걸어보니 정상적으로 표시되지 않는 겁니다. ㅠㅠ 분명히 플리커 사이트에서는 잘 표시되는데 말이죠. 한참을 고민하다가 저만 이런 문제를 겪는게 아닐 것 같아서 검색을 해봤더니~!! Wannabeman 님도 같은 문제로 문제를 겪으시다가 고생 끝에 찾은 방법을 공유해주셨더군요. 해결책은 markdown과-삽질한-하루에서 보실 수 있는데요, 결론만 말씀드리자면....

사진에서 공유 버튼을 누르면 .jpg로 끝나는 그림 링크가 나오는데요, 이 링크를 마크다운 문법으로 넣어주면 됩니다~!! >ㅁ<)~!!

마크다운으로 이미지를 삽입하는 방법은 사실 링크를 삽입하는 방법과 같은데, 차이점이라면 !를 앞에 붙여주는 정도입니다. 아래처럼 말이죠 ^^;;;

![이미지 대체 텍스트에요](http://farm6.staticflickr.com/5532/12181791906_1fd29764e7_o.jpg)

이미지 대체 텍스트에요

<이미지 출처-yes24.com>

아아... 진작 검색해볼 껄 그랬구요. ㅠㅠ 그래도 해결책을 찾았으니 다행이라는....

그럼 즐거운 하루 되세요 ^^

리눅스에서 gcc를 사용해서 코드를 컴파일하고 있는데, 뜬금없는 에러가 나왔습니다. 경고(Warning)를 에러(Error)로 취급해서 빌드를 멈춘다는 메시지였는데요, 아래와 같습니다.

cc1plus: all warnings being treated as errors

make[1]: *** 끝나지 않은 작업을 기다리고 있습니다....

사실 정확한 해결책은 경고(Warning)가 발생하는 코드를 수정하는 것이지만... 경고가 발행하는 곳이 한 두 군데가 아니라서 경고를 에러로 처리하는 옵션을 끄기로 했습니다. 사실 끄는 방법은 아주 간단한데요, gcc의 컴파일 옵션에 -Wno-error를 추가해주면 됩니다. 아래처럼 말이죠 ^^)/~

root> gcc -o a.elf -Wno-error a.c

Makefile을 이용해서 빌드한다면 CFLAG 옵션에다 추가하면 더 간단히 해결할 수 있습니다.

그럼 좋은 하루 되세요 ^^

DISQUS 소셜 댓글 달기

블로그를 방문하다보면 종빈이형 블로그처럼 댓글창이 표시되는 걸 종종 봤습니다. 페이스북이나 트위터, 구글+ 등등 다양한 서비스로 로그인이 가능하고 댓글도 모아 보여주는 신기한 기능(?) 때문에 눈여겨 보고 있었는데요, 내친김에 저도 한 번 달아보기로 했습니다.

멋진 소셜 댓글 창의 정체는 DISQUS에서 지원하는 위젯인데요, 간단히 회원가입만 하면 웹사이트용부터 시작해서 워드프레스용 코드까지 클릭만으로 생성해줍니다. 저는 아무대나 붙여넣을 수 있는 Universal Code를 선택해서 코드를 만들었는데요, 최종 코드는 아래와 같이 두 가지로 나왔습니다.

첫 번째 코드는 DISQUS 댓글 위젯을 표시해주는 코드입니다. HTML의 Body 내부 중에 표시되길 원하는 곳에 붙여 넣으면 됩니다. 코드는 제가 생성한 코드니 실제로 위젯을 다실 분은 직접 생성한 코드를 붙여넣으세요. ^^;;;

<div id="disqus_thread"></div>
    <script type="text/javascript">
        /* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
        var disqus_shortname = 'writersnote'; // required: replace example with your forum shortname

        /* * * DON'T EDIT BELOW THIS LINE * * */
        (function() {
            var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
            dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
            (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
        })();
    </script>
    <noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
    <a href="http://disqus.com" class="dsq-brlink">comments powered by <span class="logo-disqus">Disqus</span></a>

그리고 두 번째 코드는 관련된 댓글을 실제로 로딩해주는 부분인데요, 역시 적당한 곳에 붙여넣으시면 됩니다. 저는 HTML의 Body 가장 밑에 붙여넣었어요. ^^;;;;

    <script type="text/javascript">
    /* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
    var disqus_shortname = 'writersnote'; // required: replace example with your forum shortname

    /* * * DON'T EDIT BELOW THIS LINE * * */
    (function () {
        var s = document.createElement('script'); s.async = true;
        s.type = 'text/javascript';
        s.src = '//' + disqus_shortname + '.disqus.com/count.js';
        (document.getElementsByTagName('HEAD')[0] || document.getElementsByTagName('BODY')[0]).appendChild(s);
    }());
    </script>

실제로 로딩되는 예제는 종빈이형 블로그Writer's Note의 아래쪽을 보시면 됩니다. ^^

그럼 즐거운 명절 되세요 ^^)/~

사실 저는 오픈소스(Open Source)에 대해서 잘은 모릅니다. 그냥 소스가 공개되어 있으니 라이센스에 따라 가져다 쓰고 대신 프로젝트 공개나 기부와 같은 방법으로 고마움을 표현해야 한다고 알고 있습니다. ^^;;;

그런데, 오늘 ZDNet Korea오픈소스 HWP 기술, 공개 1년만에 파국이라는 뉴스 기사가 떳더라구요. 기사의 내용을 간단히 요약하면 아래와 같습니다.

오픈소스 프로젝트로 HWP를 읽을 수 있는 라이브러리를 개발하고 있는 A씨가 우분투커뮤니티의 일부 회원이 자신의 프로젝트를 도용하여 영리를 목적으로 사용하고 있는 것을 발견했다. 그래서 A씨가 "관련자에게 같이 개발에 참여하는 조건으로 그동안 했던 도용을 무마해주겠다"라고 했는데 도용자가 이를 거부했다. A씨는 이에 분노해 관련 프로젝트를 삭제했으며 도용자는 처벌을 받게 되었다.

해당 사건을 구글에서 검색했더니 우분투커뮤니티에서 관련 글이 나오더군요. 글 내용은 우분투커뮤니티의 관련 글에서 보실 수 있습니다. ^^;;;

글을 읽고 났더니 뭔가 착찹한 기분이 들었습니다. 힘들게 진행한 프로젝트를 공개해주고 많은 사람들이 참여와 고마움의 표시를 아끼지 않은 덕분에 오픈소스가 많이 활성화되었지만, 이를 이용해서 사리사욕을 채우는 사람들 때문에 좋은 프로젝트들이 사라지지 않을까 걱정이되더라구요. 오픈소스(Open Source)에는 라이센스를 따를 책임이 있는데, 너무 오픈(Open)된 소스(Source)에만 관심을 두고 있지 않았나 싶습니다. ^^;;;

뭔가 꿀꿀한 저녁이군요. A님 힘내시고 너무 상처받지 않으시길 바랍니다.

제가 웹은 거의 꼬꼬마 수준이라 글 쓰기 사이트(writers-note.appspot.com)을 만들면서 모든 코드를 Control-C + Control-V로 처리하고 있었습니다. 그러다보니 뭔가 수정할 일이 생기면 html 파일을 열여서 전부 수정해야 하더라구요. ^^;;;; 그래서 공통적인 것들은 모아뒀다가 쓰면 좋겠다는 생각이 들어서 찾아보던 중.... 장고(Django)에서 {% include '파일명' %}을 쓰면 다른 파일을 당겨서 포함시킬 수 있다는 걸 알게 됬습니다. ^^;;; 아래처럼 말이죠~

# mypage.html

<html>
<body>
{% include "includes/nav.html" %}
<h1>{{ title }}</h1>
</body>
</html>

# includes/nav.html

<div id="nav">
    You are in: {{ current_section }}
</div>

include하는 파일도 템플릿(Template)을 포함할 수 있군요. 장고(Django)에 대한 잘 정리된 내용은 greenfish님의 블로그(http://greenfishblog.tistory.com/124)를 참고하시면 좋을 것 같네요 ^^

최근에 구글 앱 엔진(Google App Engine)을 알게 된 후, 그동안 구상해 왔던 글 쓰기 사이트를 조금씩 만들어 가고 있습니다. 사실 거창한 건 아니구요, 예제를 바탕으로 살을 붙여가는 중입니다. ^^;;; 간단한 글쓰기와 글 수정, 그리고 글 삭제 기능을 만들어 놓고 개밥을 먹는 중(자기가 만든 프로그램을 직접 써보는 거라고 조엘 온 소프트웨어에 나와있던... ^^;)이었는데요, 아무나 글을 삭제할 수 있게 되어있어서 그런지... 틈틈이 테스트하면서 적었던 글이 삭제되었더군요. ㅠㅠ 아흑...

그래서 로그인 기능을 추가하고 여기에 삭제 및 수정 버튼은 작성자일 때만 가능하도록 만들었습니다. 로그인 기능은 구글 앱 엔진의 코드를 그대로 이용했는데요, 코드는 아래와 같습니다.

import webapp2
from google.appengine.api import users

class MyHandler(webapp2.RequestHandler):
    def get(self):
        user = users.get_current_user()
        if user:
            greeting = ('Welcome, %s! (<a href="%s">sign out</a>)' %
                        (user.nickname(), users.create_logout_url('/')))
        else:
            greeting = ('<a href="%s">Sign in or register</a>.' %
                        users.create_login_url('/'))

        self.response.out.write("<html><body>%s</body></html>" % greeting)

위에서 보는 것과 같이 users를 import하고 users 클래스의 create_login_url() 함수와 create_logout_url() 함수를 호출해주기만 하면 됩니다. ^^)-b 와아~ 이제 이걸로 글이 마구 지워지는 일은 막을 수 있겠네요. ^^;;; 이제 코드를 응용해서 기능을 추가해봐야겠습니다. >ㅁ<)-b

그럼 다들 좋은 하루 되세요 ^^)/~

구글 앱 엔진으로 시험삼아 간단한 글쓰기 사이트를 만들고 있습니다. 사이트의 주소는 http://writers-note.appspot.com으로 정했습니다. ㅎㅎ 새로운 걸 배우는 가장 빠른 길은 필요한 걸 만들어 보는 거라는 생각을 갖고 있어서 무작정 만들기 시작했는데요 ^^;;;; 예제만 따라하다가 실제로 해보려니 이것 저것 막히는 부분이 많군요(제가 웹은 잼병이라 더 어려운듯....) ㅠㅠ

디자인은 나중에 부트스트랩(Bootstrap)을 사용할 생각이라 기본적인 html만을 사용해서 만들고 있습니다. 마크다운(Markdown)으로 글을 쓸 수 있게 만드는 것이 목표기 때문에 마크다운 라이브러리를 포함시켜야 했는데요, 관련 자료를 속 시원하게 찾을 수 없어서 엄청 찾아다녔습니다. 그러다 결국 찾긴 찾았는데... 좀 허무하더라구요. ㅠㅠ

방법은 간단합니다. 프로젝트 폴더에 원하는 라이브러리를 폴더 통째로 복사한 다음 파이썬 코드에서 import 하면 됩니다. 파이썬 마크다운 라이브러리https://pypi.python.org/pypi/Markdown에서 다운로드 받을 수 있고, 이걸 압축 푼 뒤에 markdown 폴더를 프로젝트에 복사하는 거죠. 아래처럼 말입니다. ^^;;;

폴더 구조

writers-note 폴더
|-- markdown 폴더
    |-- extentions 폴더
    |-- 관련 파일들(__init.py__ 등등)
|-- 관련 파일들(main.py, app.yaml 등등)

폴더 구조가 위와 같다면 main.py에서는 다름과 같이 쓸 수 있습니다.

main.py의 내용

import markdown

# 마크다운은 아래와 같이 사용가능!!
result = markdown.markdown("# 제목 1 양식 #")
... 생략 ... 

만약 사용하는 라이브러리가 많아서 루트 폴더에 그대로 복사하면 복잡해질 것 같다면, libs 폴더를 만들고 그 아래에 관련 라이브러리를 복사할 수도 있습니다. 아래처럼 말이죠 ^^

폴더 구조

writers-note 폴더
|-- libs 폴더(라이브러리를 모아두는 폴더)
    |-- markdown 폴더
        |-- extentions 폴더
        |-- 관련 파일들(__init.py__ 등등)
|-- 관련 파일들(main.py, app.yaml 등등)

위처럼 폴더 구조를 만들면 import 경로에 libs를 포함시켜주면 되는데요, 다른 라이브러리를 import 하기 전에 아래처럼 sys.path.insert()를 이용해서 경로를 포함시켜주면 됩니다. ^^ 이렇게 하면 라이브러리를 많이 포함해도 괜찮을 것 같네요.

main.py의 내용

import sys
sys.path.insert(0, 'libs')

import markdown

# 마크다운은 아래와 같이 사용가능!!
result = markdown.markdown("# 제목 1 양식 #")
... 생략 ... 

구글 앱 엔진의 DB 부분을 이해 못해서 수정하고 삭제를 아직 못 넣었는데, 틈틈이 살펴봐야겠습니다. ^^;;; 나중에 어느정도 완성되면 튜토리얼로 만들어 올릴 계획도 있는데, 언제가 될지는... ㅠㅠ

그럼 좋은 하루 되세요 ^^

구글에서 서비스를 하고 있는 구글 앱 엔진에 대해서 예전부터 관심이 많았는데요, 어떻게 시작해야하고 어떻게 써야할지 몰라서 계속 미뤄두고 있었습니다. 그런데!!! 얼마전에 주옥같은 글을 발견했는데요, 바로 rucifer님이 쓰신 Google App Engine 시작하기입니다. 구글 앱 엔진 가입부터 간단한 웹 페이지 등록까지 아주 잘 설명해주셨더라구요.

<구글 앱 엔진 웹사이트>

마침 애기도 자고 있는지라 rucifer님께서 쓰신 문서구글 앱 엔진 홈페이지에 있는 보고 배우기의 동영상을 보고 간단한 방명록 서비스(?!)를 따라 만들어 봤습니다. 보고 배우기 예제는 좀 빠르게 진행되는지라 중간 중간에 일시 정지하고 코드를 따라치긴 했는데요, 예제가 정말 깔끔하게 잘 되어있어서 배우기 좋더라구요. ^^;;;

저같이 웹은 잘 모르는 잼병들한테는 가뭄의 단비처럼 느껴졌습니다. ㅠㅠ 이제 좀 고민해서 방명록 예제를 불려보는 일만 남았군요. ^^;;; 예전부터 마크다운(Markdown) 문법이 지원되는 텍스트 기반 사이트를 만들어보고 싶었는데, 틈틈이 한 번 도전해봐야겠습니다.

그럼 즐거운 주말 되세요 ^^

얼마 전에 쟁이님께서 최흥배님의 블로그를 소개시켜주셨습니다(쟁이님 감사합니다 ^^). 쟁이님의 블로그를 구경하다보니 Boost에 얼마나 심취해 계시는지 알겠더군요. C++11에도 관심이 많으신 것 같았습니다.


흥배님의 블로그를 둘러보다가 재미있는 링크를 발견했는데요, 온라인 게임 서버 개발자 모임이 바로 그 곳입니다. 게임 개발하시는 분들이 모여서 서로 정보를 공유하는 곳 같은데... 오프라인 세미나를 진행하고 그 내용도 차곡차곡 모아두었습니다. 나름 신선한 내용들이 많네요. ㅎㅎ


아래는 저를 충격에 빠뜨린 C++ 11에 대한 내용입니다. 여기서 C++ 익명 함수에 대한 내용을 처음봤는데, 자바나 루비와 비슷한 모습이어서 상당히 충격적이었습니다. 사실 자바나 루비에서 작업이 완료되었을 때 호출될 콜백 함수를 함수 파라미터로 전달하는 방식을 보고 C도 그런 방식으로 할 수 있으면 좋겠다는 생각을 했거든요. ^^



음... 언어가 서로 닮아가는 듯한 느낌도 들고... 재미있네요. ^^ 이제 언어 하나만 제대로 이해하면 다른 언어도 그냥 이해할 수 있는 세상이 열릴려나 봅니다(사실 그랬으면 좋겠어요 ㅠㅠ).


시간나실 때 한 번씩 보시면 좋을 것 같네요. >ㅁ<)-b

MIPS 머신을 구할 수 있다면 좋겠지만, 보통 PC 환경이라면 MIPS 어셈블리어 코드를 빌드하고 실행해보려면 크로스 컴파일러와 시뮬레이터가 필요합니다. 크로스 컴파일러는 컴파일러 소스를 이용해서 만드는데요, Host(PC를 운영중인 환경)와 다른 환경인 Target(실제 빌드된 바이너리를 실행할 환경)에서 실행가능한 바이너리를 생성하는 역할을 합니다. 지금처럼 Intel Architecture인 PC로부터 MIPS Architecture를 사용하는 다른 장비용 바이너리를 생성하는 것이지요. ^^;;;


사실 크로스 컴파일러를 만드는 건 상당히 힘든 작업입니다. 컴파일러 소스의 버전과 실제 코드를 컴파일하는 Host PC의 컴파일러 버전, 그리고 리눅스 환경이라면 커널 소스 코드의 버전에 따라 에러를 내뿜기도 하거든요. ㅠㅠ MINT64 OS도 크로스 컴파일러를 만들어 사용하는데, 이 부분 때문에 지금 많은 분들이 어려움을 겪고 계십니다. ㅠㅠ(죄송합니다. 조만간 깔끔한 해결책을 내놓겠습니다. ㅠㅠ)


MIPS 개발 자료는 http://www.imgtec.com/mips/developers/에서 많이 찾으실 수 있는데요, 크로스 컴파일러를 만드는 자료는 http://developer.mips.com/tools/compilers/open-source-toolchain-linux/에서 찾아 보실 수 있습니다.


<MIPS 크로스 컴파일러 다운로드 및 빌드 방법>


저는 이미 빌드된 바이너리가 잘 실행되지 않아서 직접 소스를 내려받아서 빌드를 했는데요, 빌드는 중간쯤에 보시면 아래와 같이 Mips_linux_toolchain_src-1.1.tar.bz2를 다운로드 할 수 있는 부분부터 보시면 됩니다. ^^ 보통 컴파일러 소스 코드를 다운받아서 빌드하면 문제가 많이 생기는데, 깔끔하게 묶어놔서 그런지 문제없이 한 번에 빌드가 되네요. ^^ 아래는 빌드하는 방법인데, 간단하게 압축을 풀고 빌드한 결과물이 저장될 디렉터리만 지정하면 됩니다.

> tar vfxj Mips_toolchain_src-1.1.tar.bz2
> ./build-mips-sde-elf.sh --prefix=DIR


그럼 좋은 하루 되세요. ^^

파이썬(Python) 모듈을 python으로 직접 실행하는 경우만 실행되도록 하려면 아래와 같이 if __name__ == "__main__" 으로 묶어주면 됩니다. ^^

if __name__ == ""
    print "이 부분은 python a.py와 같이 직접 실행될 때만 호출됩니다"


파이썬 코드를 작성한 뒤에 실행했을 때 SyntaxError:Non-ASCII charactor… 가 발생하는 경우는 파일의 가장 위에 아래처럼 인코딩 정보를 표시해주면 됩니다.

# -*- coding: cp949 -*-      <== 윈도우에서 기본 설정으로 저장한 파일
# -*- coding: utf-8 -*-      <== UTF8 인코딩으로 저장한 파일


자꾸 까먹어서 이제는 코드 조각들을 웹에다가 올려야겠네요. ㅠㅠ 사용하는 주 언어가 아니다보니 매번 찾아보기도 귀찮고… ㅠㅠ

그럼 좋은 하루 되세요 ^^


ps) 파이썬 소켓에 대한 정보를 원하신다면 http://docs.python.org/2/library/socket.html 를 참고하세요 ^^

C++ 언어는 해가 갈수록 많은 기능들이 추가되어 점점 생산성이 향상되는 것 같네요. 저는 C++ 언어를 제대로 이해하지 못하고 있고, 잘 쓰지도 못하는 편이라 덩치가 커지고 있는 C++이 점점 무서워지고 있습니다. ㅠㅠ


C++ 표준이 다시 제정됨에 따라 마이크로소프트의 Visual Studio를 비롯해서 여러 컴파일러에 기능들이 추가되고 있는 모양이던데… 이런 새로운 기능들을 모아 구현해놓은 부스트 라이브러리를 이용하면 구식 C++ 컴파일러를 이용하더라도 최신 C++의 기능을 사용할 수 있다고 하네요. ^^;;;


부스트 라이브러리에 대한 내용은 신영진님의 블로그에서도 보실 수 있는데, 깔끔하게 잘 정리해 놓으신 것 같습니다. 특히 마지막에 있는 PPT 슬라이드는 필요한 기능만 찾아 쓰기에 그만이네요. ^^ ASIO는 시간 날 때 한 번 써봐야겠습니다. ㅎㅎ 비동기 IO를 이렇게 쉽게 처리할 수 있다니… 좀 충격이네요. ㅎㅎ


그럼 다들 좋은 밤 되시길~

MIPS를 사용하는 기기를 만질 일이 있어서 MIPS 어셈블리어랑 구조를 볼 기회가 생겼습니다. ^^;;; 그런데… 뭐랄까요… 이게 생소한게 한 두 가지가 아니더라구요. 일단 MIPS 어셈블리어의 형태가 x86과 달라서 이해하는데 시간이 엄청 들었고… 겨우 어셈블리어로 프로그래밍을 시작했을 때 이걸 실행해 볼 수가 없어서 엄청 고민했습니다. ㅠㅠ


그런데, 이런 고민을 저만 한 게 아닌가 보더군요. ^^;;; 일반 PC 환경에서 MIPS 기기를 에뮬레이션 해주는 SPIM이라는 프로그램이 있었습니다. 다운로드는 여기에서 받을 수 있습니다. 사실 MIPS 어셈블리어 코드를 실행해보려면 컴파일러/링커와 MIPS 머신이 필요한데요, 이런 부분을 하나로 합쳐서 어셈블리어 소스 코드를 넣으면 직접 실행해줍니다. ^^


게다가 오픈 소스에 윈도우/리눅스/맥까지 지원하고 있어서 더 멋지다는~!! MIPS가 명령어도 x86 계열에 비해 단순하고, 명령어 바이트도 4바이트로 고정되어 있어서 에뮬레이터를 만들기가 좀 수월할 것 같기도 합니다. 나중에 시간이 나면 소스 코드도 한 번 훝어봐야겠네요.


ps) MIPS 어셈블리어가 궁금하다면 여기를 참고하세요 ^^

어쩌다보니 맥 장비가 생겨서 맥으로 여러가지를 해보고 있습니다. 아직 PC에 익숙해서 여러가지 시행착오를 겪으며 하나하나 배워가고 있는데요, 깜짝 놀란 부분이 몇 가지 있습니다.


이것이 새로 얻게 된 맥북 프로~!!


그중에 하나가 바로 멀티 터치인데요, 기존에 가지고 있던 맥 미니로는 경험하지 못했던 신세계가 열리더군요. @0@)-b 손가락 인식의 정확도는 물론이고 다양한 제스처를 이용해서 여러가지 작업을 할 수 있는 게 정말 멋졌습니다. ㅠㅠ 속으로 "아~ 이래서 맥을 쓰는구나" 생각했어요. ㅠㅠ


특히나 알루미늄을 깎아서 만들었다는 바디는… 뭐랄까요… 예쁘다는 느낌을 넘어서 굉장하다는 생각까지 들었습니다. 정말 처음 봤을 때는 손 대기조차 아깝더라구요. ㅠㅠ 정말 기기 하나는 폼나게 잘 만드는 듯 하네요.

안타까운 사실은… 윈도우를 버릴 수 없어서 VMware Fusion에 윈도우를 깔고 있는데, 설마… 윈도우만 주구장창 쓰는 건 아닐까 하는 걱정이 되네요. ^^;;;;


여튼 잡스님 쌩유 베리 감사~!! ㅠㅠ


ps) 키 배열이 PC와 달라서 여간 불편한 게 아니군요. ㅠㅠ 이건 적응하는데 시간이 좀 걸릴듯...

프로그래밍을 하다보면 가끔 구문 강조(Syntax Highlight) 기능이 굉장히 고마울때가 있습니다(혹시 저만 그런가요? ^^;;;) 그래서 구문 강조(Syntax Highlight) 스타일들을 보면서 나름 신경을 쓰는 편인데요, 오늘 우연히 깔끔한 스타일을 발견했습니다.

Solarized라고 하는 스타일인데요, 일단 아래 스크린샷을 한번 보시죠. ^^

스타일이 워낙 사람들마다 호불호가 갈리는 부분이라... 보기에 불편하신 분들도 있겠지만, 제가 살짝 테스트해본 결과 나름대로 괜찮았습니다. 지금 vi 설정도 이 스타일로 바꿔놨어요. ^^;;;

vi 뿐만 아니라, 비주얼 스튜디오같은 다른 에디터들도 지원하니 흥미가 있으면 한번 들어가보는 것도 괜찮을 듯 합니다.

그럼 좋은 하루 되세요 ;)

무엇을 개발하느냐에 따라서 차이가 있겠지만, 윈도우 환경의 최강 개발툴을 꼽으라면 저는 당연히 비주얼 스튜디오(Visual Studio)라고 생각합니다. 강력한 자동완성(Auto-complete) 기능과 디버깅(Debuging) 기능이 정말 환상적이거든요. ^^;;;

그런데, 최강 비주얼 스튜디오에도 단점이 한 가지있으니... 바로 실행되는데 시간이 좀 걸린다는 겁니다. @0@)-b 뭐, 간단한 소스 파일 살짝 훑어 보려는데, 비주얼 스튜디오를 실행하기에는 부담스러운 경우가 종종 있더라구요.

그래서 제가 선택한 방법은... vi와 ctags, taglist 조합을 사용하는 겁니다. vi의 강력한 검색기능과 ctags의 함수 & 구조체 분석 능력, 그리고 taglist의 바로가기 기능은 간단한 파일을 분석하기에는 충분하거든요. ^^

설치 방법

먼저 ctags를 다운로드 해야 합니다. ctags는 [http://ctags.sourceforge.net/][]에서 다운로드할 수 있고, 압축을 푼다음 ctags.exe만 vi가 설치된 폴더에 복사해줍니다. 일반적으로 vi 폴더는 Program Files\Vim\vim73과 같은 형태입니다.

ctags를 설치했다면 이제, taglist를 설치할 차례입니다. taglist는 [http://www.vim.org/scripts/script.php?script_id=273][]에서 다운로드할 수 있고, 압축을 푼 다음 doc 폴더와 plugin 폴더를 vi가 설치된 폴더에 그대로 복사하면 됩니다. vi가 설치된 폴더를 보면 같은 이름의 폴더가 있으니 그리 어렵지 않을 겁니다. ^^;;;

실행~!!

설치가 끝났으니 남은 일은 소스 코드를 vi로 열어서 결과를 확인하는 것 뿐이네요. vi를 실행하신 다음 아무 코드나 연 다음 :Tlist를 입력하시면 아래처럼 왼쪽에 함수 목록이 표시됩니다. >ㅁ<)-b



그럼 즐거운 코딩하세요 ;)


ps) 이것 참... 이게 얼마만에 여유인가 모르겠네요. ㅠㅠ)-b 아빠들 화이팅~!!

      

지난번에 VMware와 IDA를 이용해서 MBR부터 윈도우 부팅과정을 따라가는 방법에 대한 글을 올렸는데요, Ilho님께서 WinDBG를 이용해서 부팅과정을 따라가는 방법도 있다고 알려주셔서 실험해봤습니다. ^^

일단 디버거가 붙은 시점은 32비트 부트매니져가 시작되는 시점이더라구요. MBR부터 따라가지 못하는 점은 조금 아쉽지만... 강력한 장점은 윈도우 심볼을 로드할 수 있어서 따라가기 편하다는 겁니다. @0@)-b (llho님 감사드려요 ㅠㅠ)

VMware 설정

일단, 부팅과정을 따라가려면 VMware에 시리얼을 추가해야 하는데요, VMware의 왼쪽 편에 있는 "Edit vritual machine settings"를 클릭하여 뜬 "Virtual Machine Settings" 창에서 왼쪽 아래에 있는 "Add"을 누르면 됩니다. 그러면 "Add Hardware Wizard"창이 표시되는데, "Serial Port" 항목을 선택한 뒤 "Next"를 누릅니다.

이제 시리얼 포트 타입과 옵션을 설정할 차례인데요, "Serial Port Type""Output to named pipe"로 하고 "Named pipe"의 이름은 "\.\pipe\com_1", "This end is the server", "The other end is a virtual machine", "Connect at power on"로 각각 선택해주시면 됩니다(좀 항목이 많은데 아래 그림을 참고하세요 ^^;;). 그리고 시리얼 포트가 생성되면 마지막으로 "Virtual Machine Settings" 창의 오른쪽 아래에 있는 "Yield CPU on poll"을 클릭해주시면 VMware의 설정은 끝납니다.


<VMware 시리얼 포트 등록 화면 1>


<VMware 시리얼 포트 등록 화면 2>


윈도우 7 설정

다음으로... 윈도우 7에 부트 디버그 옵션을 설정해야 하는데요, cmd.exe를 관리자 권한으로 실행해서 bcdedit.exe로 옵션을 설정해줘야 합니다. cmd.exe를 실행한 다음 아래처럼 입력해주면 됩니다.

주의: bcdedit로 부트 디버그 설정을 하고 나면 재부팅 후 디버그가 붙기 전까지는 부팅 시작이 아주 늦게 시작되더군요(한 1분쯤 기다려야 부팅이 시작되었던듯...). ㅠㅠ 실제로 사용하시는 윈도우에 실험삼아 하셨다가는 큰일이 날수도 있으니 주의하시기 바랍니다. ㅠㅠ

bcdedit /bootdebug {bootmgr} on
bcdedit /bootdebug on
bcdedit /debug {bootmgr} on 
bcdedit /debug on 
bcdedit /set {bootmgr} debugtype serial
bcdedit /set {bootmgr} baudrate 115200
bcdedit /set {bootmgr} debugport 1

그리고 재부팅을 하면 부팅이 시작되지 않고 디버거가 붙기를 기다립니다. 이제 WinDBG만 설정해주면 디버깅 준비가 모두 끝납니다.

WinDBG 설정

WinDBG는 마이크로소프트에서 제공하는 디버거로 유저 모드 디버깅과 커널 모드 디버깅을 모두 지원합니다. 그리고 윈도우 자체를 디버깅할 때 심볼을 자동으로 로드해주는 강력한 기능이 있기 때문에 윈도우를 분석하는데 정말 좋은 툴이라고 생각합니다. ^^;;;

WinDBG는 마이크로소프트 사의 페이지에서 다운받을 수 있으며, 다운 받은 설치 파일을 실행하면 끝납니다. 설치가 끝나면 이제 옵션을 주어 VMware의 시리얼 포트와 연결되도록 해야 하는데요, 먼저 windbg.exe 파일을 끌어서 바로가기를 만듭니다. 그리고 속성을 클릭해서 아래 화면처럼 대상의 내용을 수정해 줍니다. -k부터 주욱 입력해주시면 됩니다. ^^;;;

C:\WinDDK\7600.16385.1\Debuggers\windbg.exe -k com:port=\\.\pipe\com_1,baud=115200,pipe,reconnect


<WinDBG 설정 화면>


자, 입력까지 끝났으면 이제 바로가기를 클릭하여 windbg를 실행합니다. 그러면 창이 뜨고 아래처럼 "Waiting to reconnect..."라는 메시지가 표시될 텐데요, VMware를 시작하면 디버거가 연결되고 윈도우가 실행됩니다. 이 상태로는 원하는 부트 디버깅을 할 수 없으니 WinDBG 창에서 Control+break를 눌러서 중단 시킵니다. 그리고 아래로 넘어가서 심볼 경로 설정과 브레이크 포인트 설정을 해줍니다.

Microsoft (R) Windows Debugger Version 6.12.0002.633 X86
Copyright (c) Microsoft Corporation. All rights reserved.

Waiting for pipe \\.\pipe\com_1
Waiting to reconnect...

WinDBG 심볼 설정 및 브레이크 포인트 설정하기

그럼 먼저 심볼을 로드할 수 있게 설정해보겠습니다. 심볼 경로는 "File" -> "Symbol File Path"를 클릭해서 지정해 줄 수 있으며, 아래처럼 입력해주면 웹에서 찾아 알아서 심볼을 다운로드 해줍니다. 굳이 윈도우 버전에 따라서 심볼을 찾느라 고생하지 않아도 된다는 거지요. ^^;;;

srv*c:\symbols.pub*http://msdl.microsoft.com/download/symbols

심볼 경로를 지정해줬으니 이번에는 bootmgr부터 디버깅을 하기 위해 WinDBG의 커맨드 창에서 아래처럼 입력해줍니다.

sxe ibp
sxe ld:bootmgr

다 입력했으면 VMware를 재시작 한 뒤에 WinDBG의 커맨드 창에서 .restart를 입력해서 재시작합니다. 그리고 잠시 기다리면 VMware와 연결되서 bootmgr부터 디버깅이 가능합니다. ^^)-b


<Bootmgr 디버깅 화면>



그럼 즐거운 디버깅(?)하세요 ;)

MBR부터 윈도우 부팅 과정 디버깅!?!

요 몆주간 윈도우 부팅 과정(MBR부터 시작하는...)을 확인할 필요가 있어서 여러가지로 찾던 중, VMware와 IDA Pro를 이용하는 방법을 발견했습니다. 물론, 이 방법 외에도 여러 방법들이 있겠지만, VMware의 빠른 속도와 IDA Pro의 강력함이 더해지니 꽤 괜찮아서 이렇게 쓰고 있습니다. ^^;;;
(혹시 다른 방법을 알고 계시면 살짝 알려주세요 >ㅁ<)/~)

VMware에 디버그 옵션 설정하기

VMware로 생성한 가상 머신이 있는 폴더에 가보면 .vmx로 끝나는 파일이 있을 겁니다. 이 파일을 노트패드와 같은 에디터로 열면 여러 설정값들이 보일텐데, 가장 아래 줄로 이동해서 다음 3줄을 추가합니다.

debugStub.listen.guest32 = "TRUE"
debugStub.hideBreakpoints = "TRUE"
monitor.debugOnStartGuest32 = "TRUE"

위 3줄은 VMware가 디버그 포트를 열어서 GDB로 OS를 디버깅할 수 있게 하는 옵션인데요, 이 옵션을 추가한 뒤 VMware를 실행시키면 바로 시작이 안되고 그냥 멈춰있습니다. ^^;;; 까만 화면이 나오거나 아래처럼 화면 가운데에 녹색 Play 버튼 같은게 나올 수 있는데, 둘다 정상이니 걱정하지 않으셔도 됩니다.


<VMware 디버깅 대기 화면>


IDA Pro로 VMware에 연결하기

VMware가 멈춰있다면 이제 IDA Pro를 실행합니다. 그리고 메뉴의 debug -> Attach -> Remote GDB debugger를 클릭하여 VMware에 붙일 준비를 합니다. "Remote GDB debugger"를 선택하면 옵션창이 표시되는데, "Hostname" 항목에는 localhost를 입력하고 "Port" 항목에는 8832를 입력하면 접속할 준비가 모두 끝납니다. ^^;;;


<Remote GDB debugger 선택 화면>



<Debug Option 설정 화면>


"Choose process to attach to"라는 창이 뜨면 그냥 ID 0번, 즉 <attach to the process started on target>으로 맞춰주세요. ^^;;;

Happy Debugging

처음에 디버거가 붙으면 BIOS의 첫부분부터 시작이 될텐데요, 사실 BIOS의 동작은 크게 안 궁금하니 브레이크 포인트를 0x7c00에 하나 걸어주고 브레이크 포인트가 걸린 뒤부터 진행하면 MBR부터 확인할 수 있습니다. ^^


 

<디버깅 화면>


이제 따라가는 일(?)만 남았군요. ^^)-b
그럼 즐거운 디버깅(?) 하세요 ^^)/~

얼마전 맥미니(Mac mini)를 중고로 구매한지라 맥에서 이것 저것 많이 해보고 있습니다. ^^;;; 윈도우를 쓰다가 맥을 쓰니 불편한 점이 한두 가지가 아닌데요, 그중에 오늘 겪은 건... RAR 파일 압축 해제입니다. OTL.... 그냥은 압축이 안풀리더군요.

그래서 찾은 것이 바로~!! UnRarX입니다.

 http://www.unrarx.com/


위의 링크에서 다운 받은 뒤 압축 풀 파일을 드래그 & 드랍 해주시면 알아서 풀어줍니다. ^^;;;
XCode 설치 시 iTunes 를 종료해야 다음으로 넘어간다는 메시지가 뜰 때가 있습니다. 이럴 때는 다음과 같이 터미널을 열어서 iTunes 관련 프로세스를 모두 종료하면 다음으로 진행됩니다.

$ ps x | grep iTunes     <== iTunes와 관련된 모든 프로세스를 표시
  127   ??  S      0:00.10 /Applications/iTunes.app/Contents/MacOS/iTunesHelper.app/Contents/MacOS/iTunesHelper -psn_0_36873
 2878 s000  S+     0:00.00 grep iTunes
$ kill 127                       <== 프로세스 죽이기 $ kill 2878

아아... 맥은... 그냥 이쁜 리눅스 같군요... OTL... 환상이 마구 깨지고 있는 중입니다. ㅠㅠ

스타트 루비(Start Ruby) #1

이 시간에는 루비 언어의 탄생 배경과 루비 언어의 특징에 대해서 간단히 알아보겠습니다. 루비 언어는 여러 언어의 장점을 취해서 만든만큼 다양한 기능들이 있지만, 사실 세컨드 랭귀지(Second Language)로 사용하는 정도라면 이번 장과 다음 장에서 설명하는 내용만으로도 충분할 것입니다. 자, 그럼 루비의 세계로 한 번 들어가 보겠습니다.

루비(Ruby)?

루비는 마츠모토 유키히로라는 일본 사람이 만들었습니다. 유키히로씨는 쉽게 쓸 수 있으면서 객체지향적인 언어를 만드는 걸 목표로 했고, 그래서 탄생한 것이 바로 루비(Ruby)입니다.

사실, 루비는 루비 온 레일즈(Ruby on Rails) 덕분에 더 널리 알려졌는데요, 레일즈 프레임워크는 스프링 프레임워크처럼 웹 개발을 편하게 해주는 프레임워크의 한 종류랍니다. 지금 보시는 이 사이트도 루비 온 레일즈로 만들어졌습니다.

루비는 다른 스크립트 언어가 갖고 있는 대부분의 기능이 포함되어 있습니다. 물론 거기에는 다양한 확장 라이브러리도 포함해서 말이지요. ;) 여러분이 필요로 하는 대부분의 기능은 이미 다른 라이브러리에 포함되어 있을 겁니다. 잘만 활용한다면 쉽고, 빠르게 개발을 진행할 수 있습니다.

이러한 특징때문에 반복되는 작업을 자동화하는 간단한 프로그램이나, 본격적인 개발 전에 프로토타입을 만들어보는 용으로 사용하면 딱입니다(물론 제 개인적인 소견이에요. ㅠㅠ).

콘솔 출력

루비에서 데이터를 출력하는 방법은 아주 간단합니다. 앞에서 본 것처럼 puts를 쓰면 대부분의 데이터를 출력할 수 있습니다. 단, 원하는 형태로 데이터를 출력하고 싶다면 조금 고민을 해야하지만, C 언어를 조금 안다면 그리 어렵지 않습니다. C 언어의 printf와 비슷한 기능을 하는 sprintf()가 있기 때문이죠. C처럼 생긴 sprintf()가 싫다면 "문자열 포맷" %[] 형식의 루비 스타일도 있으니 입맛대로 사용하면 됩니다. ^^;;;;

a = sprintf("제 이름은 %s이고 나이는 %d 입니다.", "루비", 1)
b = "제 이름은 %s이고 나이는 %d 입니다." %["루비", 1]
c = sprintf("PI는 .2f 입니다.", 3.1425);

puts a
puts b
puts c

콘솔 입력

루비에서 콘솔 입력은 한 줄 또는 여러 줄을 입력받을 수 있습니다. 한 줄 입력은 gets() or readline() 함수를 사용하면 되고, 여러 줄 입력은 readlines() 함수를 사용하면 됩니다.

a = gets()              # 엔터가 입력될 때까지 저장
b = readline()          # 위와 같은 결과
c = readlines()         # 여러 줄을 읽을 때 사용

루비 데이터 타입

루비에는 크게 7가지 기본 타입이 있는데요, 숫자와 문자열, 배열(Array)과 해시(Hash), 범위(Range)와 심볼(Symbol), 그리고 정규표현식(Regular Expression)이 그겁니다.

숫자와 문자열, 배열은 기존에 다른 언어와 큰 차이가 없기 때문에 간단히 살펴보고 넘어가겠습니다. 그렇다고 나머지가 엄청 복잡한 건 아니니 너무 걱정안하셔도 됩니다(사실 정규표현식은 좀 낯설긴 해요. ^^;;;;).

숫자, 문자열

아래는 루비에서 숫자와 문자열을 나타낸 예입니다.

a = 5                         # 정수 5
b = 10.1                      # 실수 10.1
c = "이것은 문자열입니다."    # 문자열

puts a, b, c                  # a,b,c 변수의 값을 차례로 출력

결과:
5
10.1
이것은 문자열입니다.

위의 a, b, c를 변수라고 하며, 변수는 값을 저장하는 일종의 공간입니다. 루비의 변수는 타입이 정해져있지 않고 우변에 대입하는 값에 따라서 변합니다. C나 C++ 언어처럼 선언할 때 변수의 타입을 지정해주는 것과는 다른 방식이지요.

puts는 파라미터로 넘어온 값을 출력하는 함수로, 숫자 타입부터 배열이나 해시까지 아주 편하게 출력할 수 있습니다. 앞으로 자주 사용할 것이니 puts() 함수를 눈여겨봐두기 바랍니다.

배열, 해시, 범위

배열과 해시 역시 아주 직관적입니다. 아래는 배열과 해시의 예를 나타낸 겁니다.

a = [0, 1, 2, 3, 4, 5]        # 0 에서 5까지 정수가 들어있는 1차원 배열
# 사과와 바나나를 키로 사용하고, 그 값으로 빨강, 노랑을 연결한 해시
b = {"사과" => "빨강", "바나나" => "노랑"}

puts a, a.length, b["사과"], c["바나나"]

결과:
0
1
2
3
4
5
6
빨강
노랑

배열은 다른 언어와 마찬가지로 []로 감싸고 그 안에 배열의 요소를 ,로 구분하여 넣으면 됩니다. 잠시 후에 설명하겠지만 루비의 모든 타입은 클래스이기 때문에, 기본적으로 몇가지 함수나 속성을 가지고 있습니다. 위에서 나온 length도 그중에 한 가지며, 배열의 길이를 나타내는 속성입니다.

해시는 키(Key)와 값(Value)로 이루어진 테이블이며, 다른 말로는 맵(Map)이라고도 합니다. 해시는 배열과 달리 키를 사용하여 데이터를 읽고 쓸 수 있으므로, 연속적이지 않은 데이터를 다루는데 유용합니다. 해시에서 키와 값은 => 로 연결하며, 항목이 여러 개일 경우 ,로 구분합니다.

다음 범위와 정규표현식으로 넘어가기 전에 간단히 2차원 배열을 생성하는 방법을 살펴보겠습니다. 2차원 배열은 1차원 배열을 내부에 가지고 있는 배열입니다. 따라서 아래처럼 2차원 배열에 담을 배열을 먼저 생성한 뒤에, 다른 1차원 배열을 생성해서 그 안에 두면 됩니다.

a = [0, 1]          # 1차원 배열
b = [2, 3]          # 1차원 배열
c = [a, b]          # 2차원 배열

puts c
puts c[0][0]
puts c[0][1]
puts c[1][0]
puts c[1][1]

결과:
[[0, 1], [2, 3]]
0
1
2
3

위의 코드는 2차원 배열을 만들고 각 요소에 접근하는 방법을 나타낸 겁니다. 2차원 배열이 "1차원 배열을 요소로 갖고 있는 1차원 배열"이란 것을 생각해보면, 쉽게 예측할 수 있는 코드입니다. ^^)-b

범위는 숫자와 .. 또는 ...으로 이루어진 조합으로, 시작과 끝에 포함되는 모든 정수를 뜻합니다. 즉 1..10은 1부터 10까지 모든 정수(1,2,3...10)을 뜻한다는 것이죠. .....의 차이는 ..는 끝 숫자를 범위에 포함하지만, ...는 끝 숫자를 범위에 포함하지 않는 것입니다. 아래는 그 사용법과 결과를 나타낸 겁니다.

a = 0..10          # 0부터 10까지 범위의 정수
b = 0...10         # 0부터 9까지 범위의 정수

puts a
puts b

결과:
0..10
0...10

위의 결과를 보면 살짝 당황스러울 겁니다. 0부터 10까지의 숫자가 출력되기를 바랬는데, 우리가 만든 범위를 그대로 출력해주니 말입니다. 여기에 살짝 for 문을 추가하여 실제로 범위에 들어가는 값을 출력해보겠습니다.

a = 0..10
b = 0...10

puts "0..10"
for i in a
    puts i
end

puts "0...10"
for i in b
    puts i
end

결과:
0..10
0
1
2
3
4
5
6
7
8
9
10
0...10
0
1
2
3
4
5
6
7
8
9

정규표현식(Regular Expression)과 문자열 다루기

루비의 정규표현식은 /로 구분합니다. 즉 /Ruby/처럼 사용하면 Ruby와 일치하는 문자열을 나타내는 정규표현식이 됩니다. 정규 표현식 뒤에는 페턴을 어떻게 일치시킬지를 나타내는 옵션이 들어가고 옵션의 의미는 다음과 같습니다.

* /Ruby/i : 대소문자 구분 안함
* /Ruby/m : 줄바꿈 문자도 일반 문자처럼 다룰 때 사용
* /Ruby/x : 공백문자와 주석을 허용(RE 확장 문법)

정규표현식에서 (), [], {}, ., ?, +, *, |, ^, $는 각자 의미가 있습니다. 각 기호의 의미는 말로 설명하는 것보다 직접 사용법을 보는 것이 더 이해가 쉽습니다. 다음은 각 기호의 사용법입니다.

/(R|r)uby/          # Ruby 또는 ruby와 일치
/[Rr]uby/           # Ruby 또는 ruby와 일치
/[0-9]/             # 모든 숫자 한자리와 일치
/[0-9]+/            # 모든 숫자 한자리 이상과 일치
/Ruby!*/            # Ruby 또는 Ruby 뒤에 !가 1개 이상 붙은 문자열과 일치
/Ruby!?/            # Ruby 또는 Ruby!와 일치
/Ruby{3}/           # Ruby가 3번 반복되는 문자열과 일치
/Ruby{1,3}/         # Ruby가 최소 1번부터 최대 3번까지 반복되는 문자열과 일치
/[^0-9]/            # 숫자를 제외한 문자열과 일치
/ruby$/             # ruby로 끝나는 문자열과 일치

기호로 인해 더 쉽게 정규표현식을 만들 수 있게 된 건 좋은데, 이런 기호를 실제로 쓰고 싶으면 어떻게 할까요? 방법은 간단합니다. 앞에서 나온 기호들을 실제 패턴 일치에 사용하고 싶으면 \를 앞에 붙여주면됩니다. 아래처럼 말이죠 ;)

/Ruby\?/            # Ruby?와 일치
/Ruby\+/            # Ruby+와 일치

+, *와 같은 반복 기호 뒤에는 ? 기호를 사용할 수 있는데, 이는 패턴을 일치시킬 때 범위를 어디까지로 한정하는가에 사용됩니다. 아래와 같이 Ruby> 가 있을 때 ?가 있을 때와 없을 때의 차이는 다음과 같습니다.

a = "<ruby>Ruby>"

결과:
a =~ /<.*>/
$~
=> #<MatchData "<ruby>Ruby>">

a =~ /<.*?>/
$~
=> #<MatchData "<ruby>">

위에서 $~로 나타낸 것은 정규표현식에서 일치한 부분을 나타내는 전역 변수입니다. 객체지향으로 보면 Regexp.last_match와 같습니다. 사실 Regexp.last_match는 $~의 값을 그대로 반환합니다.

정규표현식에는 문자와 숫자를 의미하거나 공백 또는 모든 문자를 의미하는 표현식이 있습니다. 위의 .이 바로 그것인데요, 다음은 해당 표현식을 나타낸 것입니다.

* /./ : 줄바꿈을 제외한 모든 문자와 일치
* /./m : 줄바꿈을 포함한 모든 문자와 일치
* /\d/ : 숫자와 일치
* /\D/ : 숫제를 제외한 모든 문자와 일치
* /\s/ : 공백 문자와 일치 \t, \r, \n, \f
* /\S/ : 공백을 제외한 문자와 일치
* /\w/ : 단어 하나와 일치
* /\W/ : 단어가 아닌 문자에 일치

사실, 문자열의 경우 배열의 인덱스에 정규표현식을 넣어서 일치하는 부분만 잘라낼 수 있습니다. 아래처럼 말이죠. slice() 함수를 사용해도 같은 결과를 얻을 수 있고, slice!()를 사용하면 원하는 결과만 문자열에서 꺼내고 기존 문자열은 나머지만 남길수도 있습니다.

a = "<ruby>Ruby>"

a[/<.*>/]
a[/<.*?>/]
a.slice(/<.*>/)
a.slice!(/<.*?>/)
puts a

결과:

<ruby>Ruby>         #a[/<.*>/]
<ruby>              #a[/<.*?>/]
<ruby>Ruby>         # a.slice(/<.*>/)의 결과

<ruby>              # a.slice!(/<.*?>/)의 결과
Ruby>               # puts a의 결과

그리고, 패턴을 비교하는데 =~만 쓰란 법도 없습니다. 문자열이라면 .match()를 사용해서 MatchData 객체를 반환하게 만들수도 있습니다. =~는 일치하는 인덱스를 반환하거나 nil을 반환하는 반면 .match()MatchData를 반환하거나 nil을 반환하는 것이 다릅니다.

명령어 실행

루비는 언어 내에서 `로 명령어를 실행하는 것을 지원합니다. 예를들어 `ls`를 하면 ls가 실행되어 그 결과가 문자열로 반환이됩니다. 다음은 ls 명령어를 실행하여 현재 디렉터리의 목록을 받아와 출력하는 예제입니다.

a = `ls`
puts a

결과:
posts.html
posts_files
start-ruby-1.md
test.css
test.html
test_files
vim-markdown-preview-설정.md

마무리...

이상으로 루비 언어의 특징에 대해서 간단하게 알아봤습니다. 다음 시간에는 루비 언어를 이용해서 귀찮은 작업을 한방에 처리할 수 있는 방법을 알아보겠습니다.

 

마크다운(Markdown)?

얼마 전에 마크다운(Markdown)이란 것을 새로 접했습니다. 위키처럼 텍스트 기반으로 편하게 문서를 작성할 수 있고, 문법 자체도 아주 직관적이어서 배우기 쉽더군요. 물론, 여기서 직관적이라는 건... 사람에 따라 조금 다르게 느낄 수도 있는 부분이지만, 위키를 한번 접해보신 분이라면 "아하~!!"라고 하실 겁니다.

그래서 루비 온 레일즈(Ruby on Rails)의 튜토리얼을 보고 간단하게 만든 사이트에 마크다운 파서인 레드카펫(Redcarpet)을 설치해서 마크다운 블로그를 만들었습니다.

사실 마크다운 형식으로 쓴 글을 파싱해서 보여주는 것이 전부라 블로그라고 하기도 좀 그렇지만... 일단 대략 완성되었으니 한번 공개해봅니다. ^^;;;; kkamagui의 마크다운 블로그로 바로가기~!! 간단 마크다운 문법 정리로 가면 마크다운 문법이 어떤 것이고 어떻게 보이는지를 간단히 확인할 수 있으니 궁금하시면 한번 들러보시기 바랍니다. ^^;;;

새로 만든 블로그에 글을 적다보니 약간 불편한 점이 있더군요. 글 쓰는 것 자체는 편해졌는데, 단지 웹에서 작업을 해야 한다는 것이 좀 불편했습니다. 만일 로컬에서도 작업할 수 있다면, VI 에디터에서 글을 쓰고 바로바로 확인하는 방법으로 더 편하게 작업할 수 있을 테니까요. ^^;;;

그래서 찾아보던중... 아웃사이더님의 블로그에서 VIM Plugin을 발견했습니다. VIM에서 작업하다가 Command Line에 :Mm만치면 웹 브라우저에서 바로 확인할 수 있는 멋진 녀석이더군요. ;)

VIM Markdown Preview 설치 방법

설치방법 또한 아주 간단했습니다. vim-markdown-preview사이트로 이동해서 파일을 다운로드한 뒤, plugin 폴더와 doc 폴더의 모든 파일을 홈 디렉터리 아래에 있는 .vim 디렉터리 아래에 넣어두면 됩니다. ^^;;; 직접 복사하는 것이 귀찮다면 아래처럼 install.sh를 직접 실행하셔도 됩니다. 단, 홈 디렉터리 아래에 .vim/plugin 폴더가 이미 생성되어 있어야 합니다.

$> install.sh

실행 방법

설치가 모두 끝났다면 vim으로 파일을 하나 열어서 아래처럼 텍스트를 그대로 입력한 다음 Command Line에 :Mm을 입력해보세요. 기본 CSS가 Github Style로 되어 있어서, Github처럼 예쁘게 포매팅된 문서를 보실 수 있을 겁니다. ^^

#1.안녕하세요 H1 입니다.
## 1.1 H2에요

이것은 일반 텍스트입니다. 마크다운으로 아주 편하게 문서를 작성할 수 있어요. ;)

* 리스트1
* 리스트2
* 리스트3

이제 코드를 한번 보겠습니다.

    이 부분은 코드로 표시될 부분입니다. 탭을 1번 입력하거나 스페이스바를 4번 입력하면 코드 블럭을 사용할 수 있습니다. 

> 이것은 인용 블럭입니다. 정말 쉽죠? ^^;;;

[kkamagui blog](http://kkamagui.tistory.com)는 링크를 거는 간단한 방법입니다. 이것 외에도 많은 방법이 있어요 ;) 더 많은 내용은 [마크다운 문법](http://blog-kkamagui.cloudfoundry.com/posts/1)을 참고하세요.

결과:


1.안녕하세요 H1 입니다.

1.1 H2에요

이것은 일반 텍스트입니다. 마크다운으로 아주 편하게 문서를 작성할 수 있어요. ;)

  • 리스트1
  • 리스트2
  • 리스트3

이제 코드를 한번 보겠습니다.

이 부분은 코드로 표시될 부분입니다. 탭을 1번 입력하거나 스페이스바를 4번 입력하면 코드 블럭을 사용할 수 있습니다. 

이것은 인용 블럭입니다. 정말 쉽죠? ^^;;;

kkamagui blog는 링크를 거는 간단한 방법입니다. 이것 외에도 많은 방법이 있어요 ;) 더 많은 내용은 마크다운 문법을 참고하세요.


CSS 바꾸는 방법

Github Style도 충분히 만족스럽지만 각자의 취향 차이가 있으니 자신이 원하는 CSS로 바꾸는 방법도 살짝 알아보겠습니다. 홈 디렉터리에 있는 .vim/plugin 폴더 아래의 preview 관련 폴더로 이동해보면 아래와 같은 파일이 보일 겁니다.

kkamagui@ubuntu:~/.vim/plugin/vim-markdown-preview/stylesheets$ ls
github.css  safari-reader.css  simple-print.css

여기서 github.css를 자신의 입맛대로 바꾸거나, 아니면 여기에 css 파일을 복사하고, plugin 폴더 아래에 있는 vmp.vim 파일을 수정해도 됩니다. 파일을 열어서 23번 라인 근처를 보시면 stylesheet를 지정하는 부분이 보이는데요, 요 부분을 수정해줍니다. 저는 application.css 파일을 사용하고 있어서 요걸 지정해줬습니다.

 22 if !exists('g:VMPstylesheet')
 23     let g:VMPstylesheet = 'application.css'
 24 endif

자, 다 변경했으면 이제 다시 Command Line에서 :Mm을 입력해보겠습니다. 그러면, 새로운 페이지가 열리면서 지정한 CSS가 적용된 화면을 볼 수 있을 겁니다. ^^;;;

마크다운 덕에 재미있는 일을 많이 해보는군요. ;) 텍스트로 만들어진 문서를 작성하는 데는 마크다운도 괜찮은 선택인 것 같습니다. 그림이 들어가야 한다면... 그림을 어디 올려서 링크를 걸어야 하는 점이 약간 불편하긴 한데요, 그래도 링크만 있다면 그림을 넣는 건 편리하기 때문에 어떻게든 될 것 같네요.

HTML 태그 중에 pre 태그는 그 내부에 있는 글을 있는 그대로 보여주는 특징이 있습니다. 그래서 Code를 보여줄 때 pre 태그를 사용해서 쓰고 있는데요, 이게 한 라인이 길어지면 스크롤바를 만들어서 보여주더라구요. ^^;;;;

사실 스크롤바를 보여줘도 상관은 없는데, 매번 스크롤해서 보려니 귀찮기도 하고... 그냥 다른 태그들처럼 다음 라인으로 개행을 해서 보여줘도 되는 것 같기도해서 방법을 찾아봤습니다.

역시나 구글신이 친절히 알려주셨는데, 아래처럼 css의 pre 태그 항목에 white-space: pre-wrap; 속성을 사용하면 됩니다. 좀더 자세한 내용은 http://stackoverflow.com/questions/248011/how-do-i-wrap-text-in-a-pre-tag 을 참고하시면 됩니다.

pre{
    background-color: #E6E6FA;
    padding:10px;
    overflow: auto;
    white-space: pre-wrap; /* pre tag내에 word wrap */
}  


아우... 이거 원 모르는게 많아서 진도가 나가질 않네요. ㅠㅠ 웹세상은 제가 아는 세상과 또 다른 세계인 것 같아요. ㅠㅠ

난데없이 요상한 곳(?)에 불이 붙어서 요즘 루비 온 레일즈(Ruby On Rails)로 간단한 웹페이지를 만들어 보고 있습니다. ^^;;; 그래봤자 루비 온 레일즈 사이트에 있는 예제를 보고 끄적거리는 수준입니다만, 제 손으로 만든 게 돌아가는 걸 보니 정말 신기하네요. 웹은 돌아가는 것이 눈에 바로 바로 보여서 정말 짱인 것 같습니다. ㅎㅎ

그런데 만든 웹페이지를 스마트폰으로 들어가보니... 글자가 점처럼 보일 정도로 광활하게 나오더군요. 이런... ㅠㅠ 그래서 어떻게 하면 스마트폰에서도 잘 보일까 싶어서 구글 검색을 하던 도중 메타 태그(Meta Tag)를 사용하면 된다는 것을 알았습니다. :) 아래처럼 말이죠.

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=3.0, minimum-scale=0.5, user-scalable=yes" />


위의 각 항목은 아래와 같은 의미를 가지고 있습니다.

- width=device-width : 플랫폼 가로 크기에 맞춤, 수치를 넣으면 그수치에 맞게 맞춰짐(ex, 300px)
- initial-scale=1.0 : 페이지 로딩시 확대비율
- maximum-scale=3.0 : 최대확대비율
- minimum-scale=0.5 : 최소축소비율
- user-scalable=yes : 사용자의 확대보기 허용 여부(no/yes)


위의 태그를 넣어주고 모바일 보기 모드일 때 가로 폭을 좀 줄여줬더니 스마트폰에서도 나름대로 볼만한 크기로 잘 나오는군요. ㅎㅎ
그럼 좋은 하루 되세요 ;)

ps)  참고 사이트
루비 온 레일즈에서 html 파싱에 사용하는 Nokogiri를 설치할 때 아래처럼 libxslt 관련 오류가 발생하면 libxslt를 설치해주면 됩니다.

Installing nokogiri (1.5.0) with native extensions
Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension.

        /usr/bin/ruby1.8 extconf.rb
checking for libxml/parser.h... yes
checking for libxslt/xslt.h... no
-----
libxslt is missing.  please visit http://nokogiri.org/tutorials/installing_nokogiri.html for help with installing dependencies.
-----
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of
necessary libraries and/or headers.  Check the mkmf.log file for more
details.  You may need configuration options.

Provided configuration options:
    --with-opt-dir
    --without-opt-dir
    --with-opt-include
    --without-opt-include=${opt-dir}/include
    --with-opt-lib
    --without-opt-lib=${opt-dir}/lib
    --with-make-prog
    --without-make-prog
    --srcdir=.


설치 방법은 다음과 같습니다.
sudo apt-get install libxslt-dev libxml2-dev

아아... 고난과 역경의 연속이군요. OTL....

+ Recent posts