1월 052014
 

예전에 대학교에서 데이터베이스 수업을 들을 때 였다. 나는 이론과목을 좋아했기 때문에 데이터베이스 설계 수업도 재미있게 들을 수 있었다. 주어진 요구사항으로부터 어떤 과정을 통해서 실제 MySQL, OracleDB의 테이블, 릴레이션, 트리거, 프로시져, 인덱스 등등의 물리적인 설계까지 오게 되는지 보는 것은 매우 흥분되는 일이였다. 하지만 수업을 듣는 다른 사람들은 별 생각없이 수업을 듣고 있는 듯 하였으며 나는 그런 모습이 이해가 되지 않았다. 무언가를 만든다면 데이터가 매우 중요한 일인데 다른 학생들은 그렇게 생각하지 않는 듯 했다.

ER다이어그램에 대하여 배우고 나서 교수님께서 실제로 요구사항을 주고 다이어그램을 그려오라는 과제를 내주셨었다. 과제를 끝내고 쉬고 있는데 어떤 친구가 와서 과제 설명 좀 해주고 도와달라고 부탁을 하였다. 그런데 그 친구는 설명을 하고 나서 방향성을 제시해 주었는데 당황스럽게도 내 말을 들으려고 하지를 않았다. 오히려 자기말이 맞다는 것이었다.

Erd

직사각형은 개체, 마름모는 관계 그리고 빨강색은 맵핑 카디날리티

ER다이어그램은 Entity-Relationship Diagram(ERD)1의 줄임말으로써 개체와 관계를 통해서 데이터 모델링을 하기위한 도구이다. 이름에도 나와 있듯이 개체(물체, 대상, 명사 등을 의미)와 관계(2개이상의 엔티티 사이의 관계, 동사 등을 의미)를 이용한 모델링이다. 그런데 관계를 만듬에 있어서 엔티티와 엔티티 사이에서 서로 데이터가 어떻게 참여하고 있는지에 대한 것도 포함된다. 예를 들어 "반(班, class)"에 대한 데이터베이스를 만든다고 했을 때 이라는 엔티티와 학생이라는 엔티티가 존재하게 되며 학생과 교실간에는 속한다라는 관계를 맺게 된다. 마지막으로 1 개 반에 1곳에 대하여 여러명의 학생이 속할 수 있을 것이다. 위의 예제의 경우 반과 학생은 1:N의 관계를 가지고 있다. 이 1:N이라고 하는 것을 맵핑 카디날리티(Mapping Cardinality)라고 부른다. 맵핑 카디날리티가 표현되지 않은 ER 다이어그램은 그리다 만 것과 동일하다. ER 다이어그램으로 그려진 내용은 추후 논리적 모델로 변환하는 과정을 거치게 된다. 논리적 모델링은 우리가 잘 알고 있는 테이블을 이용하여 모델링을 하는 것을 말한다. 그렇게 변화하는 과정에서 맵핑 카디날리티는 중요한 역할을 수행한다. 관계를 테이블과 관계로 표현하기 위해서 어트리뷰트를 어떻게 할 것인지(1:N, 1:1), 엔티티 변환 과정에서 테이블을 합쳐야 하는지(1:1), 추가적으로 맵핑 테이블을 만들어야하는지(N:M)와 같은 것들이 결정된다. 관계에 맵핑 카디날리티를 적는 것이 얼마나 중요한지는 더 이상 말할 필요도 없을 것이다.

다시 돌아와서 그 친구이야기를 계속 해보면 그 친구는 맵핑카디날리티를 ER다이어그램의 관계에 적을 필요가 없다는 이야기였다. 필자는 충분히 맵핑카디날리티의 중요성을 말한 것 같다. 필자의 생각에 그 친구는 교수님의 말씀을 제대로 안들었을 것이다. 교수님께서 설명하실 때 분명히 관계를 표현할 때 관련된 엔티티를 각각 선으로 연결하고 맵핑 카디날리티를 적으라는 이야기를 하셨다. 그때 열심히 듣지도 않고 필자가 열심히 설명해주고 증거를 제시해도 자기가 맞다면서 시간을 빼앗은 것이다. 물론 내가 설명을 잘 못했을 수도 있다는 것을 알고 있기는 하다. 증거제시를 해도 듣지 않았다는 것은 변명거리도 없을 것 같다. 물론 결과적으로 그 친구는 과제 성적을 좋게 받지 못했다.

필자도 사람이기 때문에 틀릴 수 있으며 언제나 그 가정을 아래에 깔고 이야기를 한다. 어떤 지식이라도 내가 잘 못 생각하고 있다는 증거(물적 증거, 논리적 증거, 정황 증거, 다른 가능성 등)를 제시하면 얼마든지 인정할 수도 있다. 하지만 상대방에게 책에 나와있다는 증거를 제시하면서 설득을 했는데도 듣지를 않았다. 그 이후 말을 듣지 않을 것 같으면 내쪽에서 그냥 포기해 버린다. 자기가 무조건적으로 맞다는 사람들은 어떤 증거를 제출하더라도 들을 생각을 안한다는 생각을 가지게 되었기 때문이다. 이전에는 모든 사람들이 잘 못 생각하고 있는 것에 대해서 증거를 대고 따지고 바로 고치기 위해서 노력했지만 이제는 그런 무의미한 설득을 위한 시간 낭비가 불필요하다고 생각하게 된 것이다.

