erlang 쉘에서 할 수 있는 테스트를 해보고 있다. 


http://knight76.tistory.com/entry/erlang-erlang-shell-%EA%B0%84%EB%8B%A8-%ED%85%8C%EC%8A%A4%ED%8A%B8-%ED%8A%9C%ED%94%8C-%EB%A6%AC%EC%8A%A4%ED%8A%B8


http://knight76.tistory.com/entry/erlang-erlang-shell-%EA%B0%84%EB%8B%A8-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%97%B0%EC%82%B0%EC%9E%90-%ED%95%A0%EB%8B%B9-%EC%95%A0%ED%86%B0



얼랭에서 변수 정의시, f(변수이름)을 호출하여 변수이름에 대해서만 unbound를 할 수 있다. 



1> A=1.

1

2> B=A+1.

2

3> f(A).

ok

4> A.

* 1: variable 'A' is unbound

5> B.

2



조건문의 if 이다. 


48> XX=1.

1

49> if XX < 0 -> false;

49> XX > 255 -> false;

49> true -> true

49> end.

true


만약 함수로 만든다면, 다음처럼 만들 수 있다. 함수를 만들고 변수 값을 넣으면 if 문으로 만들어진 함수를 통해 확인할 수 있다.



50> XXTEST = fun(XX) ->

50> if XX < 0 -> false;

50> XX > 0 -> false;

50> true -> true

50> end

50> end.

#Fun<erl_eval.6.54118792>


52> XXA=10.

10

53> XXTEST(XXA).

false

54> XXB=0.

0

55> XXTEST(XXB).

true




is_list(문자열)은 true, is_number(숫자)는 false이다.

is_list(숫자)는 false, is_number(문자열)은 true이다.



1> A="T".

"T"

2> is_list(A).

true

4> is_number(A).

false

5> B=1.

1

6> is_list(B).

false

7> is_number(B).

true



is_list와 case를 이용한다. list 여부를 확인하는 간단한 함수이다. 


8> XXSTR = fun(XX) ->

8>   case is_list(XX) of

8>     false -> false;

8>     true -> true  %마지막에 ;을 붙이지 않는다.

8>   end

8> end.

#Fun<erl_eval.6.54118792>

4> XXSTR("a").

true

5> XXSTR(1).

false






Posted by '김용환'
,



단순 출력은 io:format 함수를 사용한다. ~n은 한줄을 의미한다. 만약 특정 상수를 출력하고 싶다면 ~w를 추가한다.


1> io:format("hello world~n", []).

hello world

ok

2> io:format("오 한글 되나~n", []).

오 한글 되나

ok


3>A=1.1.


4> io:format("~w~n", [A]).

1.1

ok




튜플을 ordered immutable list 정도의 타입이다. { }으로 표현한다.


1> POINT = {50, 30}

1> .

{50,30}

2> {X, Y} = POINT.

{50,30}

3> X.

50

4> Y.

30


튜플 내부의 타입은 튜플과 아무 상관없이 잘 사용할 수 있다.



5> MEMBER = {'samuel', 15, 'sales'}.

{samuel,15,sales}

6> MEMBER.

{samuel,15,sales}



튜플끼리 비교가 가능하다.


9> {50, 30} == {30, 50}.

false

10> {50, 30} == {50, 30}.

true

11> {50, 30} =:= {30, 50}.

false

12> {50, 30} =:= {50, 30}.

true



리스트는 아무 것이나 넣을 수 있으며, 리스트끼리 비교할 수 있다. [ ]로 표현한다.


13> [ 10, 20, 30 , 'abc', 1.1, atom].

[10,20,30,abc,1.1,atom]

14> [ 10, 20, 30 , 'abc', 1.1, atom] == [ 10, 20, 30 , 'abc', 1.1, atom].

true

15> [ 10, 20, 30 , 'abc', 1.1, atom] == [ 10, 20, 30 , 'abc', 1.1, atom1].

false



문자가 없으면, ASCII 묶음이 된다.


21> [48, 49, 50, 51, 52, 53, 54, 55, 56, 57].

"0123456789"



리스트간의 연산을 할 수 있다. 리스트는 리스트와의 연산을 할 수 있으며, 연산자는 정해져 있다. ++, --를 사용한 예제이다.


22> [1,2,3] + 4.

** exception error: an error occurred when evaluating an arithmetic expression

     in operator  +/2

        called as [1,2,3] + 4

23> [1,2,3] + [4].

** exception error: an error occurred when evaluating an arithmetic expression

     in operator  +/2

        called as [1,2,3] + [4]

24> [1,2,3] ++ [4].

[1,2,3,4]

25> [1,2,3] -- [3].

