(loop (print (eval (read))))

;;닭집을 차리기 위한 여정

클로져 + 스마트폰(2)

clojure + 스마트폰 = <3

lein 설정및 noir 웹 프로젝트 생성하기

~/.lein/profiles.clj 를 편집한다.

1
2
3
4
{:user {:plugins [[cider/cider-nrepl "0.10.0-SNAPSHOT"]
[lein-localrepo "0.5.2"]
[noir "1.3.0"]]
:dependencies [[org.clojure/tools.nrepl "0.2.7"]]}}

다음 프로젝트 폴더 (예를들어 ~/Project ) 에 방문하여 다음을 입력하여 noir 프로젝트를 생성한다.

1
$ lein new noir foo-web

디펜던시들을 다운받고 다음의 메시지가 출력되며 프로젝트가 생성된다.

1
Generating a lovely new Noir project named foo-web...

emacs 로 다음의 파일을 연다.

1
emacs ~/Project/foo-web/project.clj

:dependenciesclojure 정도만 1.7.0 정도로 바꿔준다..

C-c, M-jclojure-jack-in 함수를 호출한다. 좀 오래 기다리면 REPL 버퍼가 열린다.

1
2
CIDER 0.10.0snapshot (package: 20150901.1605) (Java 1.8.0_45, Clojure 1.7.0, nREPL 0.2.7)
foo-web.server>

C-c, C-z 를 눌러 project.clj 버퍼가 열리도록 한 뒤에,

C-x, C-f 를 눌러 ~/Project/foo-web/src/foo_web/server.clj 파일을 연다.

C-c, C-k 를 눌러 컴파일한다.

C-c, C-z 를 눌러 REPL 버퍼로 다시 이동한다.

1
2
3
4
5
6
foo-web.server> (def srv (-main))
Starting server...
Server started on port [8080].
You can view the site at http://localhost:8080
#'foo-web.server/srv
foo-web.server>

이것으로 최초로 서버를 기동했다. aws ip 에 8080 포트로 접근해보자.

웹 페이지 만들기

src/foo_web/views/welcome.clj 파일을 연다.

C-c, M-n 를 눌러서 REPL 버퍼의 namespace 를 현재 열린 버퍼의 namespace 로 전환한다.

1
2
3
4
5
6
7
8
(ns foo-web.views.welcome
(:require [foo-web.views.common :as common]
[noir.content.getting-started])
(:use [noir.core :only [defpage]]))
(defpage "/welcome" []
(common/layout
[:p "Welcome to foo-web"]))

defpage 매크로로 선언된 부분을 보면 이후 따라오는 주소로 다음과 같은 html 을 렌더링했음을 알 수 있다.

1
<p>Welcome to foo-web</p>

html5 매크로에 의해 [:p]hiccup 이라는 라이브러리의 hiccup.core/html 매크로를 호출하여 html로 치환된다. 다음의 표현이 가능하다

