posted by 아겔-_- 2011.08.13 00:52
daum-cloud-on-debian-squeeze

daum-cloud-on-debian-squeeze

1 Daum Cloud On Debian-Squeeze

8월 13일 토요일, 오전 12:15

하악하악… 좋다 다음! http://cloud.daum.net/disk/Index.daum#ViewPcAppHelpCmd

근데 설치하려고하니 에러가…

Error: Dependency is not satisfiable: libnautilus-extension1 (>= 1:2.22.2)” while installing dropbox in Debian Squeeze

1.1 문제에 대한 검색

음… 노틸러스에 대한 내용들은 검색되네… 아예 빌드 다시하라고 이참에 xubuntu으로 갈아탈까… 찾아보니 그것도 새버젼이 깔려있네;;; 초난감;;;

데비안 squeeze에 설치된 버젼은 "2.30.1-2squeeze1".

1.2 해결

참고

http://thestandardoutput.com/2011/05/dependency-error-when-trying-to-install-dropbox-on-debian-6-squeeze/

위 내용에서 거의 그대로 libnautilus1에 대한 버젼만 맞춰줘서 .deb 파일 다시 묶어주니 잘된다. 하악하악…

  1. ".deb" 파일을 받는다.
  2. 임시 디렉토리를 다음과 같이 만든다.

    mkdir -p extract/DEBIAN

  3. .deb 파일 압축을 푼다.

    dpkg -x daumcloud1.0.0.105.deb extract/

  4. .deb 파일로부터 패키지 정보를 푼다.

    dpkg -e daumcloud1.0.0.105.deb extract/DEBIAN

  5. "extract/DEBIAN/control" 파일을 텍스트편집기로 연다.
  6. "Depends:"으로 시작하는 행을 찾는다.
  7. 문제가 되는 다음의 항목을 찾아낸다.

    libnautilus-extension1 (>= 1:2.22.2)

  8. 다 좋은데, 우분투에서는 버젼이 "1:2.22.2"와 같은데, 데비안은 그냥 "2.22.2"와 같이 넘버링한단다. 그래서 "1:" 부분만 지우고 다음처럼 만들고 저장한다.

    libnautilus-extension1 (>= 2.22.2)

  9. 빌드용 임시 디렉토리를 만들다.

    mkdir build

  10. .deb 파일을 수정한 내용을 반영해서 새로 묶는다.

    dpkg-deb -b extract/ build/

???
성공했으면, 이제 "daumcloud1.0.0.105i386.deb"와 같은 새로운 .deb 파일이 build 디렉토리에 생겼음을 볼 수 있다.
???
빌드 디렉토리로 이동하여, 요걸 설치한다.

dpkg -i daumcloud1.0.0.105i386.deb

Author: Jonghyouk Yun

Date: 2011-08-13 00:45:26 KST

HTML generated by org-mode TAG=7.01g in emacs 23

 
결과파일 링크:: http://www.box.net/shared/fcu7t1ryd5jm8lthcsv6

신고
posted by 아겔-_- 2010.11.05 23:38

Win32 + CLISP + SLIME

-*- org -*-

1 아겔 2010-11-05 금

2 필요성

  • Win32에서 쓸만한 커먼리습 구현/환경을 세팅하는게 나름대로 많은 사람들이 도전하고 나도 해봤는데 만만치도 않고, 만족스럽게 구현하는게 힘들었었다.
  • 나름 이번에 CLISP을 구현체로 사용하면서 느낀점과 노하우를 정리해보기.

3 어째서 CLISP?

3.1 장점

  • 윈도에서 별 문제없이 잘굴러간다. (CCL, SBCL, CMUCL이 좀 불안정하고 항상 베타인점과 비교해서 큰 장점이라고 생각함.) Viaweb의 경우에도 윈도환경에서 CLISP을 이용하여 개발하였다고.
  • 안정적이다. 윈도환경에서 다른 구현체들은 다운되거나 SWANK만 띄우다가도 죽는 Kitten of Death을 종종 보는데 CLISP/Win32에서는 그런 경우를 본적이없다.
  • 생각보다 정말 빠르다. 바이트코드를 이용하는 VM이라서 다른 네이티브 코드를 생성하는 컴파일러에 비해서 느릴거라는 생각을 했는데 그렇게 차이가 안나고 오히려 다른 언어들(자바, 파이썬…)등보다 빠르고 특히 수치연산과 같은 부분은 놀랄정도로 빠르다. 실제로 애플리케이션 개발해서 사용해도 성능에 무리가 없다.
  • 애플리케이션 개발하여 단독배포(Standalone Deployment)이 윈도에서도 현실적이고 잘되어있다. 단순히 EXT:SAVEINITMEM을 이용하여 실행화일과 함께 이미지를 떨굴수있도록 되있어서 편하게 배포할수있다.
  • 유니코드 지원이 좋다. 다른 구현체에 비해서 유니코드 구현 레벨도 높고 바로 적용해서 쓸만한 수준이다.
  • 구현노트에 정말 자세하게 문서화를 잘해놨고, 윈도환경에서 큰 사용자를 크게 놀래키지않고 안정적이고 멋진 성능으로 커먼리습을 경험하기에 좋은 구현체라고 생각한다. (다른 운영체제에서도 그렇긴하지만)

3.2 단점

  • 스레드 지원이 좀 거시기하다. CLISP 구현노트(implementation notes) 문서에는 CL:*FEATURES*에 :MT이 있고, MT 패키지를 통해서 구현하고, POSIX, Win32에서 지원한다는데 내 버젼에서는 지원이 꺼져있나보당. (CLISP 2.49, 2010/07/07, Win32)
  • "Bordeaux Threads"와 같은 de Facto 스레드 라이브러리에서도 CLISP은 아예 지원이 안되고있음.
  • 스레드 관련 때문인지 Hunchentoot와 같은 일반적으로 커먼리습 웹개발에 이용하는 웹서버/웹프레임웍이 지원안된다. (다른 대안도 많지만)
  • 내장 함수들은 docstring이 거의 없어서 slime-autodoc의 덕을 별로 못본다. 다른 구현체들은 docstring이 나름 붙을만큼 붙어있어서 HyperSpec 안봐도 대충 알수있지만 docstring도 안붙고 인자 이름도 그냥 arg1, arg2… 이렇게만 보여서 가끔 거시기함.