참고자료

  1. Wikipedia (Entity-Relationship model) ,http://en.wikipedia.org/wiki/Entity%E2%80%93relationship_model
1월 022014
 

현재 운영중인 jinukbaek.com 홈페이지는 블로그 페이지에 들어오기 위해 "jinukbaek.com/blog"까지 입력을 해야한다. 하지만 jinukbaek.com 도메인으로는 현재 블로그 밖에 운영하고 있지 않기 때문에 자동으로 이동(리다이렉션, Redirection)되게 해두었다. 하지만 문제는 Javascript로 이동하게 해두었다는 점에 있었다.

Redirection

Javascript와 301리다이렉션과 차이는 빨간색부분이지만 웹브라우져는 200의 경우 html코드를 실행을 해야하기 때문에 반응 속도는 좀 더 늦다.

웹 브라우져는 "http://jinukbaek.com"으로 접속을 먼저 하게 되면 서버는 특별한 설정을 하지 않았다는 전제하에 index.html을 찾아서 그림과 같이 "200 OK"라는 메시지와 index.html의 내용을 같이 보내게 된다. 이 파일을 웹 브라우져는 읽어 들여서 실행을 하게 된다. 요는 불러와서 자바스크립트를 따로 실행해야한다는 점에 있다. 비록 필자가 "jinukbaek.com/blog"로 이동하라는 코드를 넣어놨다 하더라도 웹 브라우져 입장에서는 html파일의 내용이 무엇일지 예측할 수 없기 때문에 일단 실행을 해야한다. 하지만 301과 같이 상태코드(300대의 상태 코드는 페이지 이동을 나타냄)를 이용해서 리다이렉션을 하기 때문에 딱히 내용을 확인하지 않아도 바로 이동하도록 하게 할 수 있다. 그래서 속도 향상과 검색봇이 크롤링1을 제대로 하게 된다. 제일 좋은 것은 "jinukbaek.com/blog" 주소를 블로그로 쓰지 않고 "jinukbaek.com"에 바로 블로그가 연결되도록 하는 것이 좋지만, 추후에 다른 서비스 확장도 고려하고 있는 필자의 입장에서는 어쩔 수 없는 선택이였다.

구글의 경우에는 자바스크립트까지 분석해서 크롤링하는지 모르겠지만 내용도 문제없이 검색이 되었었는데 네이버는 상황이 다른 듯 했다. 네이버 검색 신청을 하고 키워드로 검색해도 결과가 안나와서 "블로그 RSS 등록2" 을 찾아서 신청해야 했다. 다음의 경우에도 "블로그 RSS 등록3"을 통해서 검색이 되도록 하였다. 그렇게 검색이 안되는 문제를 해결하였다. 필자가 블로그 사이트를 만든지 시간이 꽤 지났기 때문에 Javascript를 통해서 리다이렉션을 했었는지 완전 잊고 있었다. 그런데 그렇게 했는지 다시 확인하게 된 것은 한 신문기사 때문이였다.

(9) JavaScript나 flash로 redirect 하지 말 것4

필자가 설마하고 확인을 해 보았더니 정말로 자바스크립트로 블로그페이지로 이동되게 되어 있었다. 봇이 자바스크립트까지 해석하지는 않을태니 당연히 크롤링이 안됬고 따라서 검색이 안되는 것이었다. 아마 "index.html" 파일 만들고 코드 몇 줄 입력하면 되기 때문에 그렇게 했을 것이다. 자바스크립트 리다이렉션은 서버 재시작이나 설정을 바꾼다거나 하는 작업 없이 아래 코드를 입력하면 된다.

<script>
	window.location = "/blog";
</script>

이참에 문제있는 부분도 수정할겸 아파치 서버 설정을 바꾸어 "http://jinukbaek.com"으로 접속하면 301 코드를 리턴하여 이동하도록 수정하였다. 수정한 환경설정 파일 경로는 "/etc/apache2/sites-enable/000-default.conf"이며 사용자 환경에 따라서 경로는 달라질 수도 있다. 수정은 환경설정 파일의 상황에 따라서 달라지는데 보통 VirtualHost 태그 사이에 넣으면 된다. 수정하고 나서 아파치 서버를 제시작(sudo service apache2 restart) 하는 것을 잊지 말자.

RedirectMatch 301 ^/$ /blog 
# RedirectMatch : 요청 주소가 해당하는 정규표현식을 만족할 경우 리다이렉션
# 301 : 리다이렉션시 http응답 코드
# ^/$ : 시작시 "/"로 시작하고 끝나는 문자열에 대해서. (즉 "/"로 요청이 왔을 때만)
# /blog : "/blog" 경로로 리다이렉션

리다이렉션시 웹브라우져가 자바스크립트 파싱하고 실행하는 상황이 생략되었기 때문에 초기 접속 속도가 약간 향상 되었으며 네이버에서 RSS내용 이외의 것도 검색이 되기 시작하였다. 이것으로써 서버운영하면서 있었던 문제 하나를 해결하였다.

참고자료

  1. 웹 크롤러, http://ko.wikipedia.org/wiki/%EC%9B%B9_%ED%81%AC%EB%A1%A4%EB%9F%AC
  2. 네이버 도움말, https://help.naver.com/ops/step2/mail.nhn?catg=547&upCatg=264
  3. 다음 검색 등록, https://register.search.daum.net/index.daum
  4. 한세희, "네이버 검색에 잘 걸리는 웹페이지 만들기 비법은?", 전자신문, 2013년 12월 20일