[1,2]



아주 특이한 것은 ++, -- 리스트 연산의 순서는 오른쪽에서 왼쪽이다. 아래 예를 들면, [3,1] -- [3]의 결과를 먼저 진행한다. [1]만 남는다. [1,2,3] -- [1] 연산의 결과를 출력한다.


27> [1,2,3] -- [3, 1] -- [3].

[2,3]


리스트를  concatenation을 할 수 있다.  파이프(|)을 이용하면 하나로 merge한다. 만약 쉼표(,)를 사용하면 리스트 안에 리스트를 생성한다.


29> List = [1,2,3].

[1,2,3]

30> [0,List].

[0,[1,2,3]]

31> [0|List].

[0,1,2,3]




얼랭만의 특징인데, head와 tail 명령어다. head 명령어는 hd로 쓰이며, 맨 앞 하나만 가진다. tail 명령은 head 1개를 제외한 나머지이다.


33> hd([1,2,3]).

1

34> tl([1,2,3]).

[2,3]







Posted by '김용환'
,


얼랭 파일 컴파일 하기


$ cat >  helloworld.erl

% Hello World

-module(helloworld).

-export([start/0]).


start() ->

    io:fwrite("Hello world, samuel!\n").




컴파일은 erlc를 사용한다. 컴파일하면 helloword.beam 파일이 생성됨을 확인할 수 있다.


$ ls -al

total 8

drwxr-xr-x  3 Samuel  wheel  102 11  7 00:00 .

drwxr-xr-x  5 Samuel  wheel  170 11  7 00:00 ..

-rw-r--r--  1 Samuel  wheel  109 11  6 23:59 helloworld.erl


$ erlc helloworld.erl


$ ls -al

total 16

drwxr-xr-x  4 Samuel  wheel  136 11  7 00:00 .

drwxr-xr-x  5 Samuel  wheel  170 11  7 00:00 ..

-rw-r--r--  1 Samuel  wheel  596 11  7 00:00 helloworld.beam

-rw-r--r--  1 Samuel  wheel  109 11  6 23:59 helloworld.erl


beam 확장자 파일은 얼랭 컴파일 파일이다. java처럼 가상머신에서 동작하는 바이너리 파일이다. 

http://www.erlang.se/~bjorn/beam_file_format.html


얼랭 쉘에서 결과를 실행한다. -s옵션을 주어 모듈이름과 함수 이름을 추가한다.


$ erl -s helloworld start

Erlang/OTP 18 [erts-7.1] [source] [64-bit] [smp:8:8] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]


Hello world, samuel!

Eshell V7.1  (abort with ^G)

1>


단순하게 'erl -s 모듈이름 함수이름'을 실행 후, 얼랭 쉘에 남아있게 된다. -s 옵션을 더 주어 얼랭 커맨드를 정상적으로 모듈을 실행하고 종료하도록 -s init stop을 준다. (만약 -s init 만 주고 실행하면, 비정상적 종료라 여기고 core dump 하니. 같이 넣어주는 것이 좋은 것 같다.)


$ erl -s helloworld start -s init stop

Erlang/OTP 18 [erts-7.1] [source] [64-bit] [smp:8:8] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]


Hello world, samuel!

Eshell V7.1  (abort with ^G)

1>

$


얼랭 쉘 내용이 보기 싫다면, -noshell을 추가한다.


$ erl -noshell -s helloworld start -s init stop

Hello world, samuel!


정상적으로 실행을 마무리했다. 




이번에는 얼랭 쉘을 미리 실행하고 컴파일된 helloworld 얼랭 파일을 읽어본다.  c() 함수로 컴파일된 얼랭 파일 모듈을 읽고, 모듈의 함수를 실행하면 끝이다.


$ erl

Erlang/OTP 18 [erts-7.1] [source] [64-bit] [smp:8:8] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]


Eshell V7.1  (abort with ^G)


1> c(helloworld).

{ok,helloworld}

2> helloworld:start().

Hello world, samuel!

ok




Posted by '김용환'
,



얼랭 커맨드 실행하려면, erl을 실행한다.



$ erl

Erlang/OTP 18 [erts-7.1] [source] [64-bit] [smp:8:8] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]


Eshell V7.1  (abort with ^G)

1>



주석은 %로 시작한다.


1> % 주석 테스트

1> %% 주석 테스트

1> %%% 주석 테스트


문장의 종료는 마침표(.)이다.


1> 10 + 10.

20


ctrl + p 또는 윗 키는 앞 명령어, ctrl + n 또는 아래 키는  뒷 명령어이다.

숫자와 문자와의 연산은 되지 않는다.


2> 30-1-'a'.