3.3 대안들

  • SBCL : 좋고 네이티브 컴파일러라 멋지긴한데, 리눅스/FreeBSD였다면 이를 쓰겠지만, 윈도에서는 정말 너무하다 싶을 정도로 뻗어버려서 안쓰고 만다는 생각밖엔 안든다. docstring이나 그런것들도 친절하게 잘해놨고, 배포도 쉽게 할수있도록 배려를 해놨지만 여전히 윈도지원이 거시기하다.
  • Clozure CL : 네이티브 컴파일러, docstring 모두 좋은데, 역시 무서울정도로 뻗어주고 윈도에서 배포도 좀 거시기해보인다.
  • ECL : 윈도에서도 빌드되고 바이트코드 방식이라고. 음 나름 평이 좋은거 같은데 시도해볼까.
  • MKCL : 아직 써본적없음. KCL계열이고, ECL에서 fork했다고. 윈도에서도 MingW을 이용해서 빌드가 가능하단다. 나중에 한번 시도해보고 싶음. 프로젝트 자체가 매우 새롭다.
  • 상용 구현체 (Franz, LispWorks) : 돈 있으면 사서 쓰고싶다. 트라이얼들은 사용시간 제한이 있거나, 힙크기 제한이나 이미지 저장이나 deploy을 못하게 막아놓았다. 결국 돈주고 사는게 제일 속편할거 같다.
  • ABCL : 특이하게 JVM위에서 굴러가는 구현체. 시도해보면 재밌을거 같다.

4 Emacs+SLIME 기본세팅

  • 딱 필요한 설정만 하는게 취향.

4.1 이맥스 설치

4.2 SLIME 패키지 수동 설치

  • 그냥 cvs snapshot 받아서 압축 풀어서 바로 적용.

4.3 ~/.emacs