12월 312013
 

아래와 같은 에러를 내면서 “gem install rmagick”이 실패할 경우, 아래의 “checking for wand/MagickWand.h”를 주의깊게 보자. magickwand 라이브러리가 설치되어 있지 않기 때문에 발생하는 것이다.

root@wminserver:/home/redmine/redmine/redmine-2.4# gem install rmagick
Building native extensions.  This could take a while...
ERROR:  Error installing rmagick:
	ERROR: Failed to build gem native extension.

    /usr/local/rvm/rubies/ruby-2.1.0/bin/ruby extconf.rb
checking for Ruby version >= 1.8.5... yes
checking for gcc... yes
checking for Magick-config... yes
checking for ImageMagick version >= 6.4.9... yes
checking for HDRI disabled version of ImageMagick... yes
checking for stdint.h... yes
checking for sys/types.h... yes
checking for wand/MagickWand.h... no

Can't install RMagick 2.13.2. Can't find MagickWand.h.
*** 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=.
	--curdir
	--ruby=/usr/local/rvm/rubies/ruby-2.1.0/bin/ruby

extconf failed, exit code 1

Gem files will remain installed in /usr/local/rvm/gems/ruby-2.1.0/gems/rmagick-2.13.2 for inspection.
Results logged to /usr/local/rvm/gems/ruby-2.1.0/extensions/x86_64-linux/2.1.0/rmagick-2.13.2/gem_make.out

 

해결방법

libmagickwand-dev를 설치해 줌으로써 해결이 된다. 아래의 명령을 실행시켜보도록 하자.

$ sudo apt-get install libmagickwand-dev
$ gem install rmagick

문제없이 잘 설치 될 것이다.

Reference

[1] Stack Overflow(Can’t install RMagick 2.13.1. Can’t find MagickWand.h), http://stackoverflow.com/questions/9050419/cant-install-rmagick-2-13-1-cant-find-magickwand-h

12월 252013
 

필자는 인디밴드 들을 위한 온라인 공연 서비스인 인디크라우드 서비스를 만들었다. 이 서비스를 만들면서 팀원들과 여러가지 미디어 서버들을 고려해본 결과 당시에 가지고 있던 자금 등의 상황을 견주어 봤을 때 제일 적절한 솔루션이 Wowza Media Server라는 결론을 얻었었다. 우리는 실제로 서버를 구입하여 직접 테스트를 해보고 실제 공연을 해본 결과 문제 없이 잘 동작하는 것을 확인할 수 있었다. 하지만 문제는 실시간 공연이라는 점이였다. 지금부터 실시간 스트리밍 서비스를 만들기 위해서 어떤 고려사항이 있는지 알아보도록 한다.

실시간 방송(생방송)을 송출하고 PC, 스마트폰 할 것 없이 모든 디바이스에서 볼 수 있게 하기 위해서는 크게 두 가지 기술이 모든 디바이스에서 지원을 해야한다.

  1. 코덱1
    코덱

    코덱(Codec, Coder-Decoder)은 영상이나 음성을 일정한 형식에 맞게 변환하는 기술을 말한다. 동영상 서버, 방송 송출 장비, 방송 수신 장비 들이 모두 코덱을 지원할 수 있어야만 한다. 예를 들어서 영상 코덱에 H.263이라는 것이 있는데 방송 송출 장비와 방송 수신 장비는 지원하지만 수신장비(Ex:스마트폰)에서 지원을 하지 않으면 영상을 볼 수가 없게 된다. 또는 방송 송출 장비에서 H.263을 지원안하는데 다른 두 부분에서 지원을 한다면 이 또한 변환이 불가능하기 때문에 방송 송출이 불가능해 진다. 이렇게 코덱은 세 가지 부분에서 다 지원이 되는 것을 해야한다. 만약 안된다면 직접 구현하여 탑제해야 하는데 라이브러리가 없다면 최악의 경우 코덱을 구현해야할 수도 있다. 회사의 경우 코드 공개가 힘든 경우가 많은데 오픈 소스를 쓰기 어려워지기 때문에 비용이 증가한다. 그리고 경우에 따라서 사용자가 스마트폰 앱을 설치하거나 PC용 프로그램을 설치해야하는 부가 비용이 발생 할 수 있다. 그리고 코덱을 선택할 때 주의할 점은 코덱 자체(Ex: 특허비, 라이센스 비용)등이 발생할 수 있다

  2. 실시간 스트리밍 프로토콜2

    프로토콜

    실시간 스트리밍 프로토콜은 영상이나 음성을 인터넷을 통해 전송하기 위한 규약을 말한다. 스트리밍 프로토콜도 코덱과 마찬가지로 각각 시스템에서 지원이 되어야 한다. 예를들면 RTMP프로토콜의 경우 서버에서 지원을 하더라도 사용자가 보게 될 디바이스(스마트폰)에서 지원을 하지 않는다면 볼 수가 없다. 이도 코덱과 마찬가지 문제가 있다. 프로토콜을 사용하기 위한 라이센스 비용은 보통 없다. 하지만 지원하지 않는 장치에 대해서는 프로토콜을 따로 구현하고 앱을 설치 해야한다는 문제가 있다.

코덱과 프로토콜

