Erlang/OTP Forums

Author Message

<  Advanced Erlang/OTP  ~  Odd behaviour with tuple data extraction

brett hallett
Posted: Sun Sep 23, 2007 11:44 pm Reply with quote
User Joined: 21 Aug 2007 Posts: 21
Following mazen's information I changed my dirty_reads as per accounts() below, and then started expirementing
with possible printing options -- now some confusion beging !.

======================================
accounts() -> %% returns :{atomic,{atomic,[[{account,"joe",0}],
%% [{account,"richard",19800}],
%% [{account,"brett",4000}]]}}
M2 = [mnesia:dirty_read(account, Key)
|| Key <- mnesia:dirty_all_keys(account)],
print(M2),
print2(M2).

%%% ============
print( [L1 | L ]) -> %% {account,"joe",0}
io:fwrite("print1:",[]),
io:fwrite('~p ~n', L1),
print(L);
print([]) ->
io:fwrite("** end accounts list 1 ***~n", []),
ok.
%%% ============
print2( [L1 | L ]) ->
io:fwrite("print2:",[]),
io:fwrite('~p ~n', L1),
print2(L);
print2([]) ->
io:fwrite("** end accounts list 2 ***~n", []),
ok.
=======================================

shell output is:


c(bank).
{ok,bank}
53> bank_client:accounts().
print1:{account,"joe",0}
print1:{account,"richard",19800}
print1:{account,"brett",4000}
** end accounts list 1 ***
print2:{account,"joe",0}
print2:{account,"richard",19800}
print2:{account,"brett",4000}
** end accounts list 2 ***
{aborted,{badarg,ok,[],infinity,mnesia}}

print & print2 output is the same, as expected, however when I change print2 thus :

%%% ============
print2( [L1 | L ]) ->
io:fwrite("print2:",[]),
{A,B,C} = L1, %%%% new
io:fwrite('~p ~n', L1),
io:fwrite("Account : ~s Name: ~s Balance: ~s ~n", [A, B, C]), %%%% new
print2(L);
print2([]) ->
io:fwrite("** end accounts list 2 ***~n", []),
ok.
===============================
the fwrite(s) just stuff up and aborts !
I've tried MANY different formats ( ~p, ~s, ~w etc ) without sucess, but the most annoying thing
is that a previously working fwrite

io:fwrite('~p ~n', L1),

also does not work now ???
I should get

print2:{account,"joe",0}

, but only 'print2:' appears.

I assume the 'badmatch' below is something to do with my format statement, but I'm
not really sure about that at all !!!

===============================
c(bank).
{ok,bank}
55> bank_client:accounts().
print1:{account,"joe",0}
print1:{account,"richard",19800}
print1:{account,"brett",4000}
** end accounts list 1 ***
print2:
=ERROR REPORT==== 22-Sep-2007::14:23:40 ===
Error in process <0.429.0> with exit value: {{badmatch,[{account,"joe",0}]},[{bank,print2,1},{bank_server,do_call,1},{bank_server,input_handler,1}]}

true

===============================

Any ideas appreciated.
View user's profile Send private message
michal
Posted: Mon Sep 24, 2007 11:55 am Reply with quote
User Joined: 20 Jul 2006 Posts: 44 Location: London
When you see error like {badmatch,[{account,"joe",0}]} try to look in you code for patterns that are similar to [{account,"joe",0}]. I can see a following line:
{A,B,C} = L1,

L1 is a list with one element [{account,"joe",0}] and you try to match it against a tuple. Rewrite the code as:

[{A,B,C}] = L1,

Michal

_________________
http://www.erlang-consulting.com
View user's profile Send private message
Mazen
Posted: Tue Sep 25, 2007 8:14 am Reply with quote
User Joined: 20 Jul 2006 Posts: 164 Location: London
The reason that you have the badmatch is explained by michal, however, the reason that you have to match against a list with 1 element in it instead of just a tuple is because mnesia:dirty_read/2 returns a *list* or records.

I.e. if dirty_read returns [] then you didn't find anything, if your table is a set or ordered_set then you can patternmatch on [Element] = ... or if your table is a bag then you will have many elements in that list.

In your case it is probably a set and thus returns [{account,Name,Cash}] when you read a record.

/Mazen
View user's profile Send private message
brett hallett
Posted: Wed Sep 26, 2007 12:05 am Reply with quote
User Joined: 21 Aug 2007 Posts: 21
There is more to this tuple / list processing than meets the eye !!

Your input(s) have been very useful, I now have a variery of ways which do what I wanted. But it was a struggle getting any useful feedback from Erlang itself ! The 'badarg' error
seems to he Erlangs catchall

Thanks
Brett
View user's profile Send private message
francesco
Posted: Wed Sep 26, 2007 6:21 am Reply with quote
User Joined: 07 Jul 2006 Posts: 249 Location: London
badarg is returned whenever you call a BIF with wrong arguments. badmatch, instead, when pattern matching fails. There are very few error messages in Erlang. Once you get used to them, it becomes fairly easy to spot what is wrong.

Regards,
Francesco
View user's profile Send private message Visit poster's website

Display posts from previous:  

All times are GMT
Page 1 of 1
This forum is locked: you cannot post, reply to, or edit topics.

Jump to:  

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You cannot download files in this forum