(setq slime-net-coding-system 'utf-8-unix)
(add-to-list 'load-path "c:/lisp/slime-2010-10-29/")
(require 'slime)
(setq inferior-lisp-program "c:/lisp/clisp/clisp.exe")
(slime-setup '(slime-fancy))
(setq slime-header-line-p nil)

5 mk-defsystem? ASDF? libCL? QuickLisp? clbuild?

  • 의존성, 외부 라이브러리.
  • 커먼리습에도 다양한 시도가 있구낭.
  • 그 이외에도 어떤 '시스템(system)'을 컴파일하고, 이미지에 적재하는데 좀 자동화하는 필요성도 있긴함. 어떤 시스템을 만들어서 배포하는데 이런거 일일이 적어주기도 그렇고 스크립트로 작성하기도 마땅한건 아니니까.
  • '시스템' : 패키지는 이름공간을 나누는데 이용하고, 자바와 같은 플랫폼과는 다르게 단순히 한 소스파일이 꼭 하나의 패키지 항목이라고 말할수도 없고, 하나의 소스에도 여러 패키지를 만들수도 있고… 차라리 C/C++처럼 여러개로 분할하여 컴파일도 가능하고… 커먼리습은 파일기반이라기보다는 이미지 기반이기 때문에 좀 다른 접근법이 필요함. 이런 상황에서 다수개의 패키지, 다수개의 소스파일을 일괄, 자동화하여 빌드/로딩할 방법이 필요함. 이런 집합을 '시스템'이라고 부르는듯함.
  • 어떻게 생각하면 C/C++의 make이랑도 비슷하다고 생각하면됨.
  • 의외로 "quicklisp user survey"(http://xach.livejournal.com/271794.html)의 결과에서 재밌는 부분을 찾았다. 나 이외에도 대부분의 CL이용자들이 직접 그냥 손으로 다운로드하여 시스템을 설치하는구나…

5.1 mk-defsystem

  • CLOCC(the CommonLisp Open Code Collection)에 포함된 'defsystem'
  • 좀 오래된 방법인거 같음.
  • 더 대중적으로 인기도 많고 대세인 'asdf'의 'asdf-install'을 통해 설치가 가능하단다.
  • C/C++의 make이랑 비슷한 위상인듯.

5.2 ASDF

  • ".asd" 파일을 통해서 정의한 시스템을 그와 딸린 소스코드를 컴파일/로딩하는데 이용하는 de Facto.
  • 현재 오픈소스 리습 커뮤니티의 거의 대부분의 라이브러리나 애플리케이션은 asdf을 통해 패키징하고 배포하는게 대세인듯.
  • 네트웍을 통해 자동으로 패키지를 다운로드하고 설치하고, 의존성도 자동으로 설치해주는 asdf-install 같은 확장도 있어서 편리하다.
  • 윈도 환경에선 asdf-install이 마땅치 않으나 그래도 asdf을 손으로 설치해도 나쁘지 않으므로 이렇게 이용하는게 차라리 속편하다.

5.3 libCL

  • 리눅스 배포판처럼 아예 자주 쓰는 커먼리습 라이브러리들을 한번에 묶어서 설치해 사용하도록 하는 방법.
  • 그럭저럭 쓸만한데 업데이트도 느리고 윈도7에서 잘 굴러가지도 않아서 편하긴 하지만 안쓰게됨.

5.4 QuickLisp

  • asdf-install처럼 원격의 시스템을 받아다 의존성까지 풀어서 설치하는 새로운 방식.
  • 좋긴한데 중앙집중적으로 또 다른 저장소에서 메타데이터들을 관리하고 좀 마음에 안들때도 있음. 어차피 정말 그래도 써야겠다면 어차피 손으로 로딩해도 되긴하지만. 무엇보다 윈7에서 잘 안맞는거 같아서 이것도 접었음.

5.5 clbuild

  • asdf-install처럼 라이브러리를 다운로드/컴파일/로드하는 방식.
  • jhbuild을 모델로해서 만들었다고 하는구낭. 쉘스크립트 방식이라 윈도에선 좀 거시기할듯. 그리고 QuickLisp처럼 중앙 저장소에서 관리를 하는구나.

6 ASDF 이용

6.1 ~/.clisprc.lisp을 이용하여 asdf 로딩/설정

  • 단순히 "asdf.lisp" 파일을 시작시 CL:LOAD 하도록 지정해주면됨.
    ;; c:/lisp/lisp/asdf/asdf.lisp 있어야겠죠?
    (load #P"c:/lisp/asdf/asdf")
    

6.2 시스템 컴파일/로딩

  • 시스템의 이름을 지정할때는 예를 들어, 시스템 이름이 "puri"인 경우 키워드나 문자열, 심볼 모두 가능.
  • ASDF:*CENTRAL-REGISTRY*에 ".asd" 파일과 소스코드가 위치한 디렉토리를 CL:PUSH해주고서 실행하는게 윈도에선 속편함.
    • 단점으로는 의존성들에 대해서도 일일이 CL:PUSH ^^;
  • 컴파일 : ASDF:COMPILE-SYSTEM이나 ASDF:OPERATE, ASDF:OOS와 ASDF:COMPILE-OP 이용.
    > (ASDF:COMPILE-SYSTEM :puri)
    ;; ..or
    > (ASDF:OPERATE 'ASDF:COMPILE-OP :puri)
    ;; ..
    > (ASDF:OOS 'ASDF:COMPILE-OP :puri)
    
  • 로딩 : 컴파일과 같으나, ASDF:LOAD-SYSTEM, ASDF:LOAD-OP인점만 다름. 컴파일은 자동으로 적용.

6.3 기타…

  • 윈도에서 "바로가기"를 이용하여 유닉스의 심볼릭 링크처럼 ASDF:*CENTRAL-REGISTRY*에 지정한 디렉토리에 ".asd" 파일만 링크하면 매번 시스템 적재할때마다 ASDF:*CENTRAL-REGISTRY*에 경로를 지정안해도 된다고 하는데 난 왜 안되지;;;
  • "NTFS Symbolic Link"을 이용하여 시도해보면될까
  • 아님 ASDF:*SYSTEM-DEFINITION-SEARCH-FUNCTIONS*에 하위 디렉토리를 검색하여 로딩하도록 함수를 추가해서도 해결이 가능해보인다.
    • http://en.wikibooks.org/wiki/Common_Lisp/External_libraries/ASDF/Configuring_ASDF#Alternative_to_symlinks.2C_search_directories_recursively
      ;; An alternative to the standard sysdef search can be defined.  This                
      ;; code below can be dropped into your Lisp init files and customized.               
      ;; It will search for all ASDF systems in subdirectories of the                      
      ;; specified directories.  That lets you simply "drop-in" new packages               
      ;; into one of the specified directories, and it will be available for               
      ;; loading without any further steps.                                                
      (in-package #:asdf)
      (defvar *subdir-search-registry* '(#p"/my/lisp/libraries/")
        "List of directories to search subdirectories within.")
      (defvar *subdir-search-wildcard* :wild
        "Value of :wild means search only one level of subdirectories; value of :wild-inferiors means search
       all levels of subdirectories (I don't advise using this in big directories!)")
      (defun sysdef-subdir-search (system)
        (let ((latter-path (make-pathname :name (coerce-name system)
                                          :directory (list :relative
                                                           *subdir-search-wildcard*)
                                          :type "asd"
                                          :version :newest
                                          :case :local)))
          (dolist (d *subdir-search-registry*)
            (let* ((wild-path (merge-pathnames latter-path d))
                   (files (directory wild-path)))
              (when files
                (return (first files)))))))
      (pushnew 'sysdef-subdir-search *system-definition-search-functions*)
      

Author: Jonghyouk Yun <ageldama@gmail.com>

Date: 2010-11-05 23:34:01 KST

HTML generated by org-mode 6.21b in emacs 23

신고
posted by 아겔-_- 2010.07.18 04:06
클로져 개발을 하려면 clojure.jar을 설치하는것도 아니고 이맥스랑 연동하는것도 아니고 오히려 leiningen을 설치하여 쓰는게 가장 좋은 방법이라고 생각한다.

편집기 연동은 솔직히 vim에 문법강조만 깔아서 써도 나쁘지않다. 어차피 'lein repl'로 테스트해볼수도 있고 될거는 다 되니까, 자동완성이나 실시간 docstring 표시같은건 되면 좋지만 사실 필수는 아니라고 생각한다. 기존의 파이썬이라 루비 개발을 할때에도 이들이 지원되면 좋았지만 안된다고 개발이 안되거나 어렵진 않았으니까.

특히 윈도에서 leiningen을 설치해 쓰는게 좋다고 생각한다.
윈도에서는 swank-clojure(<http://github.com/jochu/swank-clojure>)을 설치해도 이맥스에서 잘 연동이 안될수도 있고, 이클립스의 counterclockwise등의 IDE을 사용해도 없으면 많이 불편한게 사실이니까.

기존에 파이썬으로 lein을 다시 작성해서 메일링에도 올려보고 윈도에서 bash이 없어도 leiningen이 잘 굴러가게 하려고 삽질을 좀 해봤지만(<http://www.mail-archive.com/clojure@googlegroups.com/msg21473.html>) 맘에 들진 않았고, 호응도 좋았는데, 아이디어만 주고 말려고 했는데 자꾸 요구사항 반영해 달라고해서 귀찮을거 같아서 그만뒀다;;;
(돌 날아온다;;;)

여튼, 현재는 도스 배치파일 버젼도 배포한다. (<http://github.com/technomancy/leiningen/blob/master/bin/lein.bat>)

위의 배치파일을 다운로드하여 PATH 걸린 위치에 넣어준다.

보통 리눅스/유닉스에서는 이렇게 스크립트만 넣고 'self-install'하면 설치가 끝나지만 윈도에서는 그렇지 않아서 직접 clojure.jar, lein.jar을 찾아 넣어준다.

lein.bat을 열어보면 다음과 같은 부분이 있다.
rem this script works after downloading Leiningen standalone jar
rem and copying it on %LEIN_JAR% path

rem optionally can be downloaded also Clojure jar
rem (stable release, 1.1.0 or newer is recommended)
rem and copied on %CLOJURE_JAR% path
rem this step is not necessary, because Leiningen standalone jar
rem contains Clojure as well

set CLOJURE_VERSION=1.1.0
set LEIN_VERSION=1.1.0
일단 필요한 clojure.jar, lein.jar의 버젼을 확인한다. (set CLOJURE_VERSION=..., set LEIN_VERSION=...). 위의 URL을 방문하여 해당 버젼의 jar 파일을 다운로드한다.

그리고 이 저장한 파일의 절대경로를 환경변수로 세팅해주면 된다. 이는 lein.bat의 다음의 부분을 수정한다.

rem uncomment this and set paths explicitly
rem set LEIN_JAR=C:\Documents and Settings\wojcirob\.m2\repository\leiningen\leiningen\%LEIN_VERSION%\leiningen-%LEIN_VERSION%-standalone.jar
rem set CLOJURE_JAR=C:\Documents and Settings\wojcirob\.m2\repository\org\clojure\clojure\%CLOJURE_VERSION%\clojure-%CLOJURE_VERSION%.jar

굵게 표시한 set LEIN_JAR, set CLOJURE_JAR 두행의 맨 앞 rem을 지우고, 그 값에 저장한 clojure.jar, lein.jar의 절대경로를 지정한다.

그리고 "lein version"을 콘솔에서 실행하여 설치가 잘되었는지 확인한다. :-)

신고
posted by 아겔-_- 2010.07.18 03:49


 이 문서에서는 간략히 leiningen이 무엇인지 설명하고, 이를 이용하여 기본적인 클로져 개발 사이클에 필요한 내용을 HOWTO형식으로 정리한다. 그리고 실용적으로 개발하기위한 TDD, REPL, 이클립스 연동과 같은 부분들 또한 설명하도록 한다.





leiningen?

 leiningen은 클로져 프로젝트 관리도구다.

 자바의 Apache Maven와 같은 위상의 도구로서 다음과 같은 작업을 기본적으로 지원한다.

 * 초기 스켈레톤 생성
 * Maven, Clojars등의 원격저장소를 통한 외부라이브러리 의존성관리
 * 빌드, 테스트, 패키징 등 일반적인 개발사이클에서 필요한 작업의 자동화
 * ...그밖에 다양한 기능들을 플러그인을 통하여 지원

 Maven의 pom.xml와 같이 project.clj을 통하여 훨씬 간결하고 선언적으로 프로젝트를 관리하도록 지원한다.


 Leiningen은 단일한 스크립트로서 시스템에 설치하며, 유닉스/리눅스/OSX에서의 설치는 단순히 'lein' 쉘 스크립트를 받아 'lein self-install'로 완료하며, 윈도의 경우에는 별도의 문서를 참고하여 'self-install' 대신 직접 두세단계의 절차를 진행하여 설치한다.
 
 Leiningen은 어떤 GUI 도구나 IDE이 아니라 CMD.exe이나 유닉스쉘을 통해 접근하는 스크립트이므로 이 문서에는 쉘이나 콘솔에서 명령을 실행하는것을 기준으로 설명하겠다.

 
 * Leiningen : <http://github.com/technomancy/leiningen>
 * Apache Maven : <http://maven.apache.org/>
 * Clojars : <http://clojars.org/>









프로젝트 시작

 프로젝트는 new명령으로 다음처럼 생성한다.
 
 > lein new net.adaltan/foobar


 
 new명령은 현재 디렉토리에 프로젝트 스켈레톤을 생성하고, 'net.adaltan'은 그룹ID, 'foobar'은 프로젝트ID이다.
 결과적으로 'net.adaltan.foobar'을 최상위 네임스페이스로하는 프로젝트를 생성한다.
 
 
 
 
 
 




의존성

 개발을 하면서 외부 라이브러리를 참조하여야 할 경우, .jar 파일을 classpath에 추가하거나 Maven의 경우 pom.xml에 이를 기재하였다. 이와 같이, project.clj에 외부 의존성을 지정할수있다.
 
 기본적으로 생성한 프로젝트의 project.clj은 보통 다음과 같다.

(defproject net.adaltan/foobar "1.0.0-SNAPSHOT"
  :description "FIXME: write"
  :dependencies [[org.clojure/clojure "1.1.0"]
                 [org.clojure/clojure-contrib "1.1.0"]])


 :dependencies 벡터에 원하는 의존성을 추가하여준다. 여기에 적는 방법은 "group-id/artifact-id version"와 같은 형식으로 적는다. 예를 들어, 다음과 같은 형태로 지정한 pom.xml은...
 
    <dependency>
        <groupId>com.lowagie</groupId>
        <artifactId>itext</artifactId>
        <version>2.1.3</version>
    </dependency>

 다음의 project.clj의 의존성 벡터로 표현한다.
 
    [ ... [com.lowagie/itext "2.1.3"] ... ]

 매우 간단하다. :dependecies은 애플리케이션의 실행시간에 참조할 classpath에 추가하는 의존성이다.
 
 leiningen 자체도 의존성을 표현하는데, 이는 leiningen의 플러그인을 지정할때 사용한다. 이때는 :dev-dependencies을 키로 하며, dependecies와 같은 형식으로 지정한다. SLIME연동, 이클립스 프로젝트 연동, ...등과 같이 leiningen의 기능을 플러그인을 통해 확장할때 :dev-dependencies을 이용한다.
 
 Clojars이나 Maven repository에서 검색하여 의존성을 지정하면된다.
 
 의존성을 project.clj에 지정하였다면 "lein deps" 명령으로 이를 다운로드 받아와 적용한다.
 
 > lein deps
 ...

 추가적인 jar 저장소를 지정이 가능한데, 이들에 대해서는 이후 보일 예제 project.clj을 참고하라.

 
 
 



빌드, 패키징...

 일반적인 애플리케이션 빌드 과정에 속하는 단계들이므로 별도의 설명없이 명령들을 나열하겠다.

 프로젝트를 컴파일
 > lein compile
 
 프로젝트 클린
 
> lein clean

 프로젝트 jar로 패키징
 > lein jar
 
 프로젝트 jar로 패키징 (모든 의존성을 포함한 하나의 uberjar로 생성)
 > lein uberjar


 jar, uberjar의 경우 생성할 결과 파일이름, 디렉토리를 지정할수있으며, uberjar의 경우 standalone jar으로 만들수있으므로 메인 클래스를 지정 가능하다. 이들 키워드에 대해서는 이후에 설명할 예제 project.clj을 참고하라.
 
 프로젝트를 빌드하여 시스템 로컬 저장소에 설치
 > lein install


 프로젝트 빌드시에 소스파일 이외에도 classpath으로 복사하는 리소스 파일등이 있다면 :resources-path을 통해 해당 경로를 지정 가능하다.

 또한, .java 파일들을 프로젝트에 함께 포함하여 클로져+자바로 프로젝트를 개발한다면 lein-javac을 이용하여 이를 함께 컴파일하도록 한다.

 * lein-javac : <http://github.com/antoniogarrote/lein-javac>






REPL, 테스트

 코딩을 하고 자신이 작성한 모듈을 점진적으로 테스트하고 디버깅하려면 REPL을 이용하는게 바람직하다.
 이를 위해 다음처럼 실행한다.

 > lein repl


 위와 같이 한 다음 use을 이용하여 자신이 개발한 네임스페이스를 불러와 테스트하면된다.

 user> (use 'net.adaltan.foobar.core)


 또한, leiningen 기본 프로젝트는 항상 단위테스트 파일을 생성하는데 이들 파일은 src의 레이아웃과 같이 test 디렉토리에 위치한다. 예를 들어, src/net/adaltan/foobar/core.clj을 위한 테스트 파일인 test/net/adaltan/foobar/core_test.clj 파일은 다음과 같이 생성해준다.

(ns net.adaltan.foobar.core-test
  (:use [net.adaltan.foobar.core] :reload-all)
  (:use [clojure.test]))

(deftest replace-me ;; FIXME: write
  (is false))

 이는 clojure.test(<http://richhickey.github.com/clojure/clojure.test-api.html>)을 이용한 단위테스트다.

 함수를 작성하고 이에 대한 테스트를 적용하려면 이렇게 단위테스트를 작성하고 다음의 명령으로 테스트해본다.

 > lein test






예제 project.clj

 이 섹션에서는 예제 project.clj을 보여 어떠한 키워드들을 기본적으로 지원하는지 보여 설정가능한 기능을 파악하도록한다.

<http://github.com/technomancy/leiningen/blob/master/sample.project.clj>

;; 프로젝트 이름 "sample", group-id은 "org.example".
(defproject org.example/sample "1.0.0-SNAPSHOT" ; 버젼은 "1.0.0-SNAPSHOT"
  ;; Clojars에 업로드하였을때 설명으로 표시될 내용, 이를 통해 검색이 가능함
  :description "A sample project"
  ;; Clojars에서 표시할 프로젝트 URL
  :url "http://example.org/sample-clojure-project"
  ;; 프로젝트 메일링리스트. 혹시 다수개라면 리스트로 묶어서 여러개를 나열하도록한다.
  :mailing-list {:name "sample mailing list"
                 :archive "http://example.org/sample-mailing-list-archives"
                 :other-archives ["http://example.org/sample-list-archive2"
                                  "http://example.org/sample-list-archive3"]
                 :post "list@example.org"
                 :subscribe "list-subscribe@example.org"
                 :unsubscribe "list-unsubscribe@example.org"}
  ;; 프로젝트 라이센스 및 배포정보.
  ;;   다수개의 라이센스를 채택할경우 :license 키 대신에 :licenses을 이용해 나열한다.
  ;;   :distribution은 :repo이거나 :manual인데 공개 저장소에 올려도 좋다면 :repo을 선택한다.
  :license {:name "Eclipse Public License - v 1.0"
            :url "http://www.eclipse.org/legal/epl-v10.html"
            :distribution :repo
            :comments "same as Clojure"}
  ;; 의존성
  :dependencies [[org.clojure/clojure "1.1.0"]
                 [org.clojure/clojure-contrib "1.1.0"]
                                 ;; :exclusions 키를 이용하여 포함하지 않을 네임스페이스를 지정함
                 [log4j "1.2.15" :exclusions [javax.mail/mail
                                              javax.jms/jms
                                              com.sun.jdmk/jmxtools
                                              com.sun.jmx/jmxri]]]
  ;; 의존성을 다운로드할때 lib/ 디렉토리를 묵시적으로 삭제하고 다시 받을지 지정.
  :disable-implicit-clean false
  ;; 개발시 필요한 의존성을 나열. uberjar으로 jar로 묶었을때 이들은 포함하지 않는다.
  :dev-dependencies [[org.clojure/swank-clojure "1.2.1"]]
  ;; 자바연동과 :gen-class을 위해 AOT 컴파일할 클래스를 나열. :namespaces은 :aot와 같다.
  :aot [org.example.sample.SampleClass]
  ;; uberjar로 묶었을때 "main"으로 적용할 네임스페이스
  :main [org.example.sample]
  ;; reflection call에 대한 경고?
  :warn-on-reflection true
  ;; 기본 저장소를 사용할지?
  :omit-default-repositories true
  ;; 추가적인 저장소를 지정
  :repositories { "java.net" "http://download.java.net/maven/2"
                  "jboss" "http://repository.jboss.com/maven2/"}
  ;; 기본적인 프로젝트 파일 경로와 다르게 설정하려면 다음의 경로들을 설정할것
  :source-path "src/main/clojure"
  :library-path "target/dependency"
  :test-path "src/test/clojure"
  :resources-path "src/main/resources"
  :native-path "src/native" ; JNI, Native 의존성 파일들의 위치
  :jar-dir "target/" ; 프로젝트 jar 파일 생성 디렉토리
  :jar-name "sample.jar" ; 'lein jar'로 생성한 파일의 이름
  :uberjar-name "sample-standalone.jar" ; 'uberjar'로 생성할 파일의 이름
  ;; JVM에 전달할 인자
  :jvm-opts "-Xmx1g")

 기본설정이 있으므로 위에 나타난 키워드들을 모든 project.clj에 적을 필요는 없지만, 필요한 경우에는 이를 오버라이드하여 설정가능하므로 알아두는게 좋다.






Apache Maven, 이클립스(counterclockwise)와의 연동

 'pom' 명령으로 쉽게 pom.xml을 생성하여 Apache Maven 프로젝트로 전환이 가능하다.
 클로져 프로젝트는 Apache Maven을 통해 Leiningen을 통해 관리하듯이 관리가 가능하다.

 * Clojure Maven Plugin : <http://github.com/talios/clojure-maven-plugin>

 하지만, Leiningen만큼 많은 플러그인을 통한 기능을 지원하지는 않는것으로 보인다.

 마지막으로 가장 많이 사용하는 자바 개발도구인 이클립스와 이클립스를 위한 클로져 플러그인인 counterclockwise을 위한 프로젝트 파일을 생성하는 lein-eclipse을 소개한다.

 다음의 URL을 참고하여 :dev-dependencies에 lein-eclipse을 추가한 다음 다음처럼 하여 이클립스 프로젝트 파일을 생성한다.

 * counterclockwise : <http://code.google.com/p/counterclockwise/>
 * lein-eclipse : <http://clojars.org/lein-eclipse>

 > lein deps
 > lein eclipse

 이렇게 프로젝트를 생성한 다음엔 Import하여 바로 이클립스에서 개발이 가능하다.







신고
posted by 아겔-_- 2010.07.15 17:38

이번에 읽은책은 덕스러운 책들을 즐겨 출판하샤 세간의 찬사를 받고 계신 '도서출판 인사이트'에서 우리글로 내어놓은  "프로그래밍 클로져".
클로저 표지
 


http://pragprog.com/images/covers/original/shcloj.jpg 사실은 영문판으로 개인적으로 구입해서 "커먼리습 덕질이 우선"와 "남자라면 네이티브 컴파일러?!"라는 생각으로 한 세 챕터정도만 조금 읽어두고 썩히고 있었읍죠. (맛만 봐두고 정작 중요한 functional programming, laziness, concurrency와 관련한 부분은 읽지도 않았던게죠^^;)


Clojure 언어 자체는 최근에 들어서 GitHub, BitBucket등의 오픈소스 프로젝트 피드들을 살펴볼때마다 느끼지만 오픈소스 커뮤니티 안에서 급성장했다고 생각합니다. 정말 기존의 수많은 lisp-clone이나 이러한 시도를 했던 스킴 환경들과 달리 급성장하고있고, 충분히 성숙하고 멋진 프로젝트/라이브러리들이 이미 세상에 나와있다고 생각합니다. 그리고 JVM에서 굴러갈
무언가를 개발 하기에도 더없이 매력적인 환경이라고 생각하구요. 제가 생각하는 요인, 혹은 현재의 현상은...

  • 언어자체가 리습이지만, 기존의 리습의 역사적이고 약간은 고리타분한 모습을 벗고 non-Lisper들에게조차 idiomatic하려 매우 노력한게 곳곳에서 느껴진다.
  • 자바언어, 그리고 수많은 자바 라이브러리에 별다른 레이어나 추가적인 작업없이 직관적이고 직접적으로 접근
  • 클로져로 작성하더라도 자바측에 이를 노출하여 상호호환이 자유로움
  • 커먼리습의 매크로(defmacro), 하스켈의 지연평가(lazy evaluation)와 같은 멋진 기능들을 적절히 융합
  • 쉽고 직관적으로 고수준의 동시성 제어가 가능하도록하여 멀티코어, JVM을 최대한 활용하도록.
  • Leiningen 그리고 Clojars
    • Apache Maven처럼 프로젝트 자체의 의존성, 형태의 선언적 기술이 가능하도록 했고
    • 빌드, 테스트, 배포 등의 일반적인 작업을 Leiningen을 통해서 쉽고, 선언적으로.
    • 의존성 관리도 메이븐의 jar뿐만 아니라 Clojars을 통해서 RubyGems와 같이 사용자간의 쉬운 공유가 가능
    • Apache Maven처럼 단순히 Leiningen에 내장된 기능만이 아니라 수많은 플러그인을 통해서 Leiningen이 지원하는 기능을 확장/개발이 가능
    • 이미 수많은 라이브러리, 애플리케이션, 플러그인이 개발되어 공유하고 있음

뭐 이런것들이 생각나는 지금의 급성장하는 요인인거 같음.

책을 읽으며 많은 부분을 새로이 생각하거나 느꼈다. 특히나 이책에서는 그간 실용성이랑은 좀 안친해보이고 심지어 고리타분하게 느낄정도의 함수형 프로그래밍을 실용적인 의미로서 다시 접근해 보이는데 크게 놀랐다.

클로져에서 제공하는 동시성 제어(책에서는 '병행성'이라고하셨음. 병행성이 더 적절한 말일듯)에 대한 설명이나 늦은 평가나 무한한 리스트/시퀀스에 대한 소개, 다중메서드라고 표현한 multiple dispatch에 관한 부분은 사실 다른 언어에서 없거나, 찾기 힘들거나 모호한 개념으로 설명을 그냥 빙 돌아가는게 일반적이라고 생각했는데 이들에 대해서 처음 접하는 이들도 명확하게 개념을 잡고 이들을 어떤때 어떻게 적용할지를 생각해보게 해준다고 생각한다.


그럼에도 약간 아쉬운점도 못되는점들은...
  • 어쩔수없이 책이 나올 시점에는 세상에 없었던것들에 대한 설명이 있었으면 했다.
    • Leiningen을 이용한 개발 방법
    • deftype, defprotocol 같은 타입정의


어쨌든 좋은책을 세상에 내주고 우리말판까지 내주신 모든분들에게 감사드리고 싶은 책이었다. :-)










ps. 오늘도 말투는 이랬다 저랬다 일관성없음;;; (고치기 귀찮;;;)

ps2. 저번 "프로그래밍 루아" 독후감도 그렇고 인사이트에서 뭐 떡고물이라도 주셔야 되는거 아닌지 깊이 생각해볼일;;;

신고
posted by 아겔-_- 2010.03.27 23:25
신고
posted by 아겔-_- 2010.03.03 23:13
http://luajit.org/

음... 한마디로 말하자면... "헐퀴!"

정말 죽여주게 빠르다. lua자체가 이미 내부적으로 자체 바이트코드로 컴파일을 하는데, 이걸 다시 해당 플랫폼에 맞는 기계어로 JIT 컴파일해서 실행해서 정말 눈물나게 빠르다 ㅜ.ㅜ;;;

거기에 빌드하는 과정도 거의 기존의 lua을 빌드하는 과정과 크게 다르지 않아서 쉽고, C API 레벨에서 호환가능이라 기존 루아연동부분을 거의 링크하는 라이브러리만 교체해서 성공했다. ;-)

Project Euler 001번의 범위를 죠낸 키워서 그냥 루아에서 7.8초정도 걸리도록 범위를 키웠었다. 그리고 그걸 gcc 버젼이랑 자바버젼, LuaJIT버젼이랑 비교해보면 재미있는 결과를 얻을수있었다. (AdHoc 벤치마킹;;; 소스는 쪽팔려서 공개안할래요;;;)
gcc은 1초 안팎, jdk 6도 2초 안팎, luajit은 2초 안팎... 하악하악...

기존 루아부분을 그냥 교체해주면되고 성능은 정말 비교할수없을정도로 향상됐다... 하악...



ps. 오늘도 루아덕질인가...


신고

'삽질+돈되는짓 > Lua'tic Dawn' 카테고리의 다른 글

LuaJIT 만지작 거린 소감  (5) 2010.03.03
독서: Programming in Lua  (6) 2010.03.03
Lua HTTP Server + Native Agent  (6) 2009.06.29
posted by 아겔-_- 2010.03.03 01:47

인사이트 출판사의 "Programming in Lua"을 읽었습니다.

루아라는 언어를 알고있던것은 오래되었고 실제로 사용할 기회는 별로 없었습니다. 가능하면 네이티브 C/C++에서 작업을 안하려고 했었고, 회사일도 대부분은 자바나 플렉스 같은 VM위에서 이루어지는 일이라 Rhino, JRuby같은 스크립팅에만 익숙해져있었지 루아를 적용할 필요랄까 그런걸 잘 모르고 살았었죠. (굳이 네이티브가 아니라도 루아를 적용할수있지만 :-))

루아를 직접 사용하면서 느꼈던것은 이상한 재미였었습니다. 그동안은 필요이상으로 간결하고 너무 loosy한 언어가 아닌가 그럴바에는 그냥 루비나 파이썬을 쓰지 왜 그런걸 쓰는지 이해하기 어려웠었죠. 하지만 직접 사용했을때는 정말 달랐습니다. 테이블, 함수객체, 클로져 등으로 그간 너무 익숙해진 테크닉들을 더 단순한 방법으로 구현하고 있는 자신을 발견했을때는 묘한 기분이었습니다. 거기에 "쉽지않다"라고만 생각하던 C언어를 통한 네이티브 연동이 luabind등을 이용해서 쉽게 이루어지고, 인터프리터를 내장하는것도 정말 딱 필요한만큼의 작업만이 필요했습니다. 무엇보다 수많은 luaforge.net의 모듈들을 적용해서 강력한 무언가를 만들기 수월했습니다. (약간의 require을 통해서!)

물론 최초 진입시 마치 환경을 조성하는것 같은 빌드환경을 만들고 필요한 모듈들을 이에 맞춰 빌드하는 과정은 힘들었었지만 재미있었습니다. (luacom 같은건 다시 컴파일하고 싶지않을 정도에요;;;)

어쨌든 책은 회사에 도서신청해서 받아봤습니다. 루아에 대해서 어느정도 알고 C애플리케이션에 내장하고 C/C++을 통해서 확장할줄 아는 정도의 수준에서 받아봤습니다. 처음엔 "아... 놔... 실수했나" 싶었는데 아니었죠.

책에는 내가 루아에 대해 잘못알고있던 많은 semantic한 부분들, 그리고 너무 복잡하게 정리가 안되있던 부분들까지 깔끔하게 정리해줬습니다. 더 놀라운건 오히려 다른 수많은 applicative, functional언어들을 설명한 책들보다 오히려 간결하고 쉽게 강력한 패러다임들을 소개하고 접근하는책이라는 느낌이 들었습니다.

어떻게보면 정말 설명하기 어려울수도 있는 클로져, first-class function, iterator, coroutine(continuation)등을 쉽게 설명해줬습니다. 차라리 누군가에게 applicative programming, functional programming이 어떤거다라고 알려주려면 루아와 이 책을 이용하는게 최선이지 않을까 하는 생각이 들정도로.

루아 언어 자체의 특징과 기능(몇개 안되지만), 그리고 간결한 기능들을 이용해서 다른 언어에서는 복잡하게 구현했던 기능들을 너무도 간결하고 직교적으로 표현함을 보입니다. (그러면서도 조잡하지않아요.)

이런 테크닉적인 부분까지 세세히 다루면서 더욱이 보통 이런 책에서는 대충 넘어가기 쉬운 자원관리나 쓰레기수집에 대한 부분, C API을 이용하여 확장하고 내장하는 방법등을 정말 정확하고 지루하지 않게 설명하는 책이었습니다.

보통 균형의 측면에서 너무 디테일해서 사전을 출력한게 아닌가 싶은 책도 있고, 너무 러프해서 웹에서 튜토리얼 읽는게 더 나았겠다 싶은 책도 많은 요즘에 좋은책을 발견해서 기쁩니다.


신고

'삽질+돈되는짓 > Lua'tic Dawn' 카테고리의 다른 글

LuaJIT 만지작 거린 소감  (5) 2010.03.03
독서: Programming in Lua  (6) 2010.03.03
Lua HTTP Server + Native Agent  (6) 2009.06.29
posted by 아겔-_- 2010.02.22 23:09
솔까말... 어쩔수없다만... 그때는 좋은 선택이었다고 생각했는데 지금에 와서는 좀 거시기해진 지식/기술을 꼽으라면 개인적으로 ActionScript/Flex라고 생각함...

대세에서 밀려 버린 느낌에 이제는 스타크래프트 UI 만드는데 정도만 유용한거 같은 지식;; (도대체 Array.map에 넘겨주는 함수객체의 시그니쳐가 뭔지 알게뭐고, DataGrid에서 ItemRenderer을 적절히 쓰는 방법이 그 영역 이외에 어떤 도움을 줄지 미지수였다;;;)

다르게 말하면 최근에는 단말성 지식으로 다른 영역에 적용할 방법이 없거나 무의미한짓이라고 생각했었다... (좀 우울하게 자기부정이었었다.)

그런데 꼭 그렇진 않더라도, 그냥 조금 여유로운 시선으로 C#, .NET, WPF, XAML, SilverLight등을 보면 꼭 그렇지도 않다는 느낌이 든다. 나름 어제보다 더 나아진 모습이고 그것들을 알고 있음으로 또 도움이 된다는 긍정적인 생각을 해본다.


ps. 하악하악 MS완소... 하악하악...




신고

'삽질+돈되는짓 > Adobe AIR/Flex' 카테고리의 다른 글

WPF, XAML을 보며 단상...  (2) 2010.02.22
RTMP  (2) 2009.06.21
AMF  (0) 2009.06.21
Local Db  (0) 2009.06.21
Native Drag & Drop  (0) 2009.06.21
posted by 아겔-_- 2010.02.18 13:16
최근에 스킴몬스터(여러 의미로 짐승남임...)에게 Win32, C/C++, Lua로 작성한 애플리케이션을 인수인계해줬다. 더러운 짐승처럼 루아를 보며 말했다...

스킴 같아요. 하지만 문법이 마음에 안들어요.
...괄호로 감싸지 않으면 마음에 들지 않을거라 예상했다.

다행히도 루아도 잘 적응해서 잘 쓰시고, C/C++은 물론 어영부영 Win32 코드들도 잘 이해를 하셔서 초속성으로 잘 넘겨버렸다고 생각했다.

이 글은 최근의 인수인계를 해드리면서 느꼈던점을 최대한 부각한 블로깅을 하려는 시도다.

  1. 어떤 기술을, 혹은 C/C++ 같은걸 "왜 그렇게 생겨먹었는가"를 설명하는건 단순히 "현상이나 현재의 상태가 그렇다."라고 설명하는건 부족하다고 생각했다.
  2. 그런걸 제대로 설명하려면 현재의 모습이 왜 그렇게 되었고, 어떤 이유나 역사에 의해 결정된 모습인지 설명하는게 훨씬 서로 재미있었다.
  3. 재미있게 전달하고 받아들이니 인수인계도 훨씬 수월했다.
  4. 그리고 그런것들은 IT쪽에 정말 많다. (그리고 재미있다 :-))
앞으로 그런것들에 대해서 나름 검색도 해보고 정리도 해서 생각나는 주제가 있을때마다 이 카테고리에 올릴 생각이다.


이번 이야기는 다음과 같다.

어째서, 전통적인 C언어에서 true/false은 '0이 아닌값'과 '0'인데, 대부분의 (main()을 포함하여) 함수들이 성공시 '0'(false?)을 되돌리는 컨벤션일까?

나도 별로 의식하지 않고 그렇구나라고만 생각해왔었는데 인수인계를 하면서 저런 질문을 받으니 딱히 이유나 역사를 설명해주지 못했다.

정말 생각해보니 그랬다.
  • Win32 함수들도 대부분 성공/실패 여부만 되돌릴때는 성공시 TRUE(non-zero)을 되돌린다. (MSDN: CloseHandle Function)
  • 자바에서도 그렇고
  • 파이썬도 대부분 그랬던듯
  • 세상이 거의 그런거 같은데...
  • ...어째서 전통적인 C에서만...

음 아침에 화장실에 앉아서 문득 생각이 났는데 유닉스 쉘의 '&&', '||'이 아닌가 생각했다.

  • statement1 && statement2   means, "execute statement2 if statement1 succed"

  • statement1 || statement2  means, "execute statement2 if statement1 fail"


물론, 유닉스 전통이 애플리케이션의 되돌림값(유닉스에는 애플리케이션도 정수값을 되돌린다! 잘 아시겠지만 main()의 되돌림값은 int다.)이 당연히 연관이 있으니 영향을 받았고, 나머지 함수들도 자연스럽게 따라간건 아닐까 생각해봄.

다시 자연스럽게, && 연산자를 저렇게 성공시에만 오른편까지 '평가'하게 하려면 앞이 && 연산자에 있어서 '거짓'일수밖에 없고, 결국 '성공'을 나타내려면 'false'을 이용해야 했을거라고 추측한다. ('||'은 당연히 반대)


사실 이런 short-circuit은 C언어에서도 사용하는 테크닉이었을테니까 C언어에서 유닉스로 영향을 넓혔다고 생각하는게 맞을것 같다.

ps. perl에서의 "foo() or die('foo FAIL')"을 통한 에러처리 같은것들은 대단히 전통에 부합하는짓이었군함.

ps2. 첫번째 포스트인데 좀 임팩트도 덜하고 역사적인 재미도 덜해서 좀 그랬나...
신고

티스토리 툴바