Archive

Author Archive

Building Erlang B13R04 in CentOS 5.4

April 30th, 2010

Last post was about building Erlang B13R04 in Ubuntu. For CentOS, it’s somehow the same with yum

sudo yum -y install make gcc gcc-c++ kernel-devel m4 ncurses-devel openssl-devel
wget http://www.erlang.org/download/otp_src_R13B04.tar.gz
tar xfvz otp_src_R13B04.tar.gz
cd otp_src_R13B04/
./configure --with-ssl
sudo make install

However, I haven’t found the similar package to xsltproc and fop yet. But it’s only for building the documentation which I don’t really need.

Installation , , , ,

Building Erlang B13R04 in Ubuntu 9.10 Karmic

April 5th, 2010

Frankly speaking, I always use apt-get to install Erlang rather than building from source… lazy huh? Unfortunately, when I apt-get in Ubuntu 9.10 Karmic, only Erlang/OTP R13B01 (5.7.2) is available whereas the latest is R13B04 (5.7.5) which is required to build Riak (actually rebar requires 5.7.4 and above)…

It takes around 10-15 min to build, and these are the required libraries and dependencies

sudo apt-get install build-essential m4 libncurses5-dev libssl-dev xsltproc fop
axel -n 20 http://www.erlang.org/download/otp_src_R13B04.tar.gz
tar xfvz otp_src_R13B04.tar.gz
cd otp_src_R13B04/
./configure --with-ssl
sudo make install

Here i’m using axel for fast download, it’s your choice to use curl or wget.

Installation , , , , , ,

OneTeam Media Server and Erling

March 29th, 2010

It’s been a long time I haven’t blogged anything about erlang … damn… too many cool stuff but too little time. Actually my works are getting heavily busy these days + 4-month-old kid … lots of excuses huh?

Good news is I’ve been back to my Erling (AMF Implementation) recently. While spending sometimes to see what progress I have made so far, I came across OMS (OneTeam Media Server) release announcement.

OneTeam Media Server, or OMS for short, is a new Flash server implementation, written in erlang, by ProcessOne. This will enable your users to broadcast voice and/or video streams to multiple subscribers.

Wow, this is a great news … it’s greater to see more and more heavy task back-end services written in Erlang. I’ve registered an account with ProcessOne Git Repository just to fork the project. Lots of thing can learn from OMS. Many thanks to ProcessOne for open source this project.

AMF , , , ,

Record introspection at compile time

October 8th, 2009

For AMF implementation, I have to define the mapping between Actionscript classes with something equivalent in Erlang. First thing came into my mind is record. However, I immediately encountered some of the difficulties when using records in Erlang

  1. Read: can’t use reflection easily after parsing AMF, I received the object with properties/values and I need to map to the corresponding record
  2. Write: Need to introspect the record and write its properties into binaries

I found this post from trapexit. However, I need specifically more than that.

Normally records are defined in a header file “.hrl”. And the idea is to generate utility codes (getter, setter, record meta data ….) at compile time. The heart of it is epp:parse_file/3 function. The generator (or the helper) reads header files, parses all records and create a compilable .erl file which contains all functions you need to do all magic with records:

  1. set(Obj, PropertyName, Value) -> {ok, NewObj, {PropertyName, Value}}
  2. get(Obj, PropertyName) -> {ok, Value}
  3. fields(record_name) -> Fields = [string()]
  4. fields_atom(record_name) -> Fields = [term()]
  5. type(Obj) -> record_name

messages.hrl – the source

record_helper.erl – the generator

record_utils.erl – the generated source

Below is the demonstration of how to generate and use the record utils

1> c(record_helper.erl).
{ok,record_helper}
2> record_helper:make(["messages.hrl"], ".").
ok
3> ls().
messages.hrl            record_helper.beam
record_helper.erl      record_utils.erl
ok
6> c(record_utils).
{ok,record_utils}
7> rr("messages.hrl").
[abstract_message,async_message]
8> Obj = #async_message{}.
#async_message{
    parent =
        #abstract_message{
            clientId = undefined,destination = undefined,
            messageId = undefined,timestamp = undefined,
            timeToLive = undefined,headers = undefined,body = undefined},
    correlationId = undefined,correlationIdBytes = undefined}
