라인 원정대

라인 원정대
http://tech.naver.jp/blog/?p=2852

요약
– 2011년 6월에 서비스를 시작해서 현재 4억명의 유저가 사용하는 메신저가 됐다.
– 2012년 12월 스페인에서는 왓츠앱의 유료화에 반발해서 많은 유저가 라인을 선택함으로써 짧은 기간에 유저가 급증. 그러나 메세지 지연, 푸쉬 연착, 밧데리 소모 문제등이 발생! 개발자 3인을 긴급 출장을 보내서 현지에서 문제를 분석. 의미있는 분석결과의 반영을 2013년 4월에 적용.
– 스페인 출장을 통해 유저의 입장에서 서비스 개선점을 찾는 노력을 계속, 그래서 동남 아시아, 중남미, 호주, 중동, 미국, 러시아등등 개발자가 직접 방문해서 현지에서 심카드를 구매해서, 거리, 호텔, 지하철, 데파트의 지하 깊숙한곳, 레스토랑등에서 테스트함. 이런 출장 멤버를 [라인원정대]라고 부르게 됨.

라인 원정대
– 클라개발, 서버개발, 인프라개발자등으로 2-6인으로 구성
– 출장기간은 국가의 크기에 다르지만, 3-5일 정도 체류
– 국가특유의 네트워크특성이나, 인터넷품질, 배포전 실제환경에서 문제없는가 테스트
– 현지의 사람에게 의견을 듣기도함.
– 비행기내 와이파이에서도 라인이 된다고함?!

라인 글로벌 인프라스트럭쳐
– 유저와 서버간의 레이턴시를 줄이기위해 세계 각지에 POP(자사 IDC를 의미하는 듯)를 설치.
– 클라에서는 가까운 POP를 선택하도록되어 있음
– 인터넷 환경의 변화에 대응하기위해, (유저가 사용하는 버젼같은)다양한 환경에 대해 다른 설정을 배포할 수 있는 기능을 적용함. 다양한 통신 프로토콜 적용. 다양한 파일 다운로드 방식 적용 등..

앱리뷰
– 유저의 리뷰를 국가/언어/버젼/키워드별 어플리케이션 리뷰수와 스코어를 분석가능하게함.

라인 성능 인덱스
– 라인의 기업문화의 한가지는 ‘숫자’로 보고 판단하는 것. 라인의 품질, 개선방법의 결정. 업데이트를 통한 결과의 확인을 전부 ‘숫자’로 측정 & 개선.
– Analytics를 위한 Big data분석을 위해 Hadoop을 사용중.

Erlang 정리 2(쉘명령어)

[markdown]
### 쉘 명령어