1
2
3
4
5
6
7
8
9
10
foo-web.views.welcome> (println (hiccup.core/html [:h1.foo-class "bar"]))
;; <h1 class="foo-class">bar</h1>
;; => nil
foo-web.views.welcome> (println (hiccup.core/html [:h1#an-id.foo-class "bar"]))
;; <h1 class="foo-class" id="an-id">bar</h1>
;; => nil
foo-web.views.welcome> (println (hiccup.core/html [:div [:h1#an-id.foo-class "bar"]]))
;; <div><h1 class="foo-class" id="an-id">bar</h1></div>
;; => nil
foo-web.views.welcome>

다음과 같은 페이지를 만들어 보자.

1
2
3
4
5
6
(defpage "/foo" []
(common/layout
[:div.wrapper
[:input {:type "text"}]
[:button "OK"]
]))

common/layout 이란 매크로를 주목하자. 여기에 커서를 위치시킨뒤 M-. 를 이용하여 이동할 수 있다.

defpartial 매크로는 결국 hiccup 매크로로 작성된 블럭들을 조립할 수 있음을 알 수 있다.

따라서 좀더 활용가능하도록 바꿔보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
(defpartial layout [ & {:keys [style
script
header
content
footer]}]
(html5
[:head
[:title "Macadamia!"]
`(~@script)]
[:body
[:div#header `(~@header)]
[:div#wrapper
[:div#content `(~@content)]]
[:div#footer `(~@footer)]
]))

foo 페이지는 다음과 같이 변경한다.

1
2
3
4
5
6
7
(defpage "/foo" []
(common/layout
:content
[[:div.wrapper
[:input {:type "text"}]
[:button "OK"]
]]))

이렇게 해서 템플릿 레이아웃을 쓸 수 있게 되었다.

이제 이 템플릿 레이아웃에 bootstrap 을 적용하도록 하자.

css,js 등 정적파일은 resources/public/ 에 추가하면 된다. 여기서는 그냥 cdn을 이용하는것으로.

common.clj:use 함수에 include-js 를 추가하고 layout 을 수정하자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
(ns my-website.views.common
(:use [noir.core :only [defpartial]]
[hiccup.page :only [include-css include-js html5]]))
(defpartial layout [ & {:keys [style
script
header
content
footer]}]
(html5
[:head
[:title "Macadamia!"]
(include-css "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css")
(include-js "//code.jquery.com/jquery-1.11.3.min.js")
`(~@script)]
[:body
[:div#header `(~@header)]
[:div#wrapper.container {:style "display: table; height: 100vh;"}
[:div#content {:style "display: table-cell; vertical-align: middle;"} `(~@content)]]
[:div#footer `(~@footer)]
(include-js "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js")
]))

자 이제 bootstrap 으로 스타일링을 하자.

1
2
3
4
5
6
7
8
9
(defpage "/foo" []
(common/layout
:content
[[:div.col-md-12
[:div.row.col-md-6.col-md-offset-3
[:div.input-group
[:input.form-control {:type "text"}]
[:span.input-group-btn
[:button.btn.btn-primary "OK"]]]]]]))

잘 나온다. ㅎㅎ

클로져 + 스마트폰(1)

clojure + 스마트폰 = <3

보기전에

스스로를 생각하면 나는 웹사이트나 통신서버등 고만고만한 걸 개발하며 먹고살고는 있지만 개발자는 아니지 않나 하고 생각하게 됨.

애초에 전공도 아니고 로우레벨에 (회로나 어셈같은) 대한 지식도 전무하며 무엇보다 주위 개발자들이 좋아하는 서버응답속도 개선이나 나 코드 줄여쓰기 같은 욕구가 거의 없음..

따라서 이 글도 장난감만들기라는 본연의 목적에만 충실할 뿐 근저에 깔린 사상이나 작동원리는 나도 모르거나 생략할 거라는..

또한 이 장난감은 1년쯤 전부터 해오던거라 지금의 트렌드와는 많이 다른 legacy 들이 많이 나오므로 진지한 개발자는 안 읽으시는것이 좋겠다. 실제로 좋은말을 들어본적이 없다.

차라리 개발을 전혀 모르는 사람이 보는것이 더 좋겠지않나..

AWS 에 가입하기

https://aws.amazon.com 열루 가서…
aws_join.png

개발자라면 AWS 계정이 없는것이 이상할정도로
거의 무제한 공짜(1년간 마이크로 인스턴스 무료. 그러나 메일계정만 있으면 계속 생성가능)
이지만 그래도 아직 가입하지 않았다면 가입하는것이 좋다.

가입중 신용카드 정보를 입력하는 부분이 등장한다. 외화결제가 가능해야 하므로 준비해놓아야 한다.
aws_join2.png

가입하고 tokyo 리젼 콘솔로 접근해서 ec 인스턴스를 생성하고 pem 파일을 다운로드 받아 놓는다. 이때 free tier eligible을 선택해야 공짜가 됨. 공짜 조건은 micro 급 ec 인스턴스 한개이므로 다른 스토리지, rds, 로드밸런서 따위를 선택해서도 안된다.

aws_main.png aws_ec_launch_create.png aws_ec_launch_ami.png aws_ec_launch_instance_type.png aws_ec_launch_tag.png aws_ec_launch_security.png aws_ec_launch_done.png

해당키로 ssh로 접근해보면 잘 된다. ㅎㅎ

스마트폰 용 ssh 클라이언트 다운받기

나는 https://serverauditor.com 라는 앱을 씀.

다운받고 설정을 해야한다.

server_auditor_menu.png server_auditor_add_key.png server_auditor_add_key_2.png server_auditor_add_key_3.png server_auditor_add_identity.png server_auditor_add_host.png server_auditor_done.png

잘된다. ㅎㅎ

필요한 환경 구축하기

먼저 zsh 를 설치하자.

1
2
3
4
5
sudo apt-get update
sudo apt-get install git
sudo apt-get install zsh
sudo curl -L http://install.ohmyz.sh | sh
sudo chsh -s $(which zsh) ubuntu

중간에 zsh 이 에러를 내는데 걍 쉘 변경하다 나는 에러니까 무시하고 다음 라인 입력하면 된다.

tmux 로 세션을 만들어 둔다. 이렇게 만든 세션은 항상 살려둔 채로 끄지 않을 예정이다.

C-b stmux세션을 선택할 수 있고 C-b $로 이름을 바꿀수 있다. clojure 정도로 이름을 바꾸자. 세션 하나를 더 추가하여 관리용으로 써도 좋다.

자바와 이맥스를 설치한다.

1
2
3
4
sudo add-apt-repository ppa:openjdk-r/ppa
sudo apt-get update
sudo apt-get install openjdk-8-jdk
sudo apt-get install emacs

lein 을 설치한다.

1
2
3
4
wget https://raw.githubusercontent.com/technomancy/leiningen/stable/bin/lein
sudo chmod 755 lein
./lein
cp lein ~/bin

$PATH 에 위치해야 하므로 .zshrc 파일을 편집하여 ~/bin$PATH에 포함되도록 한다.

https://melpa.org/#/getting-started 여기에 방문해서 제시하는 내용을 ~/.emacs.d/init.el 파일을 생성하고 붙여넣는다.

emacs를 실행하자.

M-xpackage-list-packages를 입력하여 필요한 패키지를 다운받는다.

  • clojure-mode
  • cider
  • auto-complete
  • ac-cider
  • golden-ratio

해당 패키지 로 커서를 옮겨서(C-p, C-n, C-v, M-v) i 키로 선택 x키를 눌러 설치한다.

init.el 파일에 ac-cider 관련 설정을 추가해준다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
(require 'ac-cider)
(add-hook 'cider-mode-hook 'ac-flyspell-workaround)
(add-hook 'cider-mode-hook 'ac-cider-setup)
(add-hook 'cider-repl-mode-hook 'ac-cider-setup)
(eval-after-load "auto-complete"
'(progn
(add-to-list 'ac-modes 'cider-mode)
(add-to-list 'ac-modes 'cider-repl-mode)))
(defun set-auto-complete-as-completion-at-point-function ()
(setq completion-at-point-functions '(auto-complete)))
(add-hook 'auto-complete-mode-hook 'set-auto-complete-as-completion-at-point-function)
(add-hook 'cider-mode-hook 'set-auto-complete-as-completion-at-point-function)