9> record_utils:set(Obj, correlationId, "ADF-123-DDF-543").
{ok,#async_message{
        parent =
            #abstract_message{
                clientId = undefined,destination = undefined,
                messageId = undefined,timestamp = undefined,
                timeToLive = undefined,headers = undefined,body = undefined},
        correlationId = "ADF-123-DDF-543",
        correlationIdBytes = undefined},
    {correlationId,"ADF-123-DDF-543"}}
10> {ok,NewObj, _} = record_utils:set(Obj, correlationId, "ADF-123-DDF-543").
{ok,#async_message{
        parent =
            #abstract_message{
                clientId = undefined,destination = undefined,
                messageId = undefined,timestamp = undefined,
                timeToLive = undefined,headers = undefined,body = undefined},
        correlationId = "ADF-123-DDF-543",
        correlationIdBytes = undefined},
    {correlationId,"ADF-123-DDF-543"}}
11> record_utils:get(NewObj, correlationId).
{ok,"ADF-123-DDF-543"}
12> record_utils:type(NewObj).
async_message

record_helper.erl is not so clean as there’re all string concatenations … further improvements can be:

  1. Using template language like ErlyDTL or ErlTL
  2. Clean up code to have more friendly arguments
  3. You add ….

AMF, Basic, Record , ,

amf implementation using Erlang

October 4th, 2009

I just restarted a long sleep idea to implement AMF using Erlang, the project, codenamed Erling, is hosted in github. There’s nothing much yet except amf0 and amf3 implementation, i’m working on the unit test for whatever I’ve written so far to make sure it won’t go messy as the code evolved.
Everyday I’m learning new thing along with Erling and therefore more Erlang examples to come …

AMF , , ,

Date time manipulation howtos

September 6th, 2009

Erlang offers calendar module which provides computation of date, time and number of date time conversion functions. For more details, please refer to documentation for this module
Here are some examples:

Data types


Date = {Year, Month, Day}
Time = {Hour, Minute, Second}

where

Year = an integer and cannot be abbreviated. E.g.: 93 denotes year 93, not 1993
Month = 1..12
Day = 1..31
Hour = 0..23
Minute = 0..59
Second = 0..59

How to obtain local date time

{Date, Time} = calendar:local_time()

1> Current = calendar:local_time().
{{2009,9,7},{12,32,22}}
2> {{Current_Year, Current_Month, Current_Day}, _ } = Current.
{{2009,9,7},{12,32,22}}
3> Current_Year.
2009
4> Current_Month.
9
5> Current_Day.
7
6> { _, {Current_Hour, Current_Min, Current_Second}} = Current. 
{{2009,9,7},{12,32,22}}
7> Current_Hour.
12
8> Current_Min.
32
9> Current_Second.
22

How to obtain current UTC time

{Date, Time} = calendar:universal_time()

How to convert time to seconds since midnight and via versa

Seconds = calendar:time_to_seconds(Time)
Time = calendar:seconds_to_time(Seconds)

10> Time1 = {10, 6, 30}.
{10,6,30}
11> Seconds = calendar:time_to_seconds(Time1).
36390
12> calendar:seconds_to_time(Seconds).
{10,6,30}

How to verify if a year is leap year

Bool = calendar:is_leap_year(Year)

14> calendar:is_leap_year(2008).
true
15> calendar:is_leap_year(2009).
false

How to check if a date is valid

Bool = calendar:valid_date(Date)
Bool = calendar:valid_date(Year, Month, Day)

16> calendar:valid_date({2009,12,12}).
true
17> calendar:valid_date({2009,13,12}).
false
18> calendar:valid_date(2009, 12, 31).
true
19> calendar:valid_date(2008, 2, 29).
true

How to find out day of the week