[여기](http://learnyousomeerlang.com/starting-out) 링크를 요약 한 글임을 밝혀드립니다.

– Emacs를 베이스로한 라인에디터를 내장하고 있음. (Emacs를 몰라도 됨)
– `Ctrl + A`를 누르면 커서가 라인의 가장 앞으로 이동함.
– `Ctrl + E`를 누르면 커서가 라인의 가장 끝으로 이동함.
– `li`를 누르고 `tab`을 누르면 `lists:`이런식으로 자동완성 됨.

들어오긴 했는데, 끄는법을 모를 때

`help().` 를 누르면 명령어가 쫘악 나옴. 여기서 `.` 점을 꼭 찍어야됨.

`help().`를 실행 후 나오는 것 중에 보면

아래와 같은 게 보이는데
“`
q() — quit – shorthand for init:stop()
“`

`q().`를 실행하면 쉘이 종료됨

쉘을 잠깐 멈추고 싶은 경우는 `ctrl + G`를 누르면 유저스위치 커맨드 라는 게 보이는데

“`
User switch command
–>
“`

여기서 `h`를 누르면 몇가지 명령어가 나옴. 쉘 안에서 멈추고 다른 걸 실행가능

“`
User switch command
–> h
c [nn] – connect to job
i [nn] – interrupt job
k [nn] – kill job
j – list all jobs
s [shell] – start local shell
r [node [shell]] – start remote shell
q – quit erlang
? | h – this message
“`

종료는 `ctrl + G` 후 `q`로 종료가능
[/markdown]

Erlang 정리1 (erlang 이란?)

[markdown]

“`
node코드를 리팩토링 해야하는데, 하기 싫고 귀찮아서 erlang을 잠깐 봄.
명언이 생각난다.
“`

> 개발자는 자기가 흥미가 가는 것을 열심히하는 직업병이 있다.

# Erlang 정리1 (erlang 이란?)

> [http://learnyousomeerlang.com/introduction#about-this-tutorial](http://learnyousomeerlang.com/introduction#about-this-tutorial)

> 위 링크를 참고, 요약 한 것임을 밝혀 드립니다.

– functional 프로그램이다
– 참조의 투명성 (referential transparency)
– 변경가능한 데이터를 못씀 (avoiding mutable data)
– 코드는 바이트코드로 변환되고, 가상머신위에서 돌아간다.
– 표준배포판
– 개발툴(컴파일러, 디버거, 프로파일러, 테트트 프레임웤)
– OTP(Open Telecom Platform) 프레임웤
– 웹서버
– 파서 생성기
– mnesia 데이터베이스
– key-value 스토리지 시스템(복제기능, 트랜젝션, 어떤 erlang데이터도 저장가능)을 포함한다.
– actor를 강제로 쓰게 만든다.
– message로만 응답한다.
– 경량프로세스이다. (가벼우니 많이 만들수는 있지만 그게 좋은건 당연히 아니다.)
– 시계열 프로세싱이나, 운영체제의 시스템 드라이버를 만드는데는 안좋다.
– 큰규모의 서버(Queue, map-reduce)나, 고수준 프로토콜의 구현등에는 좋다.

## erlang에 뛰어들려면 무엇이 필요한가?

– 텍스트 에디터 + Erlang 실행환경 (공식사이트에서 받자 http://erlang.org/download.html)

### 리눅스환경에서 설치하기

“`
### mac
$ brew install erlang

### ubuntu
$ apt-get install erlang

### centos
$ yum install erlang

### 위의 3가지 방법으로 안 될 경우는 컴파일 설치!
### 컴파일 설치하려면 GNU make, gcc, Perl5, GNU m4, ncurses,
### termcap, termlib, OpenSSL, Sun Java jdk-1.5 이상, sed등이 필요.
### 위의 것들은 알아서 설치하시길..

### configure 설정에 –prefix= 설정을 하면 설치경로 지정가능
### 없으면 /usr/local/{bin,lib/erlang}에 기본적으로 설치됨.

$ curl -O http://www.erlang.org/download/otp_src_R16B03-1.tar.gz
$ tar xvzf otp_src_R16B03-1.tar.gz
$ cd otp_src_R16B03-1
$ LANG=C; export LANG
$ ./configure
$ make #오래걸림
$ make install
“`

## 도움얻기

“`
# man page
$ erl -man lists
“`

#### 웹 문서

공식 사이트 : [http://erlang.org/doc/](http://erlang.org/doc/)

공식 사이트 대신(디자인이 쫌 더 이쁨) : [http://erldocs.com/](http://erldocs.com/)

코딩 룰 : [http://www.erlang.se/doc/programming_rules.shtml](http://www.erlang.se/doc/programming_rules.shtml)

메일링리스트 : [http://www.erlang.org/static/doc/mailinglist.html](http://www.erlang.org/static/doc/mailinglist.html)

쿡북이나 레시피 좋아하는 사람은 여기를 : [https://erlangcentral.org/wiki/index.php?title=Main_Page](https://erlangcentral.org/wiki/index.php?title=Main_Page)

#### erlang shell 실행해보기

아래와 같이 실행하면
“`
$ erl
“`

요런식으로 나옴
“`
Erlang R16B03-1 (erts-5.10.4) [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false]

Eshell V5.10.4 (abort with ^G)
1>
“`

[/markdown]

javascript strict mode 정리

[markdown]
# javascript strict mode

strict모드를 jslint를 사용하게 되면서 사용하고 있는데, 이게 뭔지 모르는 채로 그냥 사용하는 것은 뭔가 찜찜했기에,찾아서 정리함.

strict모드는 파일, 프로그램 또는 함수의 시작 부분에 `”use strict”;`를 추가하여 strict모드를 추가 할 수 있다.

### strict모드의 제한

– Strict모드에서 변수를 선언하지않고 사용할 수 없다.
– 읽기 전용 속성에 값을 할당할 수 없다.
– extensible특성이 false로 설정된 객체에 속성을 추가할 수 없다.
– configurable특성이 false로 설정된 속성을 삭제할 수 없다.
– 객체에 같은 이름의 속성을 두번이상 정의 하지 못한다.
– 함수에서 파라메터명에 같은 이름을 두번 이상 사용하지 못한다.
– implements, interface, package, private, protected, public, static, yield 등과 같은 예약어를 변수 또는 함수 이름으로 사용 할 수 없다.
– 숫자 리터럴에 8진수 값을 할당하거나 8진수 값에 이스케이프를 사용할 수 없다.
– this의 값이 null또는 undefined인 경우 전역 객체로 바뀌지 않음.
– 문자열 “eval”, “arguments” 식별자(함수, 변수, 매개변수 명)으로 사용 할 수 없다.
– 함수선언을 statement나 함수 블록내에서 중첩해서 할 수 없다.
– 변수가 eval함수내에서 선언 되는 경우 해당 함수 밖에서 사용할 수 없다.
– 로컬 arguments 객체의 값을 변경할 수 없다.
– arguments.callee를 허용하지 않음
– with문을 허용하지 않음
[/markdown]

Chef 서버 설치하고 테스트해보기

Chef 서버 설치하고 테스트해보기

vagrant + virtualbox로 5대의 멀티 인스턴스 올리기

Chef 서버의 환경을 이해해 보려면 3개이상 가상머신을 설치해서 해보는게 좋다.
Vagrant로 5대의 가상머신을 올려보자.
Vagrant를 설치하고 VagrantFile에 아래와 같이 설정한 후

vagrant up을 실행하면 된다.

vagrant 사용법은 아래의 링크를 참고 하자.

Chef의 테스트 환경을 만드는데 매우 적합한 툴 – Vagrant (http://gyus.me/?p=326)

 

VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.define :chef_server do |cfg|
cfg.vm.box = "base"
cfg.vm.network :private_network, ip: "192.168.30.10"
cfg.vm.host_name = "chef-server"
end
config.vm.define :workstation do |cfg|
cfg.vm.box = "base"
cfg.vm.network :private_network, ip: "192.168.30.20"
cfg.vm.host_name = "workstation"
end
config.vm.define :node01 do |cfg|
cfg.vm.box = "base"
cfg.vm.network :private_network, ip: "192.168.30.21"
cfg.vm.host_name = "node01"
end
config.vm.define :node02 do |cfg|
cfg.vm.box = "base"
cfg.vm.network :private_network, ip: "192.168.30.22"
cfg.vm.host_name = "node02"
end
config.vm.define :node03 do |cfg|
cfg.vm.box = "base"
cfg.vm.network :private_network, ip: "192.168.30.23"
cfg.vm.host_name = "node03"
end
end

 

chef server 설치

아래 사이트에서 패키지를 다운 받아서 설치

http://www.getchef.com/chef/install/

[code lang=text]
wget https://opscode-omnitruck-release.s3.amazonaws.com/ubuntu/12.04/x86_64/chef-server_11.0.6-1.ubuntu.12.04_amd64.deb
[/code]

[code lang=text]
sudo dpkg -i chef-server.deb
[/code]

설치 완료후 chef-server-ctl로 Chef Server를 설정함

[code lang=text]
sudo chef-server-ctl reconfigure
[/code]

위 커맨드를 실행하면 서버를 기동시키고, nginx가 HTTPS 443포트를 바인드한다.

Chef의 각종 파일은 /opt 디렉토리에 인스톨된다.

knife 설정

[code lang=text]
knife configure
[/code]

실행하면 아래와 같은 설정 항목들이 나옴 걍 엔터.

[code lang=text]
Where should I put the config file? [/home/vagrant/.chef/knife.rb]
Please enter the chef server URL: [https://chef-server:443]
Please enter an existing username or clientname for the API: [vagrant]
Please enter the validation clientname: [chef-validator]
Please enter the location of the validation key: [/etc/chef-server/chef-validator.pem]
Please enter the path to a chef repository (or leave blank):
[/code]

임의의 클라이언트가 처음 Chef Server와 통신을 할경우, 디지털서명이 없기 때문에,
최초 한번, chef-validator라는 Client등록작업만을 전문으로 하는 클라이언트 에서 인증서를 빌려서 Chef Client의 등록작업을 하게됨. 이 작업이 완료되면 이후는 클라이언트 쪽에서 작성한 디지털서명에 의해 통신이 이루어지도록 된다.

dep패키지로 Chef Server를 설치하면 /etc/chef-server 디렉토리에 아래와 같은 파일이 있음. knife configure로 knife에게 이러한 인증서의 패스를 정확히 설정할 필요가 있다.
우선은 서버와 같은 호스트의 knife가 잘동작하도록 하고, 후에 workstation에 인증서를 전송하는 순서로 설치를 하겠음.
일단은 /etc/chef-server이하의 pem파일을 홈디렉토리로 카피함.

  • chef-validator.pem : chef-validator용의 디지털 인증서 파일
  • admin.pem : 관리자용의 클라이언트 인증서 파일(이 것을 사용하는 클라이언트 만 chef-validator를 통하지 않고 미리 작성되어 있음)

[code lang=text]
vagrant@chef-server:/$ sudo knife configure
Please enter the chef server URL: [https://chef-server:443] https://192.168.30.10
Please enter an existing username or clientname for the API: [vagrant] admin
Please enter the validation clientname: [chef-validator]
Please enter the location of the validation key: [/etc/chef-server/chef-validator.pem] ~/.chef/validation.pem
Please enter the path to a chef repository (or leave blank):
[/code]

위의 설정에서
* server URL : https://192.168.30.10
* clientname : admin
* validation key : /etc/chef-server/chef-validation.pem
을 설정함. 이것으로 해당 서버의 knife는 클라이언트의 인증서가 있는 ~/.chef/admin.pem을 이용해서 통신을 하게끔 된다. 한번 시험해봅시다.

[code lang=text]
$ knife client list
[/code]

Work Station의 셋업

새로운 Chef Client를 셋업 할 경우, 인증서의 생성과 클라이언트를 서버에 등록하는 것이 필요하다. 이것도 knife로 하게됨. 서버에 설치한 knfie를 사용해 보도록 하자.

knife client create를 실행하면 에디터에서 메타데이터의 편집을 요구하기때문에, EDITOR의 환경변수를 미리 설정해둠. knife client create 옵션의 -a 는 관리권한을 가진 클라이언트의 작성, -f는 인증파일의 저장소 지정. Vagrant를 사용하는 경우는 가상머신의 /vagrant는 공유 디렉토리로 마운트되어 있어서 다른 가상서버로의 파일전송이 편리하다. 거기에 저장을 하도록 해보자.

[code lang=text]
$ export EDITOR=vi
$ knife client create workstation -a -f /vagrant/workstation.pem
[/code]

Work Station의 knife에도 validation.pem을 저장해두면 나중에 편하니 거기에도 카피해두자.

그리고 여기서 부터는 Work Station에서 작업해야한다. 우선은 Work Station에 Chef Solo를 설치할때 사용한 Opscode Omnibug Packaging의 인스톨스크립트를 실행해서 Chef를 설치한다.

[code lang=text]
$ vagrant ssh workstation
$ curl -L https://www.opscode.com/chef/install.sh | sudo bash
$ chef-client -v
Chef: 11.8.2
[/code]

이 다음으로는 서버에서 한것과 동일하게 knife를 설정해야한다.

[code lang=text]
$ cp /vagrant/workstation.pem ~/.chef/
$ cp /vagrant/validation.pem ~/.chef/
$ knife configure
WARNING: No knife configuration file found
Where should I put the config file? [/home/vagrant/.chef/knife.rb]
Please enter the chef server URL: [https://workstation:443] https://192.168.30.10
Please enter an existing username or clientname for the API: [vagrant] workstation
Please enter the validation clientname: [chef-validator]
Please enter the location of the validation key: [/etc/chef-server/chef-validator.pem] ~/.chef/validation.pem
Please enter the path to a chef repository (or leave blank):
[/code]

서버의 URL과 방금 설정한 인승키의 패스를 설정.
제대로 설정을 했다면 knife client list로 출력이 되고 새로운 Client로 workstation이 등록된다.

[code lang=text]
### Chef Server에서 작업
$ knife client list
chef-validator
chef-webui
workstation
[/code]

<h3>Chef Client의 설치</h3>
Chef Server와 Work Station이 완료된 후에는 Client를 작업하자.
관리 대상이 되는 노드를 Chef Client로 셋업하자.

클라이언트측의 Chef인스톨도 Opscode Omnibus Packaging의 인스톨 스크립트를 실행하면 된다.

우분투를 클린상태로 설치했다면, 몇가지 패키지를 설치해야하니 다음 순서로 설치해보자.

[code lang=text]
### Chef Client에서 실행함.
$ sudo apt-get update
$ sudo apt-get install curl vim -y
$ curl -L https://www.opscode.com/chef/install.sh | sudo bash
$ chef-client -v
$ sudo mkdir -p /etc/chef
$ sudo cp /vagrant/validation.pem /etc/chef/validation.pem
[/code]

위의 스크립트를 한줄 한줄 실행해도 되고 귀찮은 사람은 파일로 만들어서 한방에 실행해도 된다.

노드에서 chef-client를 실행해서 해당 노드를 서버에 등록하자. –server로 서버의 URL을 지정하고, -N으로 노드명을 지정할 수 있다.(생략하려면 /etc/chef/client.rb를 설정하면 된다. 자세히 알고 싶으면 매뉴얼을 보도록 하자.)

[code lang=text]
$ sudo chef-client –server https://192.168.30.10 -N node01
[/code]

최초의 Client실행 때에 /etc/chef/client.pem에 클라이언트용 인증서가 생성되고, 이후의 통신은 validation.pem이 아닌 클라이언트용 인증서를 사용하게 된다.

Chef Server에 노드가 등록되었는지 Work Station의 knife에서 확인가능하다.

[code lang=text]
### Work Station에서 실행
$ knife client list
chef-validator
chef-webui
node01
workstation
[/code]

node02, node03에는 추후에 따로 세팅을 할테니 우선 두자.

헉헉헉…길다…
<h3>레시피 실행하기</h3>
잘동작하는지 테스트용 레시피를 작성후 실행해보자.
테스트로는 해당노드에 대한 각종 정보를 가지고 있는 ohai를 확인해 보는 레시피를 작성하도록 하자.
Work Station에서 쿡북을 작성하고 Server에 업로드 한 뒤 클라이언트에 적용해보자.
<h4>쿡북의 작성</h4>

[code lang=text]
$ knife cookbook create sample -o ~/chef-repo/cookbooks
[/code]

<h4>
레시피의 작성</h4>

[code lang=text]
$ vi ~/chef-repo/cookbooks/recipes/default.rb

bash "print ohai info" do
user 'vagrant'
group 'vagrant'
cwd '/home/vagrant'
environment "HOME" => '/home/vagrant'
code < /tmp/ohai.txt
EOC
creates "/tmp/ohai.txt"
end
[/code]

<h4>쿡북의 업로드</h4>

[code lang=text]
$ knife cookbook upload -a -o ~/chef-repo/cookbooks
[/code]

<h4>Node Object의 run_list 레시피 추가</h4>

[code lang=text]
$ knife node run_list add node01 'recipe[sample]'
[/code]

<h4>Node Object를 에디터에서 편집하고 싶은 경우</h4>

[code lang=text]
$ knife node edit node01
[/code]

이제 서버에 필요한 정보의 등록은 완료됐다.
노드 쪽에서 chef-client를 실행하고 생성된 파일을 확인해 보자.

[code lang=text]
$ sudo chef-client –server https://192.168.30.10 -N node01
$ cat /tmp/ohai.txt | head
{
"languages": {
"ruby": {
"platform": "x86_64-linux",
"version": "1.8.7",
"release_date": "2012-02-08",
"target": "x86_64-unknown-linux-gnu",
"target_cpu": "x86_64",
"target_vendor": "unknown",
"target_os": "linux",

[/code]

knife bootstrap 으로 노드 설정하기

가상머신으로 실행중인 경우 Work Station에서 knife bootstrap 명령을 원격으로 실행 가능하도록, 몇가지 선행되어야하는 작업이 있는데 다음과 같다.

  • 가상서버에 ssh로그인 가능하도록 호스트 OS의 ~/.vagrant.d/insecure_private_key를 Work Station의 ~/.ssh/id_rsa에 카피

[code lang=text]
### 호스트 OS에서 작업
$ scp ~/.vagrant.d/insecure_private_key worksstation:~/.ssh/id_rsa
[/code]

  • 가상서버에 설치되어 있는 옛날 버젼의 Chef가 설치시 에러를 일으킬 수 있으므로 제거. /usr/bin 디렉토리의 chef-* 파일을 어딘가로 이동해두면 된다.

[code lang=text]
### Work Station에서 작업
$ mv /usr/bin/chef-* /tmp/
[/code]

  • Work Station의 /etc/hosts에 각 노드의 IP주소를 등록해둔다.

[code lang=text]
# /etc/hosts

192.168.30.21 node01
192.168.30.22 node02
192.168.30.23 node03
[/code]

위의 설정은 knife ssh가 호스트로의 통신을 FQDN(Fully Qualified Domain Name)으로 실행하기 위한 것이다.

정리

설치와 실행이 매우 길고 좀 복잡해 보이는데, 차근차근 따라해보면 그렇지도 않다. 관리하는 서버가 10대를 넘어가면 Chef Server를 고려해 보는 것이 좋은 것 같다.

[python] private / public아이피 구분하는 스크립트

아이피가 퍼블릭인지 사설아이피인지
구분해야할 필요가 있어서, 쉘스크립트로 만들려고 찾아보다가
포기하고 쉘에서 스크립트언어를 불러오는 방법으로 변경했다.

요즘 루비를 공부중인지라 루비로 만들고 싶었지만,
회사의 서버에는 루비가 거의 설치가 안되어 있는지라

회사의 서버에 대부분 설치 되어 있는 파이썬으로 만들었다.

첨에는 어떻게 해야되는지 좀 막막했는데,
아래 링크의 소스를 보니 그렇게 어렵지 않았다.
파이썬의 소스도 아래링크의 php소스를 파이썬으로 변경한것이다.

Check private IP function PHP

그리고 스택오버플로우에 무지하게 간단한 방법이 있긴했는데,
뭔가 모듈을 설치해야되는것 같았다.
http://stackoverflow.com/questions/691045/how-do-you-determine-if-an-ip-address-is-private-in-python

그래서 그냥 php소스를 python으로 변경하는것으로 최종 결정했다.

아래는 포팅한 소스이다.
파이썬을 잘하는 편이 아닌지라 되도록 간단히 만들려고 노력했다.

원리는 ip를 long타입으로 변환해서 privateip구간에 있는지 체크하는 원리이다.
뭔가 더 좋은게 있을것 같긴한데…(아시는분은 코멘트 좀 부탁드려요.^^)

isPrivateIp.py

import sys
from struct import *
from socket import *

if len(sys.argv) != 2:
    print "input just one parameter."
    sys.exit()

input_ip = sys.argv[1]

private_addrs = ['10.0.0.0|10.255.255.255',
                 '172.16.0.0|172.31.255.255',
                 '192.168.0.0|192.168.255.255',
                 '169.254.0.0|169.254.255.255',
                 '127.0.0.0|127.255.255.255'
                 ]

def ip2long(ip_addr):
    ip_packed = inet_aton(ip_addr)
    ip = unpack("!L", ip_packed)[0]
    return ip

def isPrivateIP(ip_addr):
    long_ip = ip2long(ip_addr)
    if long_ip != -1:
        for private_addr in private_addrs:
            start, end = private_addr.split("|")

            if long_ip >= ip2long(start) and long_ip <= ip2long(end):
                return 'PRIVATE'

    return 'PUBLIC'

print(isPrivateIP(input_ip))

쉘에서 사용하는 경우

IP_TYPE="`python ${DEPLOY_HOME}/isPrivateIp.py $IPADDR`"
echo "IP type is $IP_TYPE"

if [ "$IP_TYPE" == "PRIVATE" ];then
	echo "PIVATE IP!"

fi

[ruby기초] Kernel모듈의 출력 메서드들 – p, print, printf, putc, puts –

원래는 shallow copy랑 deep copy라는 것에 대해서 쓸려고 했는데,
그것 관련해서 찾다보니 「p」라는 녀석이 테스트 코드에 보이길래
출력메서드에 대해서 적고자 한다.

찾아보니 문자열을 출력해주는 메서드는 루비의 Kernel모듈에 들어 있는데
거기에 포함되어 있는 출력관련 메서드는 아래와 같다.
p, print, printf, putc, puts

루비의 레퍼런스에 있는 설명들을 보자.
p
– 각 객체에 대해 obj.inspect를 출력하고, 그 다음 현재 출력 레코드 구분자를 프로그램의 표준출력에 쓴다.

테스트 코드

p("Hello, Ruby !\n")

결과

"Hello, Ruby !\n"

음..inspect가 실행된건지 잘 모르겠다. 하나 더 테스트해보자.

User = Struct.new(:name, :id)
u = User['park', 'wapj']
p u

결과

#<struct User name="park", id="wapj">

print – 각 객체를 차례로 STDOUT에 출력한다. 출력필드구분자($,)가 nil이 아니라면 그 내용이 각 필드 사이에 나타날 것이다. 출력레코드 구분자($\)가 nil이 아니라면 결과에 이 값도 추가될 것이다. 아무런 매개변수도 건네지 않으면 $_를 출력한다. 문자열이 아닌 객체들은 그 객체의 to_s메서드를 호출하여 문자열로 변환한다.
테스트 코드

print "apple", [1,2,3], 9876, "\n"
$, = ","
$\ = "\n"
print "apple", [1,2,3], 99

실행결과

apple1239876
apple,1,2,3,99

출력필드 구분자를 지정안하면 문자들이 붙어서나오고
지정한 뒤에는 문자열 사이사이에 출력필드구분자가 붙어서 나온다.

printf – 아래 코드와 동일하다
io.write sprintf(format, obj …)
또는
STDOUT.write sprintf(format, obj …)

형식은 printf(format, arg*)과 같고
format에다 arg로 들어온 파라메터를 적용한 문자열을 반환한다.
기본적으로는 C의 sprintf와 동일하다.

테스트코드

#2진수
printf("%b", 10) # -> 1010
#8진수
printf("%o", 10) # -> 12
#16진수
printf("%x", 10) # -> a
printf("%X", 10) # -> A

#부동소수점 
printf("%.0f", 10.12) # -> 10
printf("%.1f", 10.12) # -> 10.1
printf("%.2f", 10.12) # -> 10.12

#문자열
printf("%s", "abcdefg") # -> abcdefg

# Object#inspect의 결과를 출력
printf("%p", [1, 2, 3]) # -> [1,2,3]

# 10진수 d,i
printf("%d %i", 10, 20) # -> 10 20

플래그, 폭, 정확도등의 표시자가 있는데 이건 다음에 따로 써야 될듯..

putc – STDOUT.putc(int)와 동일.
주어진 문자(String, Fixnum)를 io에 쓴다.

putc "A"
putc 65

결과

AA

puts – STDOUT.puts(arg…)와 동일.
주어진 객체를 IO#print를 이용해서 쓴다. 개행문자로 끝나지 않는 객체는 개행문자를 붙인다.
배열을 넣으면 각요소를 새로운줄에 쓴다.

테스트 코드

puts ("hello", "ruby", "!")

결과

hello
ruby
!

※참고
출력메서드를 사용할 때에는 쌍따옴표 [“]나 홑따옴표[‘]로 보통 감싸주는데,
홑따옴표는 그냥 그대로 표시해준다고 생각하면 되고,
쌍따옴표는 [\n]같은 역슬래시[\]로 시작하는 문자를
특수문자로 치환해 주는 기능이 추가로 더 있다.

루비 습작3 스트링의 개행문자 제거하기(String#chop!)

오늘은 바로 코드로 들어가보자.

def makeCode(var)
  puts "/home/www/conf/#{var}.properties"
  puts "/home/www/db/#{var}.data"
  puts "/home/www/xml/#{var}.xml"
end

x = gets

makeCode(x)

위의 루비코드는 별거 아니다. 그냥 코드 생성기다.
위의 코드를 실행하면 변수를 콘솔에서 받아온다.
그런데 문제가 하나 있는것이 엔터키로 변수를 받아오기에 #{var} 뒤에 꼭 \n이 붙어서 온다.
실행하면 아래와 같이 변수뒤에 개행이 들어가는데, 아주 신경쓰인다.

/home/www/conf/test
.properties
/home/www/db/test
.data
/home/www/xml/test
.xml

어차피 가장뒤에 있는 문자가 ‘\n’으로 달려오니 이걸 삭제해주면 될것 같다.
찾아보니 역시나 있구만..ㅎ

[ruby] var.chop! [/ruby]

String#chop! 이라는 녀셕을 사용해서 해결했다.
문자열의 가장뒤에 있는 문자를 삭제해주는 메서드인데,
아마도 이런용도로 쓰라고 만든거라는 생각이 든다.

자세한 것은 역시나 루비의 레퍼런스를 참고하자.
http://ruby-doc.org/core-1.9.3/String.html#chop-method

변경된 소스는 다음과 같다.

def makeCode(var)
  var.chop!  
  puts "/home/www/conf/#{var}.properties"
  puts "/home/www/db/#{var}.data"
  puts "/home/www/xml/#{var}.xml"
end

x = gets

makeCode(x)

루비 습작2 카멜케이스를 abc_def_ghi형식으로 변환하기

루비로 이것 저것 만들기 시작하니 참 재미있고,
편리하다는 생각이 든다.
오늘은 어제랑 완전 반대인 예제를 만들었다.

testClassMethod 라는 문자열을 주면 test_class_method의 형식으로 변환해 주는
메서드를 만들어 보았다.

기능은 반대인데 코드는 그다지 닮지 않았다.
이번 예제에서 사용된 중요한 메서드는 gsub메서드인데 풀어쓰면
global substitute정도 될라나? 아래 레퍼런스를 참고하는게 확실하긴 하지만,
간단히 설명하면, 정규식을 사용해서 스트링내부의 문자열을 치환하는 기능을 제공한다.
자바로 치면 replaceAll() 정도 되는 메서드이다. 자주 사용될듯.

나는 책보고 했는데, 책이 없으신분들은 아래 사이트를 참고하자.
http://ruby-doc.org/core-1.9.3/String.html#method-i-gsub
책은 프로그래밍 루비 790쪽에 레퍼런스가 있다.

코드는 아래와 같다.

#!/usr/bin/ruby

def makeDowncase(val)

  val  = val.gsub(/[A-Z]/) {|x| '_' + x.downcase}

  puts val

end

print "input CamelCases : "
vars = gets
varList = vars.split(" ")
varList.each { |x| makeDowncase(x)}

실행하면 아래와 같이 나오고

input CamelCase : testClassMethod1 testClassMethod2 testClassMethod3 aaaBbbCcc dddEeeFff

결과는 이렇게 된다.

test_class_method1
test_class_method2
test_class_method3
aaa_bbb_ccc
ddd_eee_fff

루비 습작1 abc_def의 문자열을 카멜표기법으로 변경하기

루비를 공부중인데, 책보고 따라하는거 보다는 실제로 만들어보는게
재밌기도하고 실제로 도움이 되기도 해서
반복적인 작업을 없애기 위해서 아래와 같은 유틸리티성 메서드를 만들어봤다.

제목처럼 abc_def_xyz 처럼 되어있는 문자열을 abcDefXyz로 변경해주는 메서드이다.

여러개를 동시에 받아서 변환가능하다.
(문자열이 ‘ ‘ 공백으로 구분되어있어야된다. 머 더 잘 할수 있겠지만, 이 정도로도 사용하는데 문제 없음.^^;)

소스는 아래와 같다.

[ruby]
#!/usr/bin/ruby

### MAKE Camel Case from abc_def -> abcDef

def makeCapitalize(var1)
array1 = var1.split("_")
array2 = array1[1, array1.length].collect! {|x| x.capitalize}
puts "===================="
array2.insert(0, array1[0]);
puts array2.join
return array2.join
end

print "input text : "
variables = gets

varList = variables.split(" ")

varList.each { |x| makeCapitalize(x)}
[/ruby]

실제로 돌려본거는 아래와 같은 형식으로 했다.

[gyus@gyue:string]$ ./makeCamel.rb

input text : tx_server_target_method tx_server_ntype tx_server_access_method tx_naming_postfix tx_client_class tx_client_super tx_client_access tx_client_prefix tx_client_using_param profile_class tx_server_target_method profile_prefix profile_access_method lwst_txclient_method_using_param

결과

====================
txServerTargetMethod
====================
txServerNtype
====================
txServerAccessMethod
====================
txNamingPostfix
====================
txClientClass
====================
txClientSuper
====================
txClientAccess
====================
txClientPrefix
====================
txClientUsingParam
====================
profileClass
====================
txServerTargetMethod
====================
profilePrefix
====================
profileAccessMethod
====================
lwstTxclientMethodUsingParam

오홋.. 재밌네.ㅋ

참고
– 프로그래밍 루비 책
site : http://www.ruby-doc.org/core-1.9.3/Array.html#method-i-collect