방송 송출 디바이스부터 방송 수신 디바이스까지 영상/소리 데이터 흐름

위의 그림은 방송 송출 디바이스, 서버, 방송 수신 디바이스에서 고려해야할 것들을 항목별로 나누어 본 것이다.

동영상을 송출하는 측에서는 인코더(코덱)과 스트리밍 프로토콜이 필요하다. 실시간으로 획득한 영상과 소리 데이터는 인코더를 통하여 압축된다. 그리고 이 압축된 내용은 서버와 미리 약속한 프로토콜을 통하여 전송하게 된다.

서버의 디코더/인코더는 필요할 수도 있고 필요 없을 수도 있다. 만약 동영상을 수신하는 측에서 송출할 때 사용된 코덱이 지원하지 않는다면 지원하는 코덱으로 다시 인코딩을 하여야 한다. 이러한 역할을 하는 것을 트랜스코더(Transcoder)라고 부른다. 만약 필요가 없을 경우 바로 동영상을 수신하는 측으로 영상/소리 데이터를 클라이언트와 미리 약속된 프로토콜로 전달하게 된다.

클라이언트는 지원하는 프로토콜을 이용하여 압축된 영상/소리 데이터를 수신한다. 그리고 받은 데이터를 디코딩(압축을 품)하여 영상을 출력하고 소리를 재생하게 된다.

위의 그림을 통해서 우리가 선택한 Wowza Media Server에 어떤 장단점이 있는지 알아볼 것이다.

다음 포스팅에는 장치, OS, 라이브러리 별로 가능한 스트리밍 프로토콜과 코덱에 대해서 이야기를 해보고 Wowza Media Server에서 라이브 스트리밍을 할 때 어떤 문제와 어려움이 있는지에 대해서 설명해 보도록 하겠다.

  1. 위키백과- 코덱(Codec) , http://ko.wikipedia.org/wiki/코덱
  2. 위키백과 – 실시간 스트리밍 프로토콜, http://ko.wikipedia.org/wiki/실시간_스트리밍_프로토콜
12월 182013
 

BOINC0

지금으로 18개월 전 대학원 연구실에서 일을 하고 있을 때, 컴퓨터를 켜놓고 작업을 하는 일이 많았다. 논문을 읽기위해 인쇄를 하여 보고, 모르는 부분에 한하여 컴퓨터로 찾아보았기 때문이다. 그러다 보니 컴퓨터는 그냥 무심히 아무작업도 안하며 켜져있는 경우가 많았고, 이렇게 남아도는 컴퓨터 자원을 통하여 어떻게 세상에 도움이 될 수 없을까란 생각을 하게 되었다. 컴퓨터 분산컴퓨팅에 대한 논문을 읽으면서 봤던 BOINC라고 하는 시스템이 떠올랐다.

최초에 BOINC1는 SETI@HOME이라고 하는 외계생명체를 찾기 위한 프로젝트의 일부였다. BOINC는 자원봉사자들의 컴퓨터 자원(CPU, Memory, 그래픽카드 등)을 연구목적으로 이용하기 위한 프로젝트였다. 인터넷만 연결이 되어 있다면 컴퓨터로 계산해야하는 프로젝트의 일부를 자원봉사자의 컴퓨터로 전송하고 설정한 값(CPU 사용률 제한, 네트워크 제한, 작업시 실행 안함 등등)에 따라서 작업을 수행하고, 결과물을 프로젝트 서버에서 수거하는 것이었다. 사람들의 흥미를 끌기 위해서 Credit이라고 하는 봉사자의 자원을 사용한 양을 포인트로 돌려주고, 팀으로 뭉쳐서 활동을 할 수 있게 함으로써 선의적 경쟁을 유도하는 것이었다. 지금은 돈이 되지 않기 때문에 자원봉사자의 도움이 필요한 여러분야(수학, 물리학, 기상학, 의학 등등)의 프로젝트가 운영되고 있다.

자원봉사자들은 단지 컴퓨터에 BOINC 홈페이지에서 프로그램을 다운로드 받고, 어떤 프로젝트를 지원할 것인지 설정만 하면 된다. 다른 작업을 하고 있을 때 속도가 느려지는 것이 걱정이라면 설정에서 그 부분을 바꾸면 된다. 너무 부담을 가지고 시작할 필요는 없는 것이다. 대부분 듀얼CPU이상의 컴퓨터를 사용하면서 게임을 하지 않고 단순한 작업만 하는 것이라면 같이 실행시켜도 문제는 없다.

만약 자원봉사자로 참가한다면 얻을 수 있는 이득은 여러가지가 있는다. SETI@home 프로젝트의 경우 만약 외계생명체를 발견하게 된다면 이를 발견하는데 도움을 준 자원봉사자도 함께 이름이 남게 된다는 점이 참가하게 하는데 매우 고무적이다. Einstein@Home의 경우 링크와 같은 인증서를 발급해 주기도 한다.

어떠한 프로젝트에 참여할지 난감한 경우가 많은데 이것은 한국 위키2를 통해서 확인 가능하다. 필자의 경우는 “Einstein@Home”과 “NFC@Home” 그리고 “LHC@home 1.0″에 참여하고 있다. 꾸준히 한 결과 560,000크레딧을 모았고 지금도 계속 올라가고 있다. 딱히 보상이 없더라도 참여하고 있는 프로젝트에 도움이 되고 있다는 사실 만으로도 충분히 지원할 이유가 된다고 생각한다. 프로젝트 참여 방법은 아래의 링크를 참여하면 된다.