DayNumber = calendar:day_of_the_week(Date)
DayNumber = calendar:day_of_the_week(Year, Month, Day)
1 = Monday, 2 = Tuesday, ….and 7 = Sunday

20> calendar:day_of_the_week({2009,9,7}).
1
21> calendar:day_of_the_week(2009, 9, 9).
3

How to find out last day of a month

LastDay = calendar:last_day_of_the_month(Year, Month)

22> calendar:last_day_of_the_month(2008, 2).   
29
23> calendar:last_day_of_the_month(2009, 8).
31

How to calculate date time difference

{Days, Time} = calendar:time_difference(DT1, DT2)
DT1 = {Date1, Time1}
DT2 = {Date2, Time2}
Logically equivalent to DT2 – DT1

7> Date1={{2009,8,30}, {23,0,0}}.
{{2009,8,30},{23,0,0}}
8> Date2={{2009,9,30}, {23,0,0}}.
{{2009,9,30},{23,0,0}}
9> calendar:time_difference(Date2, Date1).
{-31,{0,0,0}}
10> calendar:time_difference(Date1, Date2).
{31,{0,0,0}}
11> Date3={{2008,8,30},{23,0,0}}.
{{2008,8,30},{23,0,0}}
12> calendar:time_difference(Date1, Date3).
{-365,{0,0,0}}

Basic, DateTime , , , ,

Recursion in Erlang

August 28th, 2009

Quick Sort

I took this example from Joe Armstrong’s book: Programming Erlang to show the beauty Erlang in recursion. Classic example of quick sort implementation

Can’t believe it, 6 simple and very elegant!!! I remembered roughly 10 years ago, how hard to write quick sort implementation in Pascal.

Tail Recursion

The quick sort implementation above is not tail recursive way. As the function call doesn’t return the whole results at once (look at the list concatenation). Here are few examples of tail recursion in Erlang

Basic , , , , ,

Diving into Emacs

August 3rd, 2009

I started looking at emacs as an alternative to TextMate and Eclipse for programming Erlang, especially in Windows. In fact, it’s quite hard. And I found this picture is very very true
editor-learning-curve

Uncategorized

How to spawn a process

May 15th, 2009

Erlang is all about processes and their communications. To create a process, we use BIF spawn/3 which returns the new process PID

-module(spawn_process).
-export([do_spawn/0, call/2]).

call(Arg1, Arg2) ->
    io:format("~p ~p~n", [Arg1, Arg2]).

do_spawn() ->
    %% Equivalent to SpawnProcess:call("hello", "process"),
    Pid = spawn(?MODULE, call, ["hello", "process"]),
    Pid.

Output of the call spawn_process:do_spawn/0 is the Pid of the newly created process. ?MODULE is the macro refers to the current module

1> spawn_process:do_spawn().
"hello" "process"
<0.33.0>
2>

Basic , , ,

How to create and manipulate records

March 9th, 2009

As I remember the first time I was tought about Object-Oriented paradigm, my teacher told me “everything around you is an object” … Damn, since then I couldn’t get rid of that even when programming with Erlang.

People say Records concept in Erlang is very similar to struct in C. That’s true, but for me, it looks rather like an Object

Normally, records are defined in a separate file with extension .hrl and included in the main module file.

person.hrl

%% person.hrl
-record(person, {name, age}).

Here I define a record, named person, which has 2 attributes name and age. I’ll use erl console to do some manipulation with record person

1> rr("person.hrl").
[person]
2> X = #person{name="Jonny", age="18"}.
#person{name = "Jonny",age = "18"}
3> X#person.name.
"Jonny"
4> X#person.age.
"18"
5> #person{name=Name} = X.
#person{name = "Jonny",age = "18"}
6> Name.
"Jonny"

1> I read record person defined in person.hrl
2> I created a new “object” of type person and assigned to variable X
3> I printed value of the attribute name from “object” X
4> I printed value of the attribute age from “object” X
5> I used pattern matching to extract value of the attribute name out of “object” X and assigned to variable Name
6> I printed value of variable Name

Basic ,