** exception error: an error occurred when evaluating an arithmetic expression

     in operator  -/2

        called as 29 - a


계산 기능은 잘 된다. /를 사용하면 부동형(.)으로 표현한다.


3> 1+2/2.

2.0


javascript 정도의 실수 연산을 할 수 있다.


4> 999999999999999999999999999999999999*999999999999999999999999999999999999999999999.

99999999999999999999999999999999999989999999990000000000000000000000000000000000001



그러나 엄청 큰 두 숫자를 곱하면 에러가 난다. 


* 1: illegal float


16진수 값을 연산할 수 있다. 진수 계산을 하려면 '숫자진수#값'을 사용한다. 2진수 1은 '2#1'로 표현한다.


7> 16#A + 16#2.

12


cd로 디렉토리 변경할 수 있고, pwd로 현재 디렉토리를 확인할 수 있다.


11> pwd().                                                                                                                                            /usr/local/Cellar/erlang/18.1/bin                                                                                                                    

ok


13> cd("../").

/usr/local/Cellar/erlang                                                                             

ok


16> cd("/mydev").

/mydev

ok



변수 설정은 할 수 없다. 상수만 설정할 수 있다. 대문자로 시작하는 상수는 사용할 수 있다.


20> A=1.

1

21> a=1.

** exception error: no match of right hand side value 1

22> Aa=1.

1


underscore로 값을 할당할 수 있다. 


23> _ = 1 + 2.

3


상수로 또 다른 상수를 정의할 수 있다.


25> B=A+1.

2


상수 출력은 상수 값에 마침값을 추가한다.


25> A.

1



$를 사용하면, ASCII 값을 저장한다.


31> $1.

49

32> $2.

50

33> $0.

48


상수에 정의된 모든 값을 초기화하려면 f() 를 사용한다.


39> f().

ok

40> A=1.

1

41> A=2.

** exception error: no match of right hand side value 2

42> f().

ok

43> A=1.

1



연산자 사용하기


44> B=-A.

-1

45> C=+A.

1

46> B*C.

-1

47> B/C.

-1.0

48> bnot B.

0

49> B/A.

-1.0

50> B+A.

0

51> B-A.

-2

52> B div A.

-1

53> B rem A.

0

54> B band A.

1



동일한 값이 좌/우에 같으면, 문제 없지만, 틀린 값이면 에러가 발생한다.

=을 패턴 매칭이다!!! 


60> 10 = 8 + 2.

10

61> 11 = 8 + 2.

** exception error: no match of right hand side value 10



enum 또는 글로벌 상수를 선언할 수 있다. 이를 atom이라고 부른다.

그러나 마침표가 중간에 있거나 연산자가 있으면 에러가 발생한다.


63> samuel.

samuel

64> samuel.kim.

* 1: syntax error before: '.'

64> incredible-king.

** exception error: an error occurred when evaluating an arithmetic expression

     in operator  -/2

        called as incredible - king

65> incredible_king.

incredible_king


예약어를 atom으로 선언하면 에러가 발생한다.


66> when.

* 1: syntax error before: 'when'



논리 연산자를 사용할 수 있다. 숫자에 대한 논리 연산자는 =:=이다.


66> true and true.

true

67> true or false.

true

68> not false.

true

69> not (false and false).

true

70> 1 =:= 2.

false

71> 1 =:= 1.

true


shell 커맨드를 종료하려면 halt 함수를 실행하거나  ctrl+c를 두번 누른다(또는 ctrl+c 누르고 a를 선택한다.).


80> halt().



Posted by '김용환'
,



rebar 컴파일할 때, 주의할 점은 develop 브랜치가 아닌 master 브랜치에서 bootstrap을 실행해야 한다. 

(develop에서 bootstrap 컴파일이 안되서;;;)


https://github.com/rebar/rebar


$ git clone git://github.com/rebar/rebar.git
$ cd rebar
$ ./bootstrap




Posted by '김용환'
,

mac에서 erlang 설치

erlang 2015. 10. 2. 14:11

mac에서 erlang 설치하는 방법이다. 간단하게 brew를 통해 설치할 수 있다.

공식 홈페이지에서는 윈도우와 소스만 제공하고 있다.



$ brew update


$ brew install erlang



==> Summary

🍺  /usr/local/Cellar/erlang/18.1: 7465 files, 287M



$ vi .bash_profile

export ERLANG_PATH=/usr/local/Cellar/erlang/18.1/bin

export PATH=$PATH:$ERLANG_PATH



erlang을 intellji 설정 방법은 다음을 따른다.


https://www.jetbrains.com/idea/help/getting-started-with-erlang.html

Posted by '김용환'
,