참고링크

(1) SETIKAH@KOREA(한국 SETI팀) , http://cafe.naver.com/setikah)
(2) SETI 프로젝트 참여 방법, ( http://goo.gl/AKntP )


  1. BOINC ( Berkeley Open Infrastructure for Network Computing ),http://boinc.berkeley.edu/
  2. Wikipedia (SETI@home),http://ko.wikipedia.org/wiki/SETI@home
12월 162013
 

루비(Ruby)언어 정리

소스코드를 통하여 주요한 기능만 확인해보고 넘어간다.

클래스와 객체

class Car
    @@run_car = 0  # 클래스 변수 / static 변수

    attr_reader :pos    # 읽기 전용 속성(attribute)
    attr_writer :pos    # 쓰기 전용 속성
    attr_accessor :light # 읽기/쓰기 가능 속성

    def initialize(color) # 생성자
        @color = color  # @는 멤버변수 없는 것은 지역변수
    end

    def get_color
        return @color
    end

    def get_run_car
        return @@run_car
    end

    def Car.run(num)  # 클래스 메소드 | static 함수
        @@run_car += num
    end

    def id_car()  # id_car값 반환 접근자 메소드
        @id_car
    end

    def id_car=(id_car)  # pos값 쓰기 접근자 메소드
        @id_car = id_car
    end

protected # 메소드 공개 범위 (JAVA와 같음)
    def alaram
    end

private # 메소드 공개 범위 (JAVA와 같음)
    def check 
    end
end

class SuperCar < Car   # 상속
   def initialize(color)
       super(color)  # 부모 생성자 호출
   end

   def get_color
       return "red"
   end
end

supercar = SuperCar.new("blue") # 인스턴스 생성
Car.run(100) # 클래스 메소드 호출 

모듈

module Computer
    def Computer.buy(com)
        puts com + " buy"
    end

    class CPU
        def CPU.run
            puts cpu + " run"
        end
    end
end

include "computer.pb" # 외부 루비 파일 입포트
Computer.buy "Alpha"
Computer::CPU.run   # module의 class는 ::을 이용하여 접근한다.

모듈 혼합

module LeftClick
    def lclick
        puts "Left Clicked"
    end
end

module RightClick
    def rclick
        puts "Right Clicked"
    end
end 

class Mouse
    include LeftClick
    include RightClick
end

mouse = Mouse.new() # Mouse는 LeftClick, RightClick 2가지 기능이 혼합된다. (다중상속), Module은 인스턴스 생성이 불가하나 Mouse는 class이므로 가능
12월 162013
 

루비(Ruby)언어 정리

조건문

if

if Boolean [then | :]
   code1
[elsif Boolean [then | :]
   code
]...
[else
   code ]
end
  • Boolean : 식의 Return 값이 Boolean형인 결과 값
  • code1 : 조건(Boolean)이 참일 경우 실행
  • elsif : elseif 가 아니고 elsif인 것에 주의할 것

unless

if문과 반대로 작동함

unless Boolean [then | :]
   code1
[else
   code ]
end
  • Boolean : 식의 Return 값이 Boolean형인 결과 값
  • code1 : 조건(Boolean)이 거짓일 경우 실행

if/unless를 수식어 형태로 사용

puts "true" if res > 100 : 100보다 클 경우 true를 출력

puts "false" if new <= 100 : 100 이하일 경우 false를 출력

case 문

case value
when expression [, comparision]... [then | :]
   code
when expression [, comparision]... [then | :]
   code
.
.
.
[else
    code]
end

조건에 알맞는 value값에 대해 when의 조건에 맞는 것을 실행함

goal = 100
case goal
when 95..100
    puts "A+"
when 90...95
    puts "A"
when 85...90
    puts "B+"
when 80...85
    puts "B"
when 75...80
    puts "C+"
when 70...75
    puts "C"
else
    puts "F"
end

위와 같은 형식으로 Range와 함께 사용 가능

? 연산자

condition ? true : false 형식으로 이용.

예제: res = r >= 70 ? "pass" : "fail"

순환문

while

while condition [ do | : ]
   code
end 

condition의 조건이 참일 경우에만 실행

until

until condition [ do | : ]
    code
end

condition의 조건을 만족할 때 까지 실행

while/until의 수식어 형태 사용

value += 10 until value == 100

value += 1 while value < 100

for

for variable [, variable]... in collection [do | :]
    code
end

collection을 차례대로 variable에 넣으면서 code를 실행한다.

  • 예제 1
for value in 1..10
   data += value
end
  • 예제 2
for data in ["I", "love", "you"]
   puts data
end

Ruby Iterator

collection do |variable|
   code
end

collection의 내용을 variable에 하나씩 넣으면서 code를 실행. 아래는 이를 사용한 예제.

data = ["Hello", "World", "!!"]
res = ""

0.upto(grades.length - 1) do |loop_index|
    res = data[loop_index] + " "
end

puts res
  • 0.upto(n) : 0부터 n까지 순환문을 만듬
  • 10.downto(0) : 10부터 0까지 값을 감소시키며 순환
  • 2.step(11, 3) : 11까지 2부터 3씩 증가시키는 순환문 작성(예 : 2, 5, 8, 11)
  • 5.times : 5회 반복
  • data.each : data가 컬렉션이면 모든 항목들을 순서대로 가져옴
  • loop : 무한 루프 (break문을 통해서 반복문 탈출)

반복문에서 사용할 수 있는 구문

  • break : 반복문을 탈출
  • redo : 반복문의 현재 단계를 한 번 더 실행
  • next : 다음 단계를 실행함 (C++/JAVA++의 continue와 같음)
  • retry : 반복문을 처음부터 다시 시작

메소드 정의

hello란 이름의 메소드 정의

def hello
   puts "Hello World!!"
end

사용 방법은 hello라고 하는 것 만으로 가능

  • 메개변수 전달방법
def hello(name)
   puts "Hello World!!, " + name
end

hello "Gildong"
  • 가변 개수
def hello(data, *others)
    puts data + "!! Hello World!! " + others.join(", ")
end

hello "Ruby", "Gildong", "Gilsoon", "Cheolsoo"

Ruby에서 *는 배열이라는 뜻임. 파라미터를 넘길 경우에도 사용 가능

  • 메소드 값을 리턴
def sum(a, b)
    return a + b
end
  • 2개 이상의 값 리턴
def sum_minus(a, b)
    return a+b, a-b
end
arr = sum_minus(30, 20)   # 배열 형태
s, m = sum_minus(30, 20)  # 각각 리턴값이 s, m으로 리턴
  • 변수의 유효 범위

동일 이름일 경우에 매소드 내부가 최우선

  • 블록 (block)

메소드에 파라미터(Parameter)처럼 전달될 수 있는 코드를 말함, {}를 이용하여 작성

{ puts "Hello World!!" }

또는

do
   puts "Hello World!!" 
end

형태로 작성 가능함

yield문을 이용하여 블록을 실행할 수 있다.

def hello
    yield
end

hello { puts "Hello World!!" }
  • 블록에 데이터 전달
def hello
   yield "Ruby", "Gildong"
end

hello { |word1, word2| puts word1 + " Hello World!! " + word2 }

||안에 있는 변수에 차례대로 데이터가 전달된다.

  • 반복자와 함께 블록 사용
["Hello", "World", "!!"].each {|word| puts word}
4.times {puts "!"}
  • BEGIN/END 블록
BEGIN {puts "Hi "}

puts "Hello World!"

END { puts "Bye!" }

Ruby 프로그램이 메모리에 올라갈 때 BEGIN 블록이 실행 되며 종료 될 때 END 블록이 실행된다.

12월 152013
 

숫자를 쓰는 몇가지 방법

  • 3.14
  • 31415.9e-4
  • 123456789
  • 12_345_678_910
  • 0x3D3A

문자열 (아래는 같은 문자열임)

  • “Hello World”
  • ‘Hello World’
  • %q!Hello World!
  • %Q!Hello World!
  • %q/Hello World/
  • %{Hello World}

HERE 문서 기능

print << HERE
Hello 
World 
!!
HERE`

1번째 줄의 HERE부터 마지막줄 HERE까지 하나의 문자열로 봄
즉 자동으로 개행문자를 붙여 줌

상수/변수

  • 대문자 Only : 상수
  • 그 이외 : 변수

큰따옴표 문자열 안에 변수 값 삽입

puts "My name is #{name}." #{}를 이용하여 해결한다.

간단한 입출력 예제

print please enter your name: 
gets
chomp
puts "Your name is #{$_}."
  1. gets$_에 키보드로 입력한 문자열을 저장한다.
  2. chomp$_ 뒤에 개행 문자를 제거한다.
  3. #{$_}를 입력받은 결과물을 출력한다.

심볼

C언어 enum에서 쓰는 값과 유사한 것이다. :data와 같은 형식으로 이용한다.

C언어와 다른 연산자

  • ** : Exponential(누승)
  • <=> : 작으면 음수, 같으면 0, 크면 양수 반환
  • == : 같다
  • === : case문의 when절에서 사용하는 동치 연산자
  • =~ : 정규 표현식 패턴 검사 연산자
  • defined? : 어떤 심볼이 정의되어 있으면 참
  • begin, end : 블록 표현식
  • if, unless, while, until : 실행문

배열 첨자 차이

array\[start, count] : 리턴값은 start부터 갯수 만큼의 원소를 가져온다.

해 쉬

res = {"first" => "Gildong", "last" => "Hong"} : 형식으로 사용

res["first"] : res에서 first라는 값을 가져온다

범 위(range)

1..4 : 1, 2, 3, 4

1...4 : 1, 2, 3

배열 변환

.to_a 라는 메소드를 이용

  • (1..4).to_a : [1,2,3,4]
  • (1...3).to_a : [1,2,3]

오름차순을 이용해야 배열로 변환 가능

12월 132013
 

윈도우에서 mysql2 ruby gem이 아래와 유사한 이유로 설치가 안되는 경우 해결방법. (rails4, ruby2 에서 확인)

Building native extensions. This could take a while…
ERROR: Error installing mysql2:
ERROR: Failed to build gem native extension.C:/Ruby200-x64/bin/ruby.exe extconf.rb
checking for ruby/thread.h… yes
checking for rb_thread_call_without_gvl() in ruby/thread.h… yes
checking for rb_thread_blocking_region()… yes
checking for rb_wait_for_single_fd()… yes
checking for rb_hash_dup()… yes
checking for rb_intern3()… yes
checking for mysql_query() in -lmysqlclient… no
checking for main() in -lm… yes
checking for mysql_query() in -lmysqlclient… no
checking for main() in -lz… no
checking for mysql_query() in -lmysqlclient… no
checking for main() in -lsocket… no
checking for mysql_query() in -lmysqlclient… no
checking for main() in -lnsl… no
checking for mysql_query() in -lmysqlclient… no
checking for main() in -lmygcc… no
checking for mysql_query() in -lmysqlclient… no
*** 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=.
–curdir
–ruby=C:/Ruby200-x64/bin/ruby
–with-mysql-dir
–without-mysql-dir
–with-mysql-include
–without-mysql-include=${mysql-dir}/include
–with-mysql-lib
–without-mysql-lib=${mysql-dir}/
–with-mysql-config
–without-mysql-config
–with-mysql-dir
–without-mysql-dir
–with-mysql-include
–without-mysql-include=${mysql-dir}/include
–with-mysql-lib
–without-mysql-lib=${mysql-dir}/
–with-mysqlclientlib
–without-mysqlclientlib
–with-mlib
–without-mlib
–with-mysqlclientlib
–without-mysqlclientlib
–with-zlib
–without-zlib
–with-mysqlclientlib
–without-mysqlclientlib
–with-socketlib
–without-socketlib
–with-mysqlclientlib
–without-mysqlclientlib
–with-nsllib
–without-nsllib
–with-mysqlclientlib
–without-mysqlclientlib
–with-mygcclib
–without-mygcclib
–with-mysqlclientlib
–without-mysqlclientlib
Gem files will remain installed in C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/mysql2-0.3.14 for inspection.
Results logged to C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/mysql2-0.3.14/ext/mysql2/gem_make.out

 

 1. 이 유


1. mysqlclient 또는 mysql connector가 설치되어 있지 않기 때문

2. mysql connector가 설치되어 있다 하더라도 경로 지정이 안되있는 경우

 

2. 해결방법


1) mysql c connector를 설치한다. [http://dev.mysql.com/downloads/connector/c/] (설치되어 있는 경우 생략)

2) 아래와 같은 방법으로 설치한다. 굵은 글씨 부분은 mysql connector가 설치된 환경에 맞게 수정한다.

C:\>gem install mysql2 –platform=ruby — ‘–with-mysql-lib=”C:\Program Files\MySQL\MySQL Connector C 6.1\lib” –with-mysql-include=”C:\Program Files\MySQL\MySQL Connector C 6.1\include”‘

 

Reference

[1] http://stackoverflow.com/questions/5836959/cant-install-mysql2-for-rails-3-on-windows

12월 032013
 

OSX에는 알프레드(http://www.alfredapp.com/)라는 앱이 있습니다. 이 앱은 쉽게 키보드로 여러 기능을 빠르게 실행할 수 있게 해줍니다. 기본적인 기능은 무료 버전을 다운로드 받으시면 됩니다. 하지만 Alfred에 기능(워크플로우)을 추가할 수 있는 기능은 따로 파워팩을 구매해야만 합니다.

이 앱을 사용하다 보니 네이버 검색이나, 사전에서 같은 것을 쉽게 쓸 수 있었으면 좋을 것 같다는 생각을 하게 되었습니다. 기존에 자동완성은 되지 않지만 브라우져 창을 열어 주는 것은 기존에 있었습니다. 저는 자동완성도 되길 원했기 때문에 간단히 만들어 보았습니다. 그리고 작성한 코드는 github에(https://github.com/Kuniz/alfnaversearch) 공개하였습니다.  아래 링크에서 다운 받으면 됩니다.

다운로드 

사용하면서 버그나 추가적으로 필요하신 기능같은게 있다면 댓글을 달아주세요. 가능한 범위 내에서 적용하도록 하겠습니다.

[수정 2014-04-18 01:32+0900] shasing님, 이재호님께서 제보해주신 부분 중 자동완성 후 브라우져 작동시 잘 못되는 문제 해결하였습니다.
[수정 2014-04-18 01:38+0900] shasing님께서 말씀하신 일본어 한자 자동완성 기능도 추가하였습니다.
[수정 2014-04-22 01:32+0900] shasing님께서 말씀하신 일본어 자동완성 버그 수정하였습니다.
[수정 2014-05-18 18:26+0900] 1. 국빵님께서 요청하신 중국어 자동완성 기능 넣었습니다.  2. 라이브러리 성능을 개선하였습니다. 기존에 쓰시던 분들도 다시 받아주세요 ㅎㅎ 3. 중국어 자동완성에 있어서 한글로 입력을 했을 때 한글로만 나오는건 네이버 중국어 사전 자동완성 기능이 그 부분만 제공하기 때문입니다 ㅠㅠ
[수정 2014-07-23 12:07+0900] 독일어, 한자사전 추가됬습니다.
[수정 2014-11-08 16:36+0900] 프랑스어 추가 및 링크 깨진 것 수정 하였습니다.
[수정 2016-07-02 01:26+0900] norux님이 워크플로우에 한글 디렉토리명이 있는 경우에 대한 버그 수정 기여해주셨습니다~ 감사합니다.  버그 수정한 버전 업로드 되어 있습니다!
[수정 2016-10-01 01:09+0900] 이탈리아어 사전 추가했습니다.
[수정 2016-10-15 22:30+0900] 러시아어, 스페인어, 태국어, 베트남어 사전 추가했습니다.
[수정 2016-12-11 15:07+0900] 러시아어, 스페인어, 태국어, 베트남어 사전 추가했습니다.
[수정 2016-01-01 16:05+0900] 중국어 사전 자동완성 결과 개선
[수정 2017-07-25 03:45+0900] 연관 프레임워크 업데이트 (시에라 백그라운드 버그 해결)

[수정 2017-12-14 02:06+0900] 독일어사전 API주소 변경

[수정 2021-01-01 12:38+0900] 네이버 자동완성 API주소 변경
[수정 2021-08-23 01:15+0900] 24개 언어 추가 및 일본어 사전 자동완성 주소 변경

[수정 2021-10-20 12:00+0900] 네이버 쇼핑 자동완성 적용

[수정 2022-01-04 01:50+0900] 각종 버그 수정 및 macos 등 지원 강화

[수정 2022-01-28 01:17+0900] na명령 버그 수정 및 영영사전 추가

[수정 2022-02-09 01:53+0900] python2/3 지원. @kw-lee 님 감사합니다 🙂 -> macOS 12.3에서 안될시 python3 설치 후 다운받아주세요.
 

[수정 2022-04-06 01:22+0900] 자동완성의 상세내용을 cmd+C 로 클립보드 복사되도록 기능 추가

사용방법


 na 명령 : 네이버 일반 검색을 수행합니다.

2013-12-03_20-36-02

ns 명령 : 네이버 쇼핑 검색을 수행합니다.

nae 명령 : 네이버 영어사전 검색을 수행합니다.

영어로 입력시 한글 단어가 나오며, 한글로 입력시 영어 단어가 나옵니다.

2013-12-03_20-36-35

2013-12-03_20-36-56

 

naj 명령: 네이버에서 일어사전 검색을 합니다.

로마자 입력 검색시 일문, 일어 검색시 한국어, 한국어 검색시 일어 단어가 출력됩니다.

2013-12-03_20-37-57

2013-12-03_20-37-24

2013-12-03_20-37-10

 

* `nak ...` : Naver Korean Dictionary (국어 사전)
* `nae ...` : Naver Korean-English Dictionary (영어 사전)
* `naee ...` : Naver English-English Dictionary (영어 사전)
* `naj ...` : Naver Korean-Japanese Dictionary (일본어 사전)
* `nac ...` : Naver Korean-Chinese Dictionary (중국어 사전)
* `nah ...` : Naver Hanja Dictionary (한자 사전)
* `nad ...` : Naver Korean-German Dictionary (독일어 사전)
* `naf ...` : Naver Korean-French Dictionary (프랑스어 사전)
* `nai ...` : Naver Korean-Italian Dictionary (이탈리아어 사전)
* `nar ...` : Naver Korean-Russian Dictionary (러시아어 사전)
* `nas ...` : Naver Korean-Spanish Dictionary (스페인어 사전)
* `nat ...` : Naver Korean-Thai Dictionary (태국어 사전)
* `nav ...` : Naver Korean-Vietnamese Dictionary (베트남어 사전)
* `nan ...` : Naver Korean-Indonesian Dictionary (인도네시아어 사전)
* `nau ...` : Naver Korean-Uzbekistan Dictionary (우즈베키스탄어 사전)
* `nane ...` : Naver Korean-Nepali Dictionary (네팔어 사전)
* `namn ...` : Naver Korean-Mongolian Dictionary (몽골어 사전)
* `namy ...` : Naver Korean-Burmese Dictionary (미안마어 사전)
* `nasw ...` : Naver Korean-Swahili Dictionary (스와힐리어 사전)
* `naar ...` : Naver Korean-Aramaic Dictionary (아랍어 사전)
* `nakm ...` : Naver Korean-Cambodian Dictionary (캄보디아어 사전)
* `nafa ...` : Naver Korean-Persian Dictionary (페르시아어 사전)
* `nahi ...` : Naver Korean-Hindi Dictionary (힌디어 사전)
* `nanl ...` : Naver Korean-Dutch Dictionary (네덜란드어 사전)
* `nasv ...` : Naver Korean-Swedish Dictionary (스웨덴어 사전)
* `nauk ...` : Naver Korean-Ukrainian Dictionary (우크라이나어 사전)
* `naka ...` : Naver Korean-Gruziya Dictionary (조지아어 사전)
* `nacs ...` : Naver Korean-Czech Dictionary (체코어 사전)
* `nahr ...` : Naver Korean-Croatian Dictionary (크로아티아어 사전)
* `natr ...` : Naver Korean-Turkish Dictionary (터키어 사전)
* `napt ...` : Naver Korean-Portuguese Dictionary (포르투갈어 사전)
* `napl ...` : Naver Korean-Polish Dictionary (폴란드어 사전)
* `nafi ...` : Naver Korean-Finnish Dictionary (핀란드어 사전)
* `nahu ...` : Naver Korean-Hungarian Dictionary (헝가리어 사전)
* `nasq ...` : Naver Korean-Albanian Dictionary (알바니아어 사전)
* `naro ...` : Naver Korean-Rumanian Dictionary (루마니아어 사전)
* `nala ...` : Naver Korean-Latin Dictionary (라틴어 사전)
* `nael ...` : Naver Korean-Greek Dictionary (그리스어 사전)