Newbie Test: BeepBeep III Interrupted
January 23, 2009
Set out today to extend BeepBeep, but got hung up for time writing a module that I’m hoping to use in the extension.
Oh well, it may be useful in testing other web servers/frameworks as well. With more work it might also provide a decent start toward an application involving personal contacts.
Here it is warts and all:
names.erl
-module(names).
-export([init/0, insertName/5, getNames/0, formalName/1, firstName/1, lastFirst/1]).
-include_lib("stdlib/include/qlc.hrl").
%%% Database record structures for names
-record(names,
{last,
honorific,
first,
middle,
suffix}).
% NOTE: honorific is Mr. | Mrs. | Ms, etc.
% NOTE: suffix is Jr. | III | esq. etc.
%%% Database functions
%%% Utils
init() ->
%% Initialize database
mnesia:create_schema([node()]),
mnesia:start(),
mnesia:create_table(names,
[ {type, set},
{disc_copies, [node()] },
{attributes,
record_info(fields,names)} ]).
%%% Insert functions
insertName( Honorific, First, Middle, Last, Suffix) ->
%% Add a name item to database
Fun = fun() ->
mnesia:write(
#names{last = Last,
honorific = Honorific,
first = First,
middle = Middle,
suffix = Suffix
})
end,
mnesia:transaction(Fun).
%%% Select functions by last name
getNames() ->
%% Select list of names items from database
mnesia:transaction(
fun() ->
qlc:eval( qlc:q(
[ X || X <- mnesia:table(names) ]
))
end ).
getName(Last) ->
%% Select a name by last name from database
%% NOTE: Doesn't account for duplicate last names
mnesia:transaction(
fun() ->
qlc:eval( qlc:q (
[X || X %lt;- mnesia:read({names, Last})]
))
end ).
%%% Name formatting functions
formalName(Last) ->
%% Given last name, return formal name
%% NOTE 1: Doesn't account for duplicate names
%% NOTE 2: Doesn't deal with empty fields
[Name|_] = element(2,getName(Last)),
{_, Last, Honorific, First, Middle, Suffix} = Name,
FormalName = lists:append(Honorific, " ") ++
lists:append(First, " ") ++
lists:append(Middle," ") ++
lists:append(Last, " ") ++
Suffix,
FormalName.
firstName(Last) ->
%% Given last name, return first name
%% NOTE 1: Doesn't account for duplicate names
%% NOTE 2: Doesn't deal with empty fields
[Name|_] = element(2,getName(Last)),
{_, _, _, First, _,_} = Name,
First.
lastFirst(Last) ->
%% Given last name, return full name last name first
%% NOTE 1: Doesn't account for duplicate names
%% NOTE 2: Doesn't deal with empty fields
[Name|_] = element(2,getName(Last)),
{_, Last, _, First, Middle, Suffix} = Name,
LastFirst = lists:append(Last, ", ") ++
lists:append(First, " ") ++
lists:append(Middle, " ") ++
Suffix,
LastFirst.
Here’s how to use it:
From console
-
~$ erl
blah blah
1> c(names).
2) names:init().
3) names:insertName(“President”, “Barack”, “Hussein”, “Obama”, “”).
4) names:fromalName(“Obama”).
I’m sure there’s an elegant way of dealing with empty fields in formalName/1, firstName/1, and lastFirst/1; indeed a more elegant way to write these functions altogether. But it works for me now and I’d need more time and a clearer head to figure it out.
Maybe a lurking wizard can show us the way.
So why did it take me some four hours to write this simple module?
1) My inexperience with Erlang
2) Skimpy and (to me) confusing Mnesia documentation.
I’m working on issue 1 and I’m not going to complain about issue 2 until I’m in a position to fix it. On the other hand, I can certainly pray that someone gets to it before I do. Simple examples starting with all the basic CRUD functions would be a good start.
If you have a low threshold for frustration, you’ll know that it’s not easy being an Erlang newbie. But I ran across this blog post recently. It puts things in perspective admirably.
http://www.postneo.com/2007/08/26/there-is-an-erlang-community-its-just-smaller-than-youre-used-to
Maybe if we work really really hard we can help flag and stamp out all those little pesky issues that impede our climb up the Erlang learning curve… make things easier for newbies even greener than we are.
Hope to get back to BeepBeep in my next post.
See ya’.
Poking Around in All the Right Places
January 5, 2009
Just ran across another blog devoted to poking around Erlang:
http://ayende.com/Blog/archive/2008/09/24/reading-erlang-inspecting-couchdb.aspx
Oren Eini explores CouchDB clause-by-clause. I’m looking forward to learning much.