2008년 7월 31일 목요일

haskell 로 웹페이지 한번 긁어봤다. 그리고 Maybe, Either, mapM 을 배웠다.

-- Network.HTTP 로 구글을 읽어오는 걸 짜봤다.
-- 그런데 302 moved 를 안따라가네.. 불친절하군.
-- response 받아서 2xx 나올때까지 재귀돌려야 하나?
-- 아니면 Network.HTTP 는 로우레벨이고 좀더 하이레벨 함수들이 있을까?
--
-- 어쨌건 이번에 배운건 Maybe 라는 놈이랑 Either 라는 놈
--
-- Maybe a 는 Just a 나 Nothing 이 될수있는데 패턴매칭으로 어떤 경우인지
-- 가려내서 에러처리를 해야 겠지만 샘플이니 그냥 fromJust 을 써먹었다.
--
-- Either a b 는 Left a 나 Right b 로 떨어지는놈.
-- 역시 마찬가지로 패턴매칭으로 적당히 처리를 해야 곘지만 불편하니 fromRight 이란걸 만들어봤다.
--
-- 역시 IO (IO 와 모나드의 정확한 관계는 모르겠다. 모나드중의 IO 인것은
-- 맞는데 모든 모나드가 IO 처럼 시퀀셜한 액션을 나타내는것은 아닌것
-- 같기도 하고.. 단순히 사이드이펙트를 가질수있는 모든것들이 모나드인가??
-- 이부분은 좀더 공부하면 알게되겠지)..
--
-- ..IO 위주의 코딩이 되니 편안하네. 문법만 조금 달라졌을뿐 돌아가는
-- 모양새는 C 와 다를게 없으니. 그런데 아무리 생각해도 내가 만들
-- 대부분의 프로그램들은 이런식의 절차적인 특성을 지닐텐데.. 아님 내
-- 생각이 절차적인 한계를 벗어나지 못하는 건가.
--
--
-- 이 모나드라는게 정말 끝까지 따라다닐거 같은데..
-- lisp 이라면 mapcar 류함수와 와 IO 함수를 쉽게 섞을수 있는데
-- (mapc #'print '(1 2 3 4))
--
-- haskell 의 map 은 IO 함수를 받지를 않네.
-- map putStr ["fucking", "hard"]
--
-- 뭐 저런걸 돌리는 다른 함수가 있긴 하겠지.
--
-- 음. 검색을 좀 해보니 mapM 이란게 있네. M 은 모나드의 M 이겠지.
-- 내 원래 이걸 직접 만들어볼려고 했는데 아직 모나드는 커녕 타입조차도 몰라서 실패했다.
-- 내가 만들어보려고 한 함수는
-- (a -> IO b) -> [a] -> IO [b]
-- 뭐 이런식으로 해볼라고 했는데 이게 터무니 없는 것이었나보다.
-- mapM 의 타입은
-- Monad a => (b -> a c) -> [b] -> a [c]
-- 이렇네..
--
-- Monad a=> 라면 a 가 Monad 클래스에 속한다는걸 나타내던가.. 좀더 읽고 짜봐야겠다.

import Network.HTTP
import Network.URI
import Data.Maybe(fromJust)

fromRight :: (Either a b) -> b
fromRight e = case e of
Right r -> r
Left l -> error "not right"

main =
let req = Request (fromJust $ parseURI "http://www.google.com") GET [] ""
in do
rep <- simpleHTTP req
putStrLn $ show $ fromRight rep
return ()

2008년 7월 30일 수요일

헤스켈 셀렉션 소트 구현.. 헐.

haskell 잠깐 구경하는 중인데 이걸로 selection sort 를 짜보려다 좌절을 먹고 소감이나 적어둔다.

for i ← 0 to n-2 do
    min ← i
    for j ← (i + 1) to n-1 do
        if A[j] < A[min]
            min ← j
    swap A[i] and A[min]

처음엔 selection sort 의 정의 그대로 2중 루프 돌면서 작은 값 찾아서 자리바꾸는 식으로 구현을 해보려고 했는데 이렇게 접근하니 아주 제한적인 부분만 알고있는 내 haskell 능력으로는 구현이 불가능하더라.

루프야 대강 재귀돌리면 되는데 문제는 swap.. haskell 의 리스트가 싱글링크드리스트 인것 같은데 이걸 어떻게 효율적으로 스왑을 하나.. 처음엔 당연히 스왑함수가 지원될줄 알았는데 안보이네.. 그리고 이걸 짜보려고 해도 이놈의 리스트가 불변값이라 어쩔수 없이 여러번의 복사? 가 일어날듯 해보였다.

물론 리스트를 조각내서 짜깁기 하는식으로 짜면야 간단하긴 한데... 아무래도 남들은 이런식으로 쓰지 않을거란 생각이 들었다.

그래서 대강 찾아보니 IO array 라던지 ST array 라던지 하는 수정가능한 자료구조가 있다는건 알게됐는데 문제는 이놈들이 모나드... 아직 모나드 공부는 안했지만 모나드와 다른 함수들이 자연스럽게 섞이지 않는 문제점을 겪었기에 ( 아직 공부중이라 잘 몰라서 그럴수도 있지. 하지만 모나드 라는게 사이드 이펙트를 막고자 나온거라면 모나드 함수가 비 모나드 함수안에서 투명하게 불리는것은 불가능하겠지? )..

... 모나드에 겁을 먹고 바로 구글링을 해봤다.

결국 http://www.cs.bris.ac.uk/Teaching/Resources/COMS12100/2003-4/lectures/notes.html 에서 셀렉션 소트 구현을 찾았는데

mport List

selectSort :: Ord a => [a] -> [a]
selectSort [] = []
selectSort ns =
m : selectSort (remove m ns)
where m = minimum ns

insertSort :: Ord a => [a] -> [a]
insertSort [] = []
insertSort (n:ns) =
insert n (insertSort ns)

이렇더라.. 음..
헐... 놀랍다.
함수형 언어와 절차형 언어의 접근이 다르다는걸 머리론 알고 있었지만 그걸 느끼긴 처음이네.
그리고 이미 몇년간 C/C++ 식 코딩을 해온 나한테 저런건 머리를 쥐어짜도 안나올거란걸 느꼈다.

좀더 공부를 해볼까? 그냥 접을까?


PS 그런데 저 잘난 구현도 리스트의 사본을 계속해서 만드는데 기분이 편치 않네.
성능 생각하면 모나드쪽의 어래이를 써야 할것 같은데 정말 헤스켈로 프로젝트 뛰는
애들이 어떤식으로 코딩하는지 궁금하네.


2008년 7월 22일 화요일

엘더스크롤3 모로윈드 945GC 내장브가로 플레이 시도

E2140 노오버
램 2G
GMA950

모드는 베터바디, 베터페이스? 등등 몇개만.
초반만 보면 1024*768 에서 10~30 fps 나오는데 액션이 아니니 할만하군
똥컴으로 단련된 인내심이라 20프레임만 나와도 기분좋다.

내장브가 사면서 게임은 포기했는데 내가 하는겜들은 죄다 고전 RPG 류라 별 불편함이 없네.. 컴업하기 전 PC 가 워낙 구려서 내장이라지만 성능이 더 좋고.

그래도 폴아웃3 나오면 브가하나 사줘야겠지....
돈생기면...

win32 fibers

http://blogs.msdn.com/larryosterman/archive/2005/01/05/347314.aspx

정리 졸라 잘됐다.



gobject 그냥 구경만 해봤다.

gstreamer 를 써야 할일이 있어서 최소한의 것만 읽어봤다.
  • 타입정보를 모두 들고 있는 놈. 객체의 생성,복사,파괴 등이 모두 이 타입시스템을 통해서 하는식.
  • 새 타입을 등록하려면 class structure 와 instance structure 가 필요한데
  • instance structure 는 각 인스턴스마다 고유한 값을 가질 값들.. 즉 그냥 멤버변수라고 보면 되고
  • class structure 는 같은 클래스라면 공유하는 값들..  vtable 이나 클래스 스코프 변수등등이 되겠지.
  • 어떤 타입을 만들어 달라고 타입시스템에 요청을 하면 타입시스템이 그 타입에 해당하는 class structure 인스턴스를 관리 하고 그 타입의 instance structure 의 값을 하나 만들어서 사용자한테 준다.


  • 쓰기가 더러운데 한 타입을 관리하는데 두개의 구조체가 쓰인다는걸 알면 남은것은 더러운 포인터질.
  • gstreamer 에서 제공되는 템플릿 코드를 읽기위해서 최소한의 것만 읽어봤다. 틀린내용이 있을지도 몰겠군.


2008년 7월 16일 수요일

구글 사이츠 자기 도메인 연결 기능 추가

추가됐다고 발표된지는 좀 됐는데 모든 사용자한테 동시에 이 기능이 뜨지는 않고 천천히 뜬듯. 아니면 구글이 공갈을 쳤거나. 어쨌거나 그런 기능 추가됐다는거 확인하고 매일 내 좃스팟 확인을 해왔는데 오늘 보니 나도 메뉴가 떴더라.

바로 www.yoonkn.comhttp://sites.google.com/a/yoonkn.com/wiki 에 매핑을 했는데 실패! 절라.. www 가 이미 매핑이 됐다고 에러가 뜨더라. 알고보니 내가 이전에 www.yoonkn.com 을 구글 페이지 로 링크를 해뒀었네. 근데 이걸 바꿔도 www 가 매핑이 됐다고 뜨고.. 어떻게 손보기가 힘들더라.

좀 고민하다가 어차피 안쓰는 기능이니 구글페이지를 내려버리고 그외 구글챗 구글캘린더 등 내가 구글앱에서 쓰지 않는 기능들을 덩달아 내려버렸다. 대강 정리후 다시 www 매핑을 시도해보니 성공

이제 www.yoonkn.com  으로 내 위키에 접근이 가능해졌고, 위키안의 페이지들도 www.yoonkn.com/페이지이름/페이지이름 식으로 이쁘게 나온다.

아.. 맘에 드네.

2008년 7월 10일 목요일

2008년 7월 8일 화요일

보고있는 웹사이트 마음대로 수정하기 ( 자바스크립트 )


주소창에 아래 스크립트 집어넣으면 브라우저 상에서 수정가능
javascript:document.body.contentEditable='true'; document.designMode='on'; void 0


언급된대로 구라샷 만드는데 써먹을수 있겠군. 잇힝
아래는 위 스크립트 개정판. 토글이 가능하다. 수정후엔 수정모드를 풀어줘야 하니 이걸 써먹자.

javascript:if(document.body.contentEditable == 'false' || document.body.contentEditable == 'inherit')document.body.contentEditable = 'true';else document.body.contentEditable = 'false';void 0

2008년 7월 7일 월요일

cmake 2.4-patch 7 하고 ccache 사용시 cmake 가 컴파일러를 파악하지 못하는 문제

release 빌드를 했는데 최적화 옵션이 빠진것을 보고 make edit-cache 에서 t 로 모든 옵션 켜고 읽어보니 cmake 가 세팅해줘야 할 옵션들이 죄다 빠져있었다. 좀 생각해보니 ccache 가 문제인것 같은데 역시나 CC="ccache gcc" CXX="ccache g++" 로 환경변수 잡았던거 빼고 돌려보니 cmake 가 정상적으로 플래그들 세팅해주더라.

혹시나 또다시 삽질하는 경우를 피하기위해 적어둔다.
좀더 뒤지면 해결책도 나올것 같은데 그건 나중에.


아래는 FLAGS 들이 비어있는 상태. cmake 가 CMAKE_COMPILER_ARGS1 이란놈으로 뭔가 할것 같은데.. 결과는 그렇지 못했다.
비어있는 Debug, Release flag 들


아래는 정상일때. 컴파일러가 제대로 인식이 됐고 cflags 들이 적절히 세팅되었다.
정상적으로 컴파일러 잡은것





cmake 로 pkg-config 사용하기 ( CFLAGS, LDFLAGS 설정하기 )

이전위키에 적은글

씨바 cmake 깝깝하네.
걍 CFLAGS, LDFLAGS 만 세팅하는게 뭐이리 중구난방인지
급히 여기 적어두고 나중에 몰아서 새위키에 정리하자.


# cmake 에 딸려오는 UsePkgConfig 를 쓰기로 했다.
# EXECUTE_PROCESS 를 써볼려고 헀는데 영 지저분해지길래 이놈을 쓴다.
INCLUDE(UsePkgConfig)
# UsePkgConfig.cmake 에 나온 예제 그대로
PKGCONFIG(gstreamer-0.10 GSTREAMER_INCLUDEDIR GSTREAMER_LIBDIR GSTREAMER_LDFLAGS GSTREAMER_CFLAGS)
# 인클루드 디렉토리 추가
INCLUDE_DIRECTORIES(${GSTREAMER_INCLUDEDIR})
# 링크 디렉토리 추가
LINK_DIRECTORIES(${GSTREAMER_LIBDIR})
# cflags 추가. cflag 에 -d 나 /D 만 있는게 아닌데 이딴 이름을 쓰는건 좀
# 아니라고 보는데.. 이 방법 말고 cmake 가 세팅하는 모든 CFLAGS,
# CXXFLAGS 를 수정하는 수단을 못찾겠다.
ADD_DEFINITIONS(${GSTREAMER_CFLAGS})


# 바이너리 하나 추가.
ADD_EXECUTABLE(a a.c)
# 그 바이너리에 LDFLAGS 적용. 이것도 절라 쓰레기 같은데.. 그냥
# 글로벌하게 LDFLAGS 를 수정하고 싶은데 깔끔한 방법이
# 안보인다. CMAKE_MODULE_LINKER_FLAGS 를 바꾸면 된다는데 SET 으로 저걸
# 바꾸는게 그다지 깔끔해 보이진 않는다.
SET_TARGET_PROPERTIES(a PROPERTIES LINK_FLAGS ${GSTREAMER_LDFLAGS})


티스토리에 있던 글 가져와봤는데

역으로도 되는지 모르겠다.
기존 글이랑 머징이 안되고 날려버린다는게 좀 거시기하군.





2008년 7월 2일 수요일

emacs + gdb 편하게 디버깅하기

이전에 적었던 글
http://oldpie.yoonkn.com/cgi-bin/moin.cgi/DebuggingWithEmacs
http://oldpie.yoonkn.com/cgi-bin/moin.cgi/using_GDB
새 위키에 적기전에 잠시 정리. emacs 와 gdb 로 디버깅하기 란 페이지에 정리할 생각.

emacs 에서 gdb 를 visual studio 와 유사한 키바인딩으로 사용하기

(global-set-key [f9] 'gud-break)        ; 소스창에서 바로 브레이크포인트 설정
(global-set-key [f10] 'gud-next) ; 현재 라인 실행하고 다음 라인으로
(global-set-key [f11] 'gud-step) ; 현재 함수안으로 따라 들어간다
(global-set-key [(shift f11)] 'gud-finish) ; 현재 실행중인 함수 리턴후 멈춤
(global-set-key [(shift f10)] '(lambda () ; 현재 커서까지 실행하고 멈춤
(interactive)
(call-interactively 'gud-tbreak)
(call-interactively 'gud-cont)))

흠 recenter-top-bottom 을 매번 불러서 커서를 화면 중앙으로 유지하는 것도 편할거 같은데 아직 시도는 안해봤다. 지금도 그렇게 불편하진 않다..


아래 스샷처럼 여러 윈도 같이 띄우기
사용자 삽입 이미지

(setq gdb-many-windows t)

내가 원하는 윈도를 따로 프레임으로 띄우기
내 모니터가 작아서 저렇게 놓고 디버깅하긴 좀 불편하다. 자주 쓰는 gdb 콘솔윈도우는 따로 프레임으로 뽑아내서 아래 그림처럼 alt-tab 으로 전환해가면서 사용하는게 더 편하다.
사용자 삽입 이미지

조렇게 쓰려면 위쪽 gdb 창에가서 C-x 5 2 를 누르거나 아니면 GUD 메뉴를 써먹자.
따로 뜬 프레임만 닫을때는 C-x 5 0

간단한 .gdbinit 사용
정말 최소한의 것만 적자면
  1. pretty print 켜주고,
  2. emacs 상에서 M-x gdb 로 gdb 띄울때 매번 arg 세팅을 피하기 위해서 set args 해주고
  3. 몇몇 중요한 함수들 브레이크를 미리 잡아둔다.
정도... 예를들어 .gdbinit 을 요런식으로 만들어주자.
set print pretty on
set args -B 200 --frames 5 -o /tmp/output.264 /tmp/foreman_352x288_30fps_449.yuv 352x288
b x264_me_search_ref

어떤 타입의 정보를 자주 살펴봐야 할때
gdb 의 print 명령이 꽤나 좋지만 아주 복잡한 구조체가 있고 그중 일부 멤버만 디버깅에 필요하다면 매번 print 하는건 상당히 귀찮다. 아래에 언급한 STL 디버깅 스크립트 처럼 gdbinit 안에 적당한 디버깅용 함수를 만들어서 이걸 이용하는 방법도 있지만 대부분의 경우 가능하면 소스안에 포함하는게 좋다고 본다.( 물론 STL 은 내부구현이 가려져 있으니 소스내에서 뽑는건 오히려 좋지 않겠지, msvc 도 유사한 기능이 있을테니 이런건 디버거 레벨에서 처리하는게 맞을듯) 예를들어 아래 같은 코드가 있으면
사용자 삽입 이미지

디버깅시 int 값이 필요할때마다 gdb 상에서 call dump_int(foo) 를 통해서 값을 출력해볼수 있다.

사용자 삽입 이미지




좀더..