Friday, June 26, 2009

Search engine attempt for the Standard Erlang Documentation

The main Erlang documentation site, erlang.org/doc is a set of static pages, which is not that convenient if you need to find a module quickly. Here I have attempted to break some ice. The heavy-scripted page contains the list of standard Erlang modules encoded. The relevant links appear in from of you as you type the module name. The tiddlywiki JavaScript engine does the job behind the scene.

It works nicely for me, I also have another file for off-line Erlang doc browsing,
which, if placed into the same folder as the Erlang doc root, will work the same way as the online version.

Thursday, June 18, 2009

String substitution missing in Erlang - for them lazy boys.

I keep seeing complaints that there is no such thing as substring replace
string:sub("Hello, there!","there","World") -> "Hello, World!"
or the global substitution:
gsub("Hell###, W###rld!","###","o") -> "Hello, World!"

Here is the module strre.erl:

-module(strre).
-author("Serge: onerlang.blogspot.com").
-purpose("string replace functionality").
-export([sub/3,gsub/3,test/0]).

sub(Str,Old,New) ->

Lstr = len(Str),
Lold = len(Old),
Pos = str(Str,Old),
if
Pos =:= 0 ->
Str;
true ->
LeftPart = left(Str,Pos-1),
RitePart = right(Str,Lstr-Lold-Pos+1),
concat(concat(LeftPart,New),RitePart)
end.

gsub(Str,Old,New) ->
Acc = sub(Str,Old,New),
subst(Acc,Old,New,Str).

subst(Str,_Old,_New, Str) -> Str;
subst(Acc, Old, New,_Str) ->
Acc1 = sub(Acc,Old,New),
subst(Acc1,Old,New,Acc).

test() ->
io:format("~p ~p ~p ~p ~p ~p ~p ~n",
[
"SELECT * FROM people WHERE first='John' OR last='John'" =:=
gsub("SELECT * FROM people WHERE first=$1 OR last=$1","$1","'John'"),
"aBc" =:= sub("abc","b","B"),
"Abc" =:= sub("abc","a","A"),
"abC" =:= sub("abc","c","C"),
"aac" =:= gsub("bbc","b","a"),
"abc" =:= gsub("abc","d","C"),
"abc" =:= sub("abc","d","D")]).

What is the string representation for the float?

The Erlang people hold on to the point where the "123456" is for integer 123456 only, not for 123456.0 float! I was using nice and small pgsql PostgreSQL driver for Erlang and everything worked cool before I had troubles to fetch float datatype values which are rounded to integer.

As it happens, the list_to_float("123") will produce an error:

21> erlang:list_to_float("123").
** exception error: bad argument
in function list_to_float/1
called as list_to_float("123")
22> erlang:list_to_float("123.0").
123.0

That feature was explicitly confirmed by Erlang team, so we have to supply the missing ".0" ourselves. I had to patch the pgsql_util:decode_col locally to make it work:

decode_col(#desc{format=text, type=Float}, Value)
when Float =:= float4; Float =:= float8 ->
ListValue = binary_to_list(Value),
IsFloat = string:str(ListValue,"."),
if
IsFloat > 0 -> FValue = Value;
true -> FValue = Value ++ ".0"
end,
list_to_float